您现在的位置是:首页 >学无止境 >【python】pytorch包(第四章)手写数字图像识别网站首页学无止境
【python】pytorch包(第四章)手写数字图像识别
简介【python】pytorch包(第四章)手写数字图像识别
问题描述:
给定手写字体的图片,人工智能自动判断这是数字几
数据来源:
MNIST数据集
代码实战:
Part 1. 准备数据集
该模块内容完成的功能:
- 下载MNIST数据集;
- 转换数据格式,使适用于pytorch;
- 数据分批;
- 将上述功能 API化
from torch.utils.data import DataLoader
from torchvision.datasets import MNIST
from torchvision.transforms import Compose,ToTensor,Normalize
def get_data(Batch_Size,train=True):
#train = True则是训练集,否则是测试集
#以每批Batch_size大小进行数据分批
transform_fn = Compose([
ToTensor(), #转张量
Normalize(mean=(0.1307,),std=(0.3081))#正则化
#mean和std的形状和通道数相同
])
dataset = MNIST( #数据集类别
root=r'E:MNIST数字识别 raining', #将数据集存储在路径/files/内
train =True, #True表示获取的是训练s集,否则获取的是训练集
download=False,#如果没有下载过数据集,则需要标True下载
transform= transform_fn #图片处理函数
)
data_loader = DataLoader( #分批次的数据集类别
dataset, #将dataset分批
batch_size = Batch_Size, #每批包含Batch_size个数据
shuffle=True #随机打乱
)
return data_loader
Part 2. 构建模型
1. 构建模型逻辑
神经网络结构:
四层神经网络,输入层->全连接层1->全连接层2->输出层参数设定:
激活函数: relu()
损失函数: 交叉熵损失函数
数据形状:
原始数据:[batch_size,1,28,28] # 原始数据形状
输入层:[batch_size,1x28x28] # 摊开
第一层输出:[batch_size,28] # 参数28可以自行修改
第二层输出:[batch_size,10] # 十个数字,十个类别
优化器: Adam()
import torch
from torch import nn
import torch.nn.functional as F
class Number_Identify(nn.Module):
def __init__(self):
super(Number_Identify,self).__init__() #继承父类init的参数
self.fc1 = nn.Linear(1*28*28,28,bias=True)
#第一层神经网络,输入维度为1*28*28,输出维度为28
self.fc2 = nn.Linear(28,10,bias=True)
#第二层神经网络,输入维度为28,输出维度为10
def forward(self,x): #模型输入x,输出out
x = x.view(-1,1*28*28)
#view()相当于reshape(),参数为-1表示 根据情况自适应调整
x = self.fc1(x) #经过第一层神经网络计算
x = F.relu(x) #经过激活函数
out = self.fc2(x) #经过第二层神经网络计算
return F.log_softmax(out,dim=-1)
2. 模型实例化
from torch import optim
model = Number_Identify()#调用模型基底、
#criterion = nn.CrossEntropyLoss() #损失函数
optimizer = optim.Adam(model.parameters(),lr=1e-3) #优化器
Part 3. 训练模型
该模块内容完成的功能:
- 从MNIST数据集导入训练数据集
- 实现训练逻辑
- 将上述功能 API化
构建模型训练的逻辑过程
#训练函数
def train(epoch):
model.train(mode=True) #当前模型设定为训练模式
data_train = get_data(2,train=True)
#获取训练数据,数据按每两个一组分批
for idx,(data,target) in enumerate(data_train):
optimizer.zero_grad() #清零梯度
out = model(data) #向前计算:预测当前数据的结果
loss = F.nll_loss(out,target) #计算带权损失
loss.backward() #反向传播
optimizer.step() #参数更新
#训练进度展示:
if idx%10000 == 0:
print(' batches[%d/%d],loss:%.6f' % (
idx,len(data_train),loss.data
))
模型训练
#训练
training_times = int(input("输入训练次数:"))
for epoch in range(training_times): #多次训练
print("Train_epoch[%d/%d]:" % (epoch+1,training_times))
train(epoch)
print("=========Train_epoch[%d/%d] finished======" % (epoch+1,training_times))
print("======训练完成======")
Part 4. 保存模型
torch.save(
model.state_dict(),
r'E:AI_Model_saveNumber_Identifymodel_net.pt'
)#保存模型
torch.save(
optimizer.state_dict(),
r'E:AI_Model_saveNumber_Identifymodel_optimiter.pt'
)#保存优化器
Part 5. 模型使用
1. 加载模型
import os
import torch
if os.path.exists(r'E:AI_Model_saveNumber_Identify'):
model.load_state_dict(torch.load(
r'E:AI_Model_saveNumber_Identifymodel_net.pt'
)) #加载模型
optimizer.load_state_dict(torch.load(
r'E:AI_Model_saveNumber_Identifymodel_optimiter.pt'
))#加载优化器
print("======成功调用=======")
else:
print("路径错误")
2. 模型评估
编写test函数,实现模型评估的API
实现功能:批量预测+计算正确率
API部分
import numpy as np
import torch
def test(model,data_test):
loss_list = []
accuracy_list = []
for idx,(Input,target) in enumerate(data_test):
with torch.no_grad():#预测状态,不改变梯度参数
output = model(Input) #批量预测
cur_loss = F.nll_loss(output,target) #计算损失
loss_list.append(cur_loss)
pred = output.max(dim=-1)[-1] #批量预测结果
accuracy = pred.eq(target).float().mean() #计算准确率
accuracy_list.append(accuracy)
#这里计算的是每个batch的正确率与损失
return np.mean(accuracy_list),np.mean(loss_list)
导入测试数据 并测试
data_test = get_data(100,train=False)
#读取测试数据集,每100个为一组进行测试
accuracy,loss = test(model,data_test) #测试数据
print("准确率:%.2f" % (accuracy*100),"%")
print("Loss:",loss)
3. 单图预测【待填】
After all:
用pytorch做了这个实战,个人感受是:
pytorch的数据预处理更加傻瓜式,但伴随的参数也更多,需要熟悉的API也更多,学起来更麻烦一些,成本更高,但使用起来的便利性更好;
相比之下,keras的数据预处理需要我们自己完成,学起来很简单,但用起来很麻烦(每次都要自己手写数据的预处理)
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。