欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-03-14 11:45:58
...

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

代码

可视化数据和制作标签

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()
    ```