pytorch|pytorch入门(三)——minist手写体数字识别案例

from torch.nn import init import torch.nn as nn import math import time import torch from torchvision import transforms from sklearn.model_selection import train_test_split import numpy as np import torch.nn.functional as F import pandas as pd import torchvision

【pytorch|pytorch入门(三)——minist手写体数字识别案例】第一步:定义好网络
#网络1 class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(1, 10, kernel_size=5) self.conv2 = nn.Conv2d(10, 20, kernel_size=5) self.conv2_drop = nn.Dropout2d() self.fc1 = nn.Linear(320, 50) #4*4*20 self.fc2 = nn.Linear(50, 10) def forward(self, x): x = F.relu(F.max_pool2d(self.conv1(x), 2)) x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) x = x.view(-1, 320) x = F.relu(self.fc1(x)) x = F.dropout(x, training=self.training) x = self.fc2(x) return F.log_softmax(x,dim=1)

第二步:定义好参数
#定义批次大小(每次传递512条记录给模型训练,充分利用矩阵计算的并行性能) batch_size=512 #定义训练epoch epoch=20 #定义模型 model=Net() #初始化权重参数 for layer in model.modules(): if isinstance(layer,nn.Linear): init.xavier_uniform_(layer.weight)#定义优化器 optimizer=torch.optim.Adam(model.parameters(),0.001) #定义损失函数 criterion=nn.CrossEntropyLoss()#创建交叉熵函数 #定义损失函数数组,用于可视化训练过程 loss_holder=[] #损失值设为无限大,每次迭代若损失值比loss_value小则保存模型,并将最新的损失值赋给loss_value loss_value=https://www.it610.com/article/np.inf step=0

第三步:加载数据集
minist数据集训练集有60000张照片,测试集有10000张照片。
batch_size=512,所以有118组batch_size
train_loader = torch.utils.data.DataLoader( torchvision.datasets.MNIST('./data/', train=True, download=True, transform=torchvision.transforms.Compose([ torchvision.transforms.ToTensor(), torchvision.transforms.Normalize( (0.1307,), (0.3081,)) ])), batch_size=batch_size, shuffle=True) test_loader = torch.utils.data.DataLoader( torchvision.datasets.MNIST('./data/', train=False, download=True, transform=torchvision.transforms.Compose([ torchvision.transforms.ToTensor(), torchvision.transforms.Normalize( (0.1307,), (0.3081,)) ])), batch_size=batch_size, shuffle=False)

第四步:训练
for i in range(epoch): for batch_idx, (data,label) in enumerate(train_loader): #输出值 outputs = model(data) #损失值 loss = criterion(outputs, label) #反向传播,将所有梯度的参数清0,否则该步的梯度会和前面已经计算的梯度累乘 optimizer.zero_grad() loss.backward() #更新参数 optimizer.step() #记录误差 print('epoch{},Train loss{:.6f},Dealed/Records:{}/{}'.format(i,loss/batch_size,(batch_idx+1)*batch_size,60000)) if batch_idx%20==0: step+=1 loss_holder.append([step,loss/batch_size]) #模型性能有所提升则保存模型,并更新loss_value if batch_idx%20==0 and loss

第五步:绘图。每20次保留一次loss可以看出大概迭代了120次(20个epoch,每个epoch有118个batch_idx,每20个batch_idx保留一次),从图中可以看出,经历了10次迭代后就逐渐稳定下来了。
import matplotlib.pyplot as plt fig=plt.figure(figsize=(20,15)) #x轴斜体避免重叠 fig.autofmt_xdate() loss_df=pd.DataFrame(loss_holder,columns=['time','loss']) x_times=loss_df['time'].values plt.ylabel('loss') plt.xlabel('times') plt.plot(loss_df['loss'].values) plt.xticks([10,30,50,70,80,100,120,140,160,200]) plt.show()

pytorch|pytorch入门(三)——minist手写体数字识别案例
文章图片

第六步:接下来用训练好的模型来进行测试.
#读取模型 model_path='model.ckpt' model=torch.load(model_path) #转化为测试模式 model.eval() for layer in model.modules(): layer.requires_grad=False for batch_idx, (data,label) in enumerate(test_loader): #只进行前向传播,不进行反向传播 outputs = model(data) loss = criterion(outputs, label) print('Test loss{:.6f},Dealed/Records:{}/{}'.format(loss/batch_size,(batch_idx+1)*batch_size,60000))

pytorch|pytorch入门(三)——minist手写体数字识别案例
文章图片


    推荐阅读