资讯动态

27-29.完整的模型训练套路

发布时间:2026/10/17 10:39:29 来源:尧图企业网站定制
一、准备训练数据集1.选择数据集importtorchvisionfromtorch.utils.tensorboardimportSummaryWriterfrommodelimport*# 准备数据集fromtorchimportnnfromtorch.utils.dataimportDataLoader train_datatorchvision.datasets.CIFAR10(root../data,trainTrue,transformtorchvision.transforms.ToTensor(),downloadTrue)test_datatorchvision.datasets.CIFAR10(root../data,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue)# length 长度train_data_sizelen(train_data)test_data_sizelen(test_data)# 如果train_data_size10, 训练数据集的长度为10print(训练数据集的长度为{}.format(train_data_size))print(测试数据集的长度为{}.format(test_data_size))我们执行上述代码可以在下图查看控制台输出的数据集长度的信息。2.利用dataloader加载数据集importtorchvisionfromtorch.utils.tensorboardimportSummaryWriterfrommodelimport*# 准备数据集fromtorchimportnnfromtorch.utils.dataimportDataLoader train_datatorchvision.datasets.CIFAR10(root../data,trainTrue,transformtorchvision.transforms.ToTensor(),downloadTrue)test_datatorchvision.datasets.CIFAR10(root../data,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue)# length 长度train_data_sizelen(train_data)test_data_sizelen(test_data)# 如果train_data_size10, 训练数据集的长度为10print(训练数据集的长度为{}.format(train_data_size))print(测试数据集的长度为{}.format(test_data_size))# 利用 DataLoader 来加载数据集train_dataloaderDataLoader(train_data,batch_size64)test_dataloaderDataLoader(test_data,batch_size64)3.搭建神经网络importtorchfromtorchimportnn# 搭建神经网络classTudui(nn.Module):def__init__(self):super(Tudui,self).__init__()self.modelnn.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))defforward(self,x):xself.model(x)returnxif__name____main__:tuduiTudui()inputtorch.ones((64,3,32,32))outputtudui(input)print(output.shape)如下我们用torch.ones模拟输入数据查看打印出来的输出数据的形状确实是64 X 10 的矩阵。‌模型实例化: tudui Tudui()输入输出验证:输入64张3×32×32图像输出64×10矩阵每行代表一张图在10个类别上的概率分布测试输入: 使用torch.ones((64,3,32,32))创建模拟输入输出检查: 验证输出形状应为[64,10]运行方式: 在ifname ‘main’:块中测试为什么要用 torch.ones 而不是真实图片‌1‌调试模型结构‌在还没有准备好真实数据集或者想快速检查模型是否能跑通Forward Pass时用全1张量作为“dummy input”虚拟输入非常方便。‌2验证输出形状‌通过传入已知形状的输入可以确认模型输出的维度是否符合预期例如分类任务最后是否输出(64,10)。4.创建损失函数# 损失函数loss_fnnn.CrossEntropyLoss()5.创建优化器# 优化器# learning_rate 0.01# 1e-21 x (10)^(-2) 1 /100 0.01learning_rate1e-2optimizertorch.optim.SGD(tudui.parameters(),lrlearning_rate)6.关于.item()方法7.训练网络train.pyimporttorchvisionfromtorch.utils.tensorboardimportSummaryWriterfrommodelimport*# 准备数据集fromtorchimportnnfromtorch.utils.dataimportDataLoader train_datatorchvision.datasets.CIFAR10(root../data,trainTrue,transformtorchvision.transforms.ToTensor(),downloadTrue)test_datatorchvision.datasets.CIFAR10(root../data,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue)# length 长度train_data_sizelen(train_data)test_data_sizelen(test_data)# 如果train_data_size10, 训练数据集的长度为10print(训练数据集的长度为{}.format(train_data_size))print(测试数据集的长度为{}.format(test_data_size))# 利用 DataLoader 来加载数据集train_dataloaderDataLoader(train_data,batch_size64)test_dataloaderDataLoader(test_data,batch_size64)print(train_dataloader,train_dataloader)print(test_dataloader,test_dataloader)# 创建网络模型tuduiTudui()# 损失函数loss_fnnn.CrossEntropyLoss()# 优化器# learning_rate 0.01# 1e-21 x (10)^(-2) 1 /100 0.01learning_rate1e-2optimizertorch.optim.SGD(tudui.parameters(),lrlearning_rate)# 设置训练网络的一些参数# 记录训练的次数total_train_step0# 记录测试的次数total_test_step0# 训练的轮数epoch10# 添加tensorboardwriterSummaryWriter(../logs_train)foriinrange(epoch):print(-------第 {} 轮训练开始-------.format(i1))# 训练步骤开始tudui.train()fordataintrain_dataloader:imgs,targetsdata outputstudui(imgs)lossloss_fn(outputs,targets)# 优化器优化模型optimizer.zero_grad()loss.backward()optimizer.step()total_train_steptotal_train_step1iftotal_train_step%1000:print(训练次数{}, Loss: {}.format(total_train_step,loss.item()))writer.add_scalar(train_loss,loss.item(),total_train_step)# 测试步骤开始tudui.eval()total_test_loss0total_accuracy0withtorch.no_grad():fordataintest_dataloader:imgs,targetsdata outputstudui(imgs)lossloss_fn(outputs,targets)total_test_losstotal_test_lossloss.item()accuracy(outputs.argmax(1)targets).sum()total_accuracytotal_accuracyaccuracyprint(整体测试集上的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_steptotal_test_step1torch.save(tudui,tudui_{}.pth.format(i))print(模型已保存)writer.close()model.py模块化设计: 将模型类单独放在model.py文件中导入方式: 在train.py使用from model import *导入模型类文件结构: 确保模型文件和训练文件在同一目录下# -*- coding: utf-8 -*-# 作者小土堆# 公众号土堆碎念importtorchfromtorchimportnn# 搭建神经网络classTudui(nn.Module):def__init__(self):super(Tudui,self).__init__()self.modelnn.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))defforward(self,x):xself.model(x)returnxif__name____main__:tuduiTudui()inputtorch.ones((64,3,32,32))outputtudui(input)print(output.shape)测试目的: 在每轮训练完成后评估模型性能使用测试数据集计算损失或正确率来评估我们的模型有没有训练好。我们可以在tensorboard中查看到我们的损失是随着训练次数在下降的。关于正确率的计算分类问题中特有的衡量指标accuracy (outputs.argmax(1) targets).sum()我们有两个输入input.[0.1,0.2] 这个是指第一个输入的样本在0类别的概率是0.1在1类别的概率是0.2[0.3,0.4]这个是指第二个输入在0类别的概率是0.3在1类别的概率是0.4outputs是网络模型预测的输出这便相当于预测了第一个输入样本是1类别第二个 输入样本也是1类别。因为两个样本都是为1类别的概率更大些0.2大于0.10.4大于0.3所以preds是[1] [1]但是真实输入的 target表示第一个输入样本是0类别第二个输入样本是1类别argmax可以求出来横向的最大值所在的位置也就是第一行0.2所在的位置和第二行0.4所在的位置。所以通过argmax就可以从outputs这步转换为preds这步。preds的[1][1]表示预测的样本1的类别索引位置是1预测的样本2的类别索引位置也是1.根据preds和inputs target计算得出 第一个预测错误所以是false,第二个预测正确所以是true,两个相加得到1.计算preds和targets的对应位置相等的个数有多少其实就是算出来了正确的个数有多少。再除以总的个数就是正确率。‌accuracy (outputs.argmax(1) targets).sum()‌argmax(1) 取每个样本预测概率最大的类别与真实标签比较返回一个布尔张量.sum() 统计这一 batch 中‌预测正确的样本数‌。其实求的是preds和target中对应位置相等的个数有多少。argmax(1)是横向看argmax(0)是纵向看。如下argmax(0)纵向看第一列是第一行大所以是0第二列是第二行大所以是1.#模型保存与文件名格式化关于train和eval模式设置误区在训练步骤开始前设置model.train()和在测试前设置model.eval()并非强制要求只有当模型包含特定层如Dropout或BatchNorm时才需要显式调用特殊层影响这些模式设置主要影响Dropout层训练时随机失活评估时全连接和BatchNorm层训练时用batch统计量评估时用全局统计量模式切换原理train()将模块及其子模块设置为训练模式影响特定层的训练期行为eval()将模块设置为评估模式等价于train(False)整体流程整体代码train.pyimporttorchvisionfromtorch.utils.tensorboardimportSummaryWriterfrommodelimport*# 准备数据集fromtorchimportnnfromtorch.utils.dataimportDataLoader train_datatorchvision.datasets.CIFAR10(root../data,trainTrue,transformtorchvision.transforms.ToTensor(),downloadTrue)test_datatorchvision.datasets.CIFAR10(root../data,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue)# length 长度train_data_sizelen(train_data)test_data_sizelen(test_data)# 如果train_data_size10, 训练数据集的长度为10print(训练数据集的长度为{}.format(train_data_size))print(测试数据集的长度为{}.format(test_data_size))# 利用 DataLoader 来加载数据集train_dataloaderDataLoader(train_data,batch_size64)test_dataloaderDataLoader(test_data,batch_size64)# 创建网络模型tuduiTudui()# 损失函数loss_fnnn.CrossEntropyLoss()# 优化器# learning_rate 0.01# 1e-21 x (10)^(-2) 1 /100 0.01learning_rate1e-2optimizertorch.optim.SGD(tudui.parameters(),lrlearning_rate)# 设置训练网络的一些参数# 记录训练的次数total_train_step0# 记录测试的次数total_test_step0# 训练的轮数epoch10# 添加tensorboardwriterSummaryWriter(../logs_train)foriinrange(epoch):print(-------第 {} 轮训练开始-------.format(i1))# 训练步骤开始tudui.train()fordataintrain_dataloader:imgs,targetsdata outputstudui(imgs)lossloss_fn(outputs,targets)# 优化器优化模型optimizer.zero_grad()loss.backward()optimizer.step()total_train_steptotal_train_step1iftotal_train_step%1000:# 控制频率: 每100步打印⼀次训练信息print(训练次数{}, Loss: {}.format(total_train_step,loss.item()))writer.add_scalar(train_loss,loss.item(),total_train_step)# 测试步骤开始tudui.eval()total_test_loss0total_accuracy0withtorch.no_grad():fordataintest_dataloader:imgs,targetsdata outputstudui(imgs)lossloss_fn(outputs,targets)total_test_losstotal_test_lossloss.item()accuracy(outputs.argmax(1)targets).sum()total_accuracytotal_accuracyaccuracyprint(整体测试集上的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_steptotal_test_step1# 官方推荐方式torch.save(model.state_dict(), path)torch.save(tudui,tudui_{}.pth.format(i))print(模型已保存)writer.close()model.pyimporttorchfromtorchimportnn# 搭建神经网络classTudui(nn.Module):def__init__(self):super(Tudui,self).__init__()self.modelnn.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))defforward(self,x):xself.model(x)returnxif__name____main__:tuduiTudui()inputtorch.ones((64,3,32,32))outputtudui(input)print(output.shape)执行上述train.py文件代码控制台输出如下同时生成tudui系列pth文件。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