基于pytorch的cnn卷积神经网络——代码

李宏毅老师的深度学习课程,讲到CNN,Mark一下。

代码实现:

# -*- encoding: utf-8 -*-

import sys
import csv
import time
import numpy as np
import torch
import torch.nn as nn
from torch.utils.data import TensorDataset, DataLoader


def readfile(path):
    print("Reading File...")
    x_train = []
    x_label = []
    val_data = []
    val_label = []

    raw_train = np.genfromtxt(path, delimiter=\',\', dtype=str, skip_header=1)
    for i in range(len(raw_train)):
        tmp = np.array(raw_train[i, 1].split(\' \')).reshape(1, 48, 48)
        if (i % 10 == 0):
            val_data.append(tmp)
            val_label.append(raw_train[i][0])
        else:
            x_train.append(tmp)
            x_train.append(np.flip(tmp, axis=2))    # simple example of data augmentation
            x_label.append(raw_train[i][0])
            x_label.append(raw_train[i][0])

    x_train = np.array(x_train, dtype=float) / 255.0
    val_data = np.array(val_data, dtype=float) / 255.0
    x_label = np.array(x_label, dtype=int)
    val_label = np.array(val_label, dtype=int)
    x_train = torch.FloatTensor(x_train)
    val_data = torch.FloatTensor(val_data)
    x_label = torch.LongTensor(x_label)
    val_label = torch.LongTensor(val_label)

    return x_train, x_label, val_data, val_label


x_train, x_label, val_data, val_label = readfile(\'Data/train.csv\')   # \'train.csv\'

train_set = TensorDataset(x_train, x_label)
val_set = TensorDataset(val_data, val_label)

batch_size = 256
train_loader = DataLoader(train_set, batch_size=batch_size, shuffle=True, num_workers=0)
val_loader = DataLoader(val_set, batch_size=batch_size, shuffle=False, num_workers=0)


def gaussian_weights_init(m):
    classname = m.__class__.__name__
    if classname.find(\'Conv\') != -1 and classname.find(\'Conv\') == 0:
        m.weight.data.normal_(0.0, 0.02)


class Classifier(nn.Module):
    def __init__(self):
        super(Classifier, self).__init__()
        self.cnn = nn.Sequential(
            nn.Conv2d(1, 64, 4, 2, 1),  # [64, 24, 24]
            nn.BatchNorm2d(64),
            nn.LeakyReLU(0.2),
            nn.Conv2d(64, 64, 3, 1, 1),
            nn.BatchNorm2d(64),
            nn.LeakyReLU(0.2),
            nn.MaxPool2d(2, 2, 0),      # [64, 12, 12]

            nn.Conv2d(64, 128, 3, 1, 1),
            nn.BatchNorm2d(128),
            nn.LeakyReLU(0.2),
            nn.Conv2d(128, 128, 3, 1, 1),
            nn.BatchNorm2d(128),
            nn.LeakyReLU(0.2),
            nn.MaxPool2d(2, 2, 0),      # [128, 6, 6]

            nn.Conv2d(128, 256, 3, 1, 1),
            nn.BatchNorm2d(256),
            nn.LeakyReLU(0.2),
            nn.Conv2d(256, 256, 3, 1, 1),
            nn.BatchNorm2d(256),
            nn.LeakyReLU(0.2),
            nn.MaxPool2d(2, 2, 0)       # [256, 3, 3]
        )

        self.fc = nn.Sequential(
            nn.Linear(256*3*3, 1024),
            nn.LeakyReLU(0.2),
            nn.Dropout(p=0.5),
            nn.Linear(1024, 512),
            nn.LeakyReLU(0.2),
            nn.Dropout(p=0.5),
            nn.Linear(512, 7)
        )

        self.cnn.apply(gaussian_weights_init)
        self.fc.apply(gaussian_weights_init)

    def forward(self, x):
        out = self.cnn(x)
        out = out.view(out.size()[0], -1)
        return self.fc(out)


model = Classifier().cuda()
# print(model)
loss = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
best_acc = 0.0

for i, data in enumerate(train_loader):
    if i == 0:
        print(data[0])

num_epoch = 100
for epoch in range(num_epoch):
    epoch_start_time = time.time()
    train_acc = 0.0
    train_loss = 0.0
    val_acc = 0.0
    val_loss = 0.0

    model.train()
    for i, data in enumerate(train_loader):
        optimizer.zero_grad()

        train_pred = model(data[0].cuda())  #预测
        batch_loss = loss(train_pred, data[1].cuda())  #误差计算
        batch_loss.backward()  #误差的反向传播
        optimizer.step()  #参数更新

        train_acc += np.sum(np.argmax(train_pred.cpu().data.numpy(), axis=1) == data[1].numpy())
        train_loss += batch_loss.item()

        progress = (\'#\' * int(float(i) / len(train_loader) * 40)).ljust(40)
        print(\'[%03d/%03d] %2.2f sec(s) | %s |\' % (epoch + 1, num_epoch, \
                                                  (time.time() - epoch_start_time), progress), end=\'\r\', flush=True)

    model.eval()
    for i, data in enumerate(val_loader):
        val_pred = model(data[0].cuda())
        batch_loss = loss(val_pred, data[1].cuda())

        val_acc += np.sum(np.argmax(val_pred.cpu().data.numpy(), axis=1) == data[1].numpy())
        val_loss += batch_loss.item()

        progress = (\'#\' * int(float(i) / len(val_loader) * 40)).ljust(40)
        print(\'[%03d/%03d] %2.2f sec(s) | %s |\' % (epoch + 1, num_epoch, \
                                                   (time.time() - epoch_start_time), progress), end=\'\r\', flush=True)

    val_acc = val_acc / val_set.__len__()
    print(\'[%03d/%03d] %2.2f sec(s) Train Acc: %3.6f Loss: %3.6f | Val Acc: %3.6f loss: %3.6f\' % \
          (epoch + 1, num_epoch, time.time() - epoch_start_time, \
           train_acc / train_set.__len__(), train_loss, val_acc, val_loss))

    if (val_acc > best_acc):
        with open(\'save/acc.txt\', \'w\') as f:
            f.write(str(epoch) + \'\t\' + str(val_acc) + \'\n\')
        torch.save(model.state_dict(), \'save/model.pth\')
        best_acc = val_acc
        print(\'Model Saved!\')

Ref:基于卷积神经网络的面部表情识别(Pytorch实现)----台大李宏毅机器学习作业3(HW3)

Ref:PyTorch 入门实战(四)——利用Torch.nn构建卷积神经网络