当前位置:   article > 正文

PyTorch快速入门教程【小土堆】-神经网络-完整的模型训练套路_with torch.no_grad():小土堆

with torch.no_grad():小土堆

一.创建一个python文件model.py,在里面搭建神经网络模型

model.py

  1. #搭建神经网络
  2. import torch
  3. from torch import nn
  4. class Tudui(nn.Module):
  5. def __init__(self) -> None:
  6. super().__init__()
  7. self.model=nn.Sequential(
  8. nn.Conv2d(3,32,5,1,2),
  9. nn.MaxPool2d(2),
  10. nn.Conv2d(32,32,5,1,2),
  11. nn.MaxPool2d(2),
  12. nn.Conv2d(32,64,5,1,2),
  13. nn.MaxPool2d(2),
  14. nn.Flatten(),
  15. nn.Linear(64*4*4,64),
  16. nn.Linear(64,10)
  17. )
  18. def forward(self,x):
  19. x=self.model(x)
  20. return x
  21. #main函数
  22. if __name__ == '__main__':
  23. tudui=Tudui()
  24. #验证网络模型的正确性,创造一个输入尺寸,判断输出尺寸是不是我们想要的
  25. input=torch.ones((64,3,32,32))#batchsize=64,channel=3,尺寸32*32
  26. output=tudui(input)
  27. 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)

二.创建另一个python文件Train.py用于训练和测试,引入刚才创建的模型

from model import *

1.准备数据集

#训练集
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)#相当于将数据打包为一个batch一个batch的加载
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#记录训练次数,一个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型输出为整数

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#计算测试正确的总个数

(3)关于argmax()的理解

以本文为例是求batch内的每个图片对应的10个输出中的最大值所在的位置,最大值代表该图片属于哪个类概率较大,位置编号代表类别的,所以要得到位置

这里output是64*10维argmax(1),相当于求每一行的最大值对应的位置编号得到64*1维数据

targets是64*1维

==得到一个由true和false构成的64*1维的集合,.sum将true视为1,false视为0,求和,得到测试正确的个数

举例:

代码示例如下:

  1. import torch
  2. outputs=torch.tensor([[0.1,0.2],
  3. [0.3,0.4]])
  4. outputs.argmax(1)#1表示横向看,哪个大,将所在的位置返回
  5. print(outputs.argmax(1))#输出结果为tensor([1, 1])
  6. preds=outputs.argmax(1)
  7. targets=torch.tensor([0,1])
  8. print(preds==targets)#输出结果为tensor([False, True])
  9. print((preds==targets).sum())#计算相等的个数,输出结果为tensor(1)

 

9.计算测试集的loss,正确率,以此展现训练网络在测试集上的效果

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

12.保存模型(在特定步数或某一轮保存模型)

#方式1:保存模型
torch.save(tudui,"tudui_{}.pth".format(i))#将模型保存在指定路径中
#方式2:保存模型
#torch.save(tudui.state_dict(),"tudui_{}.pth".format(i))
print("模型已保存")

以上步骤完整代码如下:

