模型训练流程:
准备数据集
train_data=torchvision.datasets.CIFAR10(root='D:\yw_app\pycharm\Pycharm_project\pytorch\datasets',train=True,transform=torchvision.transforms.ToTensor(),
download=True)
test_data=torchvision.datasets.CIFAR10(root='D:\yw_app\pycharm\Pycharm_project\pytorch\datasets',train=False,transform=torchvision.transforms.ToTensor(),
download=True)
可查看数据集大小:
train_data_size=len(train_data)
test_data_size=len(test_data)
print('训练集的长度是:{}'.format(train_data_size))
print('测试集的长度是:%s'%test_data_size)
加载数据集
rain_dataloader=DataLoader(train_data,batch_size=64)
test_dataloader=DataLoader(test_data,batch_size=64)
搭建网络
可单独创建一个.py文件存放网络,在train文件中import来使用
model.py:
import torch
from torch import nn
#搭建模型
class Tudui(nn.Module):
def __init__(self) -> None:
super().__init__()
self.model = nn.Sequential(
nn.Conv2d(3, 32, 5, 1, 2),
nn.MaxPool2d(2),
nn.Conv2d(32, 32, 5, 1, 2),
nn.MaxPool2d(2),
nn.Conv2d(32, 64, 5, 1, 2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(64 * 4 * 4, 64),
nn.Linear(64, 10)
)
def forward(self, x):
x = self.model(x)
return x
#验证网络正确性
if __name__ == '__main__':
tudui=Tudui()
input=torch.ones((64,3,32,32))#给定输入尺寸 64张3*32*32的图片
output=tudui(input)
print(output.shape)#torch.Size([64, 10]) 输出64行,对应64张图片,每行是十种分类的可能概率
创建网络模型
tudui=Tudui()
创建损失函数
loss_fn=nn.CrossEntropyLoss()#交叉熵损失函数
交叉熵损失函数,用于分类问题,值越小,训练效果越好
创建优化器
learning_rate=0.01 #1e-2
optim_fn=torch.optim.SGD(tudui.parameters(),lr=learning_rate)#随机梯度下降
设置网络训练参数
#记录训练的次数
total_train_step=0
#记录测试的次数
total_test_step=0
#记录训练轮数
epoch=10
训练轮数——每轮训练整体50000张图片,轮数越多,模型准确率越高
训练次数——每次训练一个batch_size(64)的图片,每轮要训练50000/64次
可视化训练结果
训练部分:
writer=SummaryWriter('./logs_train')
for i in range(epoch):
print('----------第{}轮训练开始--------'.format(i+1))
#训练步骤开始
tudui.train()#有dropout和BatchNorm层时使用
for data in train_dataloader:
imgs,targets=data #获取数据集,图片,targets
output=tudui(imgs) #将图片放入网络
loss=loss_fn(output,targets) #比较误差值
#优化器优化模型
optim_fn.zero_grad() #使用优化器之前,先梯度清零
loss.backward() #利用损失求每个节点梯度
optim_fn.step() #优化器优化参数
total_train_step+=1
if total_train_step%100==0:#每100次打印一次,更美观
print('训练次数:{},Loss:{}'.format(total_train_step,loss.item()))
writer.add_scalar('train_loss',loss.item(),total_train_step)
测试部分:
for i in range(epoch):
---------------------
-------训练部分------
tudui.eval()#有dropout和BatchNorm层时使用
total_test_loss=0
total_accuracy=0
with torch.no_grad():#不需要梯度,用训练好的模型参数验证测试集
for data in test_dataloader:
imgs, targets = data # 获取数据集,图片,targets
output = tudui(imgs) # 将图片放入网络
loss = loss_fn(output, targets) # 计算每次损失值
total_test_loss=total_test_loss+loss.item() #累计每轮损失值
accuracy=(output.argmax(1)==targets).sum() #输出output是64*10,每行取最大值argmax(1),每列取最大值argmax(0) 计算每次准确率
total_accuracy=total_accuracy+accuracy #累计每轮准确率
print('整体测试集上的loss:{}'.format(total_test_loss))
print('整体测试集上的正确率:{}'.format(total_accuracy/test_data_size))
writer.add_scalar('test_loss', total_test_loss, total_test_step)
writer.add_scalar('test_accuracy',total_accuracy/test_data_size,total_test_step)
total_test_step+=1
每轮: 每次训练
获取一个batch_size(64)的图片及对应targets
将图片送入网络
计算损失值
优化器清零梯度
利用误差反向传播
优化器优化参数
每100次
打印一次训练次数,绘制此时损失值图
达到50000/64次,一轮训练部分完成,开始测试部分
设置初始损失值=0,准确率 =0
每次测试
获取一个batch_size(64)的图片及对应targets
将图片送入网络
计算每次损失值
累计每轮损失值
计算每次准确率
累计每轮准确率
达到10000/64次,一轮测试部分完成
绘制一轮的测试损失值图,打印准确率
模型保存
for i in range(epoch):
-----------------------------
----------训练部分------------
-----------------------------
-----------------------------
----------测试部分------------
-----------------------------
torch.save(tudui,'tudui_{}.pth'.format(i))
#torch.save(tudui.state_dict(),'tudui_{}.pth'.format(i))
print('第{}轮模型已保存'.format(i+1))
writer.close()
保存每轮的训练参数
结果
训练细节
模型.train(),模型.eval()在含dropout层和BatchNorm时使用