深度学习(Pytorch) 卷积神经网络训练 fashion mnist

fashion mnist数据获取

根据Fashion Mnist论文给出的网址下载数据集:
https://github.com/zalandoresearch/fashion-mnist

网络结构

包括输入层,两个卷积层,全连接层和输出层,下面是详细信息

Net(
  (conv1): Sequential(
    (0): Conv2d(1, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    (1): ReLU()
    (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (conv2): Sequential(
    (0): Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    (1): ReLU()
    (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (output): Linear(in_features=1568, out_features=10, bias=True)

深度学习(Pytorch) 卷积神经网络训练 fashion mnist_第1张图片

代码

可视化数据和制作标签

import os
from skimage import io
import torchvision.datasets.mnist as mnist

root="fashion_mnist/"
train_set = (
    mnist.read_image_file(os.path.join(root, 'train-images-idx3-ubyte')),
    mnist.read_label_file(os.path.join(root, 'train-labels-idx1-ubyte'))
        )
test_set = (
    mnist.read_image_file(os.path.join(root, 't10k-images-idx3-ubyte')),
    mnist.read_label_file(os.path.join(root, 't10k-labels-idx1-ubyte'))
        )
print("training set :",train_set[0].size())
print("test set :",test_set[0].size())

def convert_to_img(train=True):
    if(train):
        f=open(root+'train.txt','w')
        data_path=root+'/train/'
        if(not os.path.exists(data_path)):
            os.makedirs(data_path)
        for i, (img,label) in enumerate(zip(train_set[0],train_set[1])):
            print(str(label)[7])
            img_path=data_path+str(i)+'.jpg'
            io.imsave(img_path,img.numpy())
            f.write(img_path+' '+str(label)[7]+'\n')

        f.close()
    else:
        f = open(root + 'test.txt', 'w')
        data_path = root + '/test/'
        if (not os.path.exists(data_path)):
            os.makedirs(data_path)
        for i, (img,label) in enumerate(zip(test_set[0],test_set[1])):
            img_path = data_path+ str(i) + '.jpg'
            io.imsave(img_path, img.numpy())
            f.write(img_path + ' ' + str(label)[7] + '\n')
        f.close()

convert_to_img(True)
convert_to_img(False)

加载数据

from torch.utils.data import Dataset, DataLoader
from PIL import Image

# -----------------ready the dataset--------------------------
def default_loader(path):
    return Image.open(path)
class MyDataset(Dataset):
    def __init__(self, txt, transform=None, target_transform=None, loader=default_loader):
        fh = open(txt, 'r')
        imgs = []
        for line in fh:
            line = line.strip('\n')
            line = line.rstrip()
            words = line.split()
            imgs.append((words[0],int(words[1])))
        self.imgs = imgs
        self.transform = transform
        self.target_transform = target_transform
        self.loader = loader

    def __getitem__(self, index):
        fn, label = self.imgs[index]
        img = self.loader(fn)
        if self.transform is not None:
            img = self.transform(img)
        return img,label

    def __len__(self):
        return len(self.imgs)

训练

import torch
import time
from torch.autograd import Variable
from torchvision import transforms
import matplotlib.pyplot as plt
import fashion_mnist_data_ready as mnist_load

root="fashion_mnist/"


LR = 0.001
EPOCH = 10
BATCH_SIZE = 128

# 读取数据
train_data=mnist_load.MyDataset(txt=root+'train.txt', transform=transforms.ToTensor())
test_data=mnist_load.MyDataset(txt=root+'test.txt', transform=transforms.ToTensor())
train_loader = mnist_load.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)
test_loader = mnist_load.DataLoader(dataset=test_data, batch_size=BATCH_SIZE)



# 构造网络
class Net(torch.nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = torch.nn.Sequential(
            torch.nn.Conv2d(1, 16, 5, 1, 2),
            torch.nn.ReLU(),
            torch.nn.MaxPool2d(kernel_size=2)
        )
        # conv1输出为(16, 14, 14)
        self.conv2 = torch.nn.Sequential(
            torch.nn.Conv2d(16, 32, 5, 1, 2),
            torch.nn.ReLU(),
            torch.nn.MaxPool2d(2)
        )
        # conv2输出为(32, 7, 7)
        self.output = torch.nn.Linear(32 * 7 * 7, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = self.conv2(x)
        x = x.view(x.size(0), -1)
        prediction = self.output(x)
        return prediction



model = Net()
model = model.cuda()
print(model)

if __name__ == '__main__':

    optimizer = torch.optim.Adam(model.parameters(), lr=LR,betas=(0.9, 0.99))
    loss_func = torch.nn.CrossEntropyLoss()

    Acc = [[],[]]
    Loss = [[],[]]

    for epoch in range(EPOCH):
        start_time = time.time()
        print('epoch {}'.format(epoch + 1))
        # training-----------------------------
        train_loss = 0.
        train_acc = 0.
        for batch_x, batch_y in train_loader:
            batch_x = batch_x.cuda()
            batch_y = batch_y.cuda()
            batch_x, batch_y = Variable(batch_x), Variable(batch_y)
            out = model(batch_x)
            loss = loss_func(out, batch_y)
            train_loss += loss.item()
            pred = torch.max(out, 1)[1]
            train_correct = (pred == batch_y).sum()
            train_acc += train_correct.item()
            optimizer.zero_grad() # 清空梯度
            loss.backward()
            optimizer.step() # 更新参数
        total_loss = (train_loss * float(BATCH_SIZE)) / len(train_data)
        total_acc = train_acc / (len(train_data))
        Acc[0].append(total_acc)
        Loss[0].append(total_loss)
        print('Train Loss: {:.6f}, Acc: {:.6f}'.format(total_loss,total_acc))


        # 评测
        model.eval()
        eval_loss = 0.
        eval_acc = 0.
        for batch_x, batch_y in test_loader:
            batch_x = batch_x.cuda()
            batch_y = batch_y.cuda()
            batch_x, batch_y = Variable(batch_x), Variable(batch_y)
            out = model(batch_x)
            loss = loss_func(out, batch_y)
            eval_loss += loss.item()
            pred = torch.max(out, 1)[1]
            num_correct = (pred == batch_y).sum()
            eval_acc += num_correct.item()
        total_loss = (eval_loss * float(BATCH_SIZE)) / len(test_data)
        total_acc = eval_acc / (len(test_data))
        Acc[1].append(total_acc)
        Loss[1].append(total_loss)
        print('Test Loss: {:.6f}, Acc: {:.6f}'.format(total_loss,total_acc))
        print('training took %fs!' % (time.time() - start_time))

    torch.save(Net,'fashion_mnist_module.pkl'+str(epoch))

    labels = ['train-acc', 'test-acc']
    for i, acc in enumerate(Acc):
        plt.plot(acc,label=labels[i])
    plt.title('acc-0.001-512')
    plt.legend(loc='best')
    plt.xlabel('Epoch')
    plt.ylabel('Acc')
    plt.show()

    labels = ['train-loss', 'test-loss']
    for i, loss in enumerate(Loss):
        plt.plot(loss, label=labels[i])
    plt.title('loss-0.001-512')
    plt.legend(loc='best')
    plt.xlabel('Epoch')
    plt.ylabel('Loss')
    plt.show()
    ```

你可能感兴趣的:(深度学习)