train.py

  1. import torch
  2. import torchvision.datasets
  3. #把model中的所有引入,model中有模型
  4. from torch.utils.tensorboard import SummaryWriter
  5. from model import *
  6. #1.准备数据集
  7. #训练集
  8. from torch import nn
  9. from torch.utils.data import DataLoader
  10. #训练集
  11. train_data=torchvision.datasets.CIFAR10("dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True)
  12. #测试集
  13. test_data=torchvision.datasets.CIFAR10("dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)
  14. #查看数据集有多少数据
  15. train_data_size=len(train_data)
  16. test_data_size=len(test_data)
  17. print("训练数据集的长度为:{}".format(train_data_size))
  18. print("训练数据集的长度为:{}".format(test_data_size))
  19. #2.利用dataloader加载数据集
  20. train_dataloader=DataLoader(train_data,batch_size=64)
  21. test_databoader=DataLoader(test_data,batch_size=64)
  22. #3.创建网络模型
  23. tudui=Tudui()
  24. #4.定义损失函数
  25. loss_fn=nn.CrossEntropyLoss()
  26. #5.定义优化器
  27. # learning_rate=0.01#学习速率 1e-2=1x(10)^(-2)
  28. learning_rate=1e-2
  29. optimizer=torch.optim.SGD(tudui.parameters(),lr=learning_rate)#params:网络模型
  30. #6.设置训练网络的一些参数
  31. #记录训练的次数
  32. total_train_step=0
  33. #记录测试的册数
  34. total_test_step=0
  35. #训练的轮数
  36. epoch=10
  37. #添加tensorboard
  38. writer=SummaryWriter("logs_train")
  39. #7.设置训练轮数
  40. for i in range(epoch):
  41. print("----------第{}轮训练开始--------------".format(i+1))
  42. #训练步骤开始
  43. # 并不是说把网络设置为训练模式才可以训练
  44. #作用是:当模块中有Dropout, BatchNor层时,一定要调用他,其对特定模块起作用
  45. tudui.train()
  46. for data in train_dataloader:#从dataloader中一个batch一个batch的取数据
  47. imgs,targets=data
  48. output=tudui(imgs)#真实输出
  49. #(1)计算真实输出与目标之间的误差
  50. loss=loss_fn(output,targets)
  51. #(2)优化器调优 优化模型
  52. optimizer.zero_grad()#梯度清零
  53. loss.backward()#反向传播,得到每个参数的梯度
  54. optimizer.step()#对每个梯度进行优化
  55. total_train_step=total_train_step+1
  56. if total_train_step%100==0:
  57. print("训练次数:{},Loss:{}".format(total_train_step,loss.item()))
  58. writer.add_scalar("train_losss",loss.item(),total_train_step)
  59. #如何知道模型有没有训练好---------进行测试,在测试集上跑一遍,用测试数据集上的损失或正确率来评估模型有没有训练好
  60. #8.测试
  61. #(1)设置测试 参数
  62. total_test_loss=0#总损失
  63. total_accuracy=0#整体正确率
  64. #(2)测试步骤开始,
  65. # 作用是:当模块中有Dropout, BatchNor层时,一定要调用他,其对特定模块起作用
  66. tudui.eval()
  67. with torch.no_grad():#将网络模型中的梯度消失,只需要测试,不需要对梯度进行调整,也不需要利用梯度来优化
  68. for data in test_databoader:#从测试集中取数据
  69. imgs,targets=data
  70. outputs=tudui(imgs)
  71. loss=loss_fn(outputs,targets)
  72. total_test_loss=total_test_loss+loss.item()
  73. # 求每个对应位置最大的值和targets比较返回true或false。利用sum求和
  74. accuracy=(outputs.argmax(1)==targets).sum()
  75. total_accuracy=total_accuracy+accuracy
  76. #9.计算测试集的loss,正确率,以此展现训练网络在测试集上的效果
  77. print("整体测试集上的Loss: {}".format(total_test_loss))
  78. print("整体测试集上的正确率:{}".format(total_accuracy/test_data_size))#正确率为测试正确的个数/测试集总个数
  79. writer.add_scalar("test_accuracy",total_accuracy/test_data_size,total_test_step)
  80. writer.add_scalar("test_loss",total_test_loss,total_test_step)
  81. total_test_step=total_test_step+1
  82. #12.保存模型(在特定的步数或某一轮保存模型)
  83. #方式1:保存模型
  84. torch.save(tudui,"tudui_{}.pth".format(i))#将模型保存在指定路径中
  85. #方式2:保存模型
  86. #torch.sava(tudui.state_dict(),"tudui_{}.pth".format(i))
  87. print("模型已保存")
  88. writer.close()

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/51800
推荐阅读
相关标签
  

闽ICP备14008679号