赞
踩
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
- #main函数
- if __name__ == '__main__':
- tudui=Tudui()
- #验证网络模型的正确性,创造一个输入尺寸,判断输出尺寸是不是我们想要的
- input=torch.ones((64,3,32,32))#batchsize=64,channel=3,尺寸32*32
- output=tudui(input)
- print(output.shape)

如何测试搭建的神经网络模型是否符合要求,验证网络模型的正确性
创造一个输入尺寸,判断输出尺寸是不是我们想要的
if __name__ == '__main__':
tudui=Tudui()
#验证网络模型的正确性,创造一个输入尺寸,判断输出尺寸是不是我们想要的
input=torch.ones((64,3,32,32))#batchsize=64,channel=3,尺寸32*32的全1数据
output=tudui(input)
print(output.shape)
from model import *
#训练集 train_data=torchvision.datasets.CIFAR10("dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True) #测试集 test_data=torchvision.datasets.CIFAR10("dataset",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("训练数据集的长度为:{}".format(test_data_size))
train_dataloader=DataLoader(train_data,batch_size=64)#相当于将数据打包为一个batch一个batch的加载 test_databoader=DataLoader(test_data,batch_size=64)
tudui=Tudui()
loss_fn=nn.CrossEntropyLoss()#交叉熵损失函数多用于分类问题
# learning_rate=0.01#学习速率 1e-2=1x(10)^(-2)
learning_rate=1e-2
optimizer=torch.optim.SGD(tudui.parameters(),lr=learning_rate)#params:网络模型
#记录训练的次数 total_train_step=0 #记录测试的册数 total_test_step=0 #训练的轮数 epoch=10
#添加tensorboard
writer=SummaryWriter("logs_train")
for i in range(epoch):#设置训练轮数
print("----------第{}轮训练开始--------------".format(i+1))
#训练步骤开始
# 并不是说把网络设置为训练模式才可以训练
#作用是:当模块中有Dropout, BatchNor层时,一定要调用他,其对特定模块起作用,没有时也可以加它
tudui.train()
for data in train_dataloader:#从dataloader中一个batch一个batch的取数据
imgs,targets=data
output=tudui(imgs)#真实输出
#(1)计算真实输出与目标之间的误差
loss=loss_fn(output,targets)
#(2)优化器调优 优化模型
optimizer.zero_grad()#梯度清零
loss.backward()#反向传播,得到每个参数的梯度
optimizer.step()#对每个梯度进行优化
total_train_step=total_train_step+1#记录训练次数,一个batch一次
if total_train_step%100==0:#如果训练次数能整除100,输出,因为每次都输出太多太咋
print("训练次数:{},Loss:{}".format(total_train_step,loss.item()))
writer.add_scalar("train_losss",loss.item(),total_train_step)
#.item()作用:将tensor型输出为整数
如何知道模型有没有训练好?
在测试集上跑一遍,用测试数据集上的损失或正确率来评估模型有没有训练好
#(1)设置测试 参数 total_test_loss=0#总损失 total_accuracy=0#总体测试正确的个数 #(2)测试步骤开始, # 作用是:当模块中有Dropout, BatchNor层时,一定要调用他,其对特定模块起作用 tudui.eval() with torch.no_grad():#将网络模型中的梯度消失,只需要测试,不需要对梯度进行调整,也不需要利用梯度来优化 for data in test_databoader:#从测试集中取数据 imgs,targets=data outputs=tudui(imgs)# loss=loss_fn(outputs,targets)#计算损失 total_test_loss=total_test_loss+loss.item()#计算总损失 # 求每个对应位置最大的值和targets比较返回true或false。利用sum求和 accuracy=(outputs.argmax(1)==targets).sum() total_accuracy=total_accuracy+accuracy#计算测试正确的总个数
(3)关于argmax()的理解
以本文为例是求batch内的每个图片对应的10个输出中的最大值所在的位置,最大值代表该图片属于哪个类概率较大,位置编号代表类别的,所以要得到位置
这里output是64*10维,argmax(1),相当于求每一行的最大值对应的位置编号得到64*1维数据
targets是64*1维
==得到一个由true和false构成的64*1维的集合,.sum将true视为1,false视为0,求和,得到测试正确的个数
举例:

