0
点赞
收藏
分享

微信扫一扫

PyTorch学习笔记(5)--mnist数据集训练

蓝哆啦呀 2022-04-22 阅读 73
from __future__ import print_function
import os
import struct
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
import torch.optim as optim
import matplotlib.pyplot as plt
def load_mnist(path,kind='train'):
    labels_path=os.path.join(path,'%s-labels.idx1-ubyte/%s-labels.idx1-ubyte'%(kind,kind))
    images_path = os.path.join(path, '%s-images.idx3-ubyte/%s-images.idx3-ubyte' % (kind, kind))
    # labels_path = os.path.join(path, '%s-labels.idx1-ubyte' % kind)
    # images_path=os.path.join(path,'%s-images.idx3-ubyte'%kind)
    with open(labels_path,'rb') as lbpath:
        magic,n=struct.unpack('>II',lbpath.read(8))
        labels=np.fromfile(lbpath,dtype=np.uint8)
    with open(images_path,'rb') as imgpath:
        magic,num,rows,cols=struct.unpack(">IIII",imgpath.read(16))
        # labels=np.array(labels)
        images=np.fromfile(imgpath,dtype=np.uint8).reshape(len(labels),784)
    return images,labels
X_train,y_train =load_mnist('./data',kind='train')
print('Rows:%d,columns:%d'%(X_train.shape[0],X_train.shape[1]))
X_test,y_test=load_mnist('./data',kind='t10k')
print('Rows:%d,columns:%d'%(X_train.shape[0],X_train.shape[1]))
batch_size=100
num_classes=10
epochs=2
# input image dimensions
img_rows,img_cols =28,28
train_losses=[]
test_losses=[]
test_counter=[]
train_counter=[]
x_train=X_train
x_test=X_test
if 'channels_first'=='channels_first':
    x_train=x_train.reshape(x_train.shape[0],1,img_rows,img_cols)#样本,通道,高度,宽度
    x_test=x_test.reshape(x_test.shape[0],1,img_rows,img_cols)
    input_shape=(1,img_rows,img_cols)
else:
    x_train=x_train.reshape(x_train.shape[0],img_rows,img_cols,1)
    x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
    input_shape=(img_rows,img_cols,1)
x_train=x_train.astype('float32')
x_test=x_test.astype('float32')
x_train/=255
x_test/=255
print('x_train shape:',x_train.shape)
print(x_train.shape[0],'x_train samples')
print(y_train.shape[0],'y_train samples')
print(x_test.shape[0],'x_test samples')
print(y_test.shape[0],'y_test samples')
num_samples=x_train.shape[0]
print("num_samples:",num_samples)
'''
build torch model
'''
class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        #(5,5)卷积核
        self.conv1=nn.Conv2d(1,10,kernel_size=5)#将1通道的图像数据的输入卷积成10个神经元,这一个通道会和10个神经元都建立连接
        self.conv2=nn.Conv2d(10,20,kernel_size=5)#将10通道的图像数据的输入卷积成20个神经元,这10个通道会和20个神经元都建立连接
        # self.conv1 = nn.Conv2d(1, 32, kernel_size=5)
        # self.conv2 = nn.Conv2d(32, 64, kernel_size=5)
        self.conv2_drop=nn.Dropout2d()#抛弃部分数据
        #self.fc1=nn.Linear(320,50)
        self.fc1 = nn.Linear(10*6*6, 50)
        self.fc2=nn.Linear(50,10)#两个全连接层
    def forward(self,x):
        x=F.relu(F.max_pool2d(self.conv1(x),2))#池化成最大值,池化核为(2,2)
        x=F.relu(F.max_pool2d(self.conv2_drop(self.conv2_drop(x)),2))
        x=x.view(-1,10*6*6)#动态调整这个维度上的元素个数以保证元素的总数不变
        x=F.relu(self.fc1(x))
        x=F.dropout(x,training=self.training)
        x=self.fc2(x)
        return F.log_softmax(x,dim=1)#图像分类的损失函数
model=Net()
if os.path.exists('mnist_torch.pkl'):
    model=torch.load('mnist_torch.pkl')
print(model)

'''
trainning
'''
optimizer=optim.SGD(model.parameters(),lr=0.01,momentum=0.5)
def train(epoch,x_train,y_train):
    num_batchs=num_samples/batch_size
    model.train()
    num_batchs=int(num_batchs)
    for k in range(num_batchs):
        start,end=k*batch_size,(k+1)*batch_size
        data,target=Variable(x_train[start:end],requires_grad=False),Variable(y_train[start:end])
        optimizer.zero_grad()
        output=model(data)
        loss=F.nll_loss(output,target)
        loss.backward()
        optimizer.step()
        if k%10==0:
            print('Train Epoch:{}[{}/{}({:.0f}%)]\tLoss:{:.6f}'.format(epoch,k*len(data),num_samples,100.*k/num_samples,loss.item()))
            train_losses.append(loss.item())
            train_counter.append((k*64)+((epoch-1)*len(data)))
    torch.save(model,'mnist_torch.pkl')


'''
evaluate
'''
def test(epoch):
    model.eval()
    test_loss=0
    correct=0
    if 2>1:
        with torch.no_grad():
            data,target=Variable(x_test),Variable(y_test)
        #data,target=Variable(x_test,volatile=True),Variable(y_test)
        output=model(data)
        test_loss+=F.nll_loss(output,target).item()
        test_losses.append(test_loss)
        # for i in range(epochs+1):
        #     test_counter.append(i*len(data))
        test_counter.append( len(data))
        # test_counter=[i*len(data) for i in range(epochs+1)]
        # print(test_loss)
        # print(len((x_test)))
        pred=output.data.max(1)[1]
        correct+=pred.eq(target.data).cpu().sum()
    #test_loss/=len(x_test)
    print('\nTest set:Average loss:{:.4f},Accuracy:{}/{}({:.0f}%)\n'.format(test_loss,correct,len(x_test),100.*correct/len(x_test)))
x_train=torch.from_numpy(x_train).float()
x_test=torch.from_numpy(x_test).float()
y_train=torch.from_numpy(y_train).long()
y_test=torch.from_numpy(y_test).long()
for epoch in range(1,epochs):
    train(epoch,x_train,y_train)
    test(epoch)
'''
painting
'''
fig= plt.figure()
plt.plot(train_counter,train_losses,color='blue')
plt.scatter(test_counter,test_losses,color='red')
plt.legend(['Train Loss', 'Test Loss'], loc='upper right')
plt.xlabel('number of training examples seen')
plt.ylabel('negative log likelihood loss')
plt.show()

得到结果:(多次训练后的结果,每次训练得到的结果不同)

得到train_loss曲线和test_loss点: 

 读者自己跑代码时若遇到问题:

请读者移步至笔者所写另一篇博客:(1条消息) 解决PermissionError: [Errno 13] Permission denied: ‘./data\\train-labels.idx1-ubyte‘_别管我啦就是说的博客-CSDN博客icon-default.png?t=M3K6https://blog.csdn.net/m0_61385981/article/details/124309779?spm=1001.2014.3001.5502

若读者需要查看mnist数据集内容:

import cv2
for i in range(60000):
    image1 = X_train[i]
    image1 = image1.astype('float32')
    image1 = image1.reshape(28, 28, 1)
    cv2.imwrite('./img/'+str(i)+".jpg", image1

mnist数据集下载网址:

http://yann.lecun.com/exdb/mnist/

参考书籍:《PyTorch深度学习实战》
 

举报

相关推荐

0 条评论