代码示例如下:
- import torch
-
- outputs=torch.tensor([[0.1,0.2],
- [0.3,0.4]])
- outputs.argmax(1)#1表示横向看,哪个大,将所在的位置返回
- print(outputs.argmax(1))#输出结果为tensor([1, 1])
- preds=outputs.argmax(1)
- targets=torch.tensor([0,1])
- print(preds==targets)#输出结果为tensor([False, True])
- print((preds==targets).sum())#计算相等的个数,输出结果为tensor(1)
print("整体测试集上的Loss: {}".format(total_test_loss))
print("整体测试集上的正确率:{}".format(total_accuracy/test_data_size))#正确率为测试正确的个数/测试集总个数
#将结果在tensorboard上展示
writer.add_scalar("test_accuracy",total_accuracy/test_data_size,total_test_step)
writer.add_scalar("test_loss",total_test_loss,total_test_step)
total_test_step=total_test_step+baba
#方式1:保存模型 torch.save(tudui,"tudui_{}.pth".format(i))#将模型保存在指定路径中 #方式2:保存模型 #torch.save(tudui.state_dict(),"tudui_{}.pth".format(i)) print("模型已保存")
以上步骤完整代码如下:
train.py
- import torch
- import torchvision.datasets
- #把model中的所有引入,model中有模型
- from torch.utils.tensorboard import SummaryWriter
-
- from model import *
- #1.准备数据集
- #训练集
- from torch import nn
- from torch.utils.data import DataLoader
- #训练集
- train_data=torchvision.datasets.CIFAR10("dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True)
- #测试集
- test_data=torchvision.datasets.CIFAR10("dataset",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("训练数据集的长度为:{}".format(test_data_size))
-
- #2.利用dataloader加载数据集
- train_dataloader=DataLoader(train_data,batch_size=64)
- test_databoader=DataLoader(test_data,batch_size=64)
-
- #3.创建网络模型
- tudui=Tudui()
-
- #4.定义损失函数
- loss_fn=nn.CrossEntropyLoss()
-
- #5.定义优化器
- # learning_rate=0.01#学习速率 1e-2=1x(10)^(-2)
- learning_rate=1e-2
- optimizer=torch.optim.SGD(tudui.parameters(),lr=learning_rate)#params:网络模型
-
- #6.设置训练网络的一些参数
- #记录训练的次数
- total_train_step=0
- #记录测试的册数
- total_test_step=0
- #训练的轮数
- epoch=10
-
- #添加tensorboard
- writer=SummaryWriter("logs_train")
-
- #7.设置训练轮数
- for i in range(epoch):
- print("----------第{}轮训练开始--------------".format(i+1))
- #训练步骤开始
- # 并不是说把网络设置为训练模式才可以训练
- #作用是:当模块中有Dropout, BatchNor层时,一定要调用他,其对特定模块起作用
- tudui.train()
- for data in train_dataloader:#从dataloader中一个batch一个batch的取数据
- imgs,targets=data
- output=tudui(imgs)#真实输出
- #(1)计算真实输出与目标之间的误差
- loss=loss_fn(output,targets)
-
- #(2)优化器调优 优化模型
- optimizer.zero_grad()#梯度清零
- loss.backward()#反向传播,得到每个参数的梯度
- optimizer.step()#对每个梯度进行优化
-
- total_train_step=total_train_step+1
-
- if total_train_step%100==0:
- print("训练次数:{},Loss:{}".format(total_train_step,loss.item()))
- writer.add_scalar("train_losss",loss.item(),total_train_step)
-
- #如何知道模型有没有训练好---------进行测试,在测试集上跑一遍,用测试数据集上的损失或正确率来评估模型有没有训练好
- #8.测试
- #(1)设置测试 参数
- total_test_loss=0#总损失
- total_accuracy=0#整体正确率
- #(2)测试步骤开始,
- # 作用是:当模块中有Dropout, BatchNor层时,一定要调用他,其对特定模块起作用
- tudui.eval()
- with torch.no_grad():#将网络模型中的梯度消失,只需要测试,不需要对梯度进行调整,也不需要利用梯度来优化
- for data in test_databoader:#从测试集中取数据
- imgs,targets=data
- outputs=tudui(imgs)
- loss=loss_fn(outputs,targets)
- total_test_loss=total_test_loss+loss.item()
- # 求每个对应位置最大的值和targets比较返回true或false。利用sum求和
- accuracy=(outputs.argmax(1)==targets).sum()
- total_accuracy=total_accuracy+accuracy
- #9.计算测试集的loss,正确率,以此展现训练网络在测试集上的效果
- print("整体测试集上的Loss: {}".format(total_test_loss))
- print("整体测试集上的正确率:{}".format(total_accuracy/test_data_size))#正确率为测试正确的个数/测试集总个数
- writer.add_scalar("test_accuracy",total_accuracy/test_data_size,total_test_step)
- writer.add_scalar("test_loss",total_test_loss,total_test_step)
- total_test_step=total_test_step+1
- #12.保存模型(在特定的步数或某一轮保存模型)
- #方式1:保存模型
- torch.save(tudui,"tudui_{}.pth".format(i))#将模型保存在指定路径中
- #方式2:保存模型
- #torch.sava(tudui.state_dict(),"tudui_{}.pth".format(i))
- print("模型已保存")
-
- writer.close()
-

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。