完整的模型训练套路 pytorch

**前置知识:

1、

(1).train():将模型设置为训练模式

(2).eval():将模型设置为评估模式

不写也可以(只对特定网络模型有作用,如含有Dropout的)

2、

with torch.no_grad()::主要用于评估和推理,确保不会计算梯度,从而节省内存和加速计算。

3、

.item()的作用:将tensor型转为普通数值型

当你有一个只有一个元素的张量时,可以使用 .item() 来提取这个值。

复制代码
a=torch.tensor(5)
print(a) #tensor(5)
print((a.item())) #5

4、

如何由分类得分来计算正确率:

复制代码
outputs=torch.tensor([
    [0.1,0.2],
    [0.3,0.4]
]) #两个样本的二分类得分

preds=outputs.argmax(1) #1是横向对比,0是纵向对比,得到预测的分类:[1,1]

targets=torch.tensor([0,1]) #正确的分类

print(preds==targets) #tensor([False,  True])
print((preds==targets).sum()) #tensor(1)
print((preds==targets).sum().item()/2) #正确率=分类正确的样本数/总样本数,得0.5

**代码:

python 复制代码
import torch.optim
import torchvision.datasets
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

from model import * #引入模型类文件

一、准备数据集:

python 复制代码
#准备数据集
train_set=torchvision.datasets.CIFAR10(root="../dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True)
test_set=torchvision.datasets.CIFAR10(root="../dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

train_set_size=len(train_set)
test_set_size=len(test_set)
print(f"训练数据集的长度为:{train_set_size}")
print(f"测试数据集的长度为:{test_set_size}")

train_dataloader=DataLoader(train_set,batch_size=64)
test_dataloader=DataLoader(test_set,batch_size=64)

二、创建网络模型:

模型类的定义单独写在一个文件夹里

python 复制代码
import torch
from torch import nn

#搭建神经网络
class Classification_CIFAR10(nn.Module):
    def __init__(self):
        super().__init__()
        self.model=nn.Sequential(
            nn.Conv2d(in_channels=3,out_channels=32,kernel_size=5,stride=1,padding="same"), #stride默认等于1,padding没有设置则是0
            nn.MaxPool2d(kernel_size=2), #stride默认等于kernel_size,padding没有设置则是0
            nn.Conv2d(in_channels=32,out_channels=32,kernel_size=5,stride=1,padding="same"),
            nn.MaxPool2d(2),
            nn.Conv2d(in_channels=32,out_channels=64,kernel_size=5,stride=1,padding="same"),
            nn.MaxPool2d(2),
            nn.Flatten(),
            nn.Linear(in_features=64*4*4,out_features=64),
            nn.Linear(in_features=64,out_features=10)
        )

    def forward(self,x):
        x=self.model(x)
        return x

#测试模型的正确性:设一个input,看output的尺寸是否正确
if __name__ == '__main__':
    model=Classification_CIFAR10()
    input=torch.ones((64,3,32,32))
    output=model(input)
    print(output.shape)
    #[ 0.0308, -0.0105, -0.0186,  0.2409, -0.0044,  0.0182,  0.1824, -0.0557, -0.1188,  0.0300]

#输入:一张3通道的图像(大小为32*32)------>64通道(大小为4*4)------>全连接后linear成64通道------>最后linnear成10通道(即十个类别的得分)
#(1,3,32,32)------>(1,10)同理,(64,3,32,32)------>(64,10)
python 复制代码
#创建网络模型
model_classification=Classification_CIFAR10()

三、参数和辅助工具的设置:

(损失函数,优化器;训练、测试的次数记录;tensorboard)

python 复制代码
#损失函数
loss_func=nn.CrossEntropyLoss() #optional表示参数是可选的

#优化器
learning_rate=1e-2 #相当于(0.01)
optimizer=torch.optim.SGD(model_classification.parameters(),lr=learning_rate) #随机梯度下降

#设置训练网络的一些参数
total_train_step=0 #记录训练的次数
total_test_step=0 #记录测试的次数
epoch=2 #训练、测试的轮数(一轮有多次,次数=imgs总数/每次处理的图片数)

#添加tensorboard来监控数据的变化
writer=SummaryWriter("E:\DLearning\Learning\logs") #路径问题,换成绝对路径试一试

四、开始训练和测试:

python 复制代码
for i in range(epoch):

    print(f"------------------------------------------第{i+1}轮训练开始------------------------------------------")
    #训练步骤开始
    for data in train_dataloader:
        imgs,targets=data
        outputs=model_classification(imgs)
        #计算损失
        loss=loss_func(outputs,targets)
        #优化
        optimizer.zero_grad() #梯度清零
        loss.backward() #计算梯度并反向传播
        optimizer.step() #梯度优化(跳跃式)

        total_train_step=total_train_step+1
        if total_train_step%100==0: #逢百才打印、记录(更节省、更清晰)
            print(f"训练次数:{total_train_step},Loss:{loss.item()}")
            writer.add_scalar("train_loss",loss.item(),total_train_step)


    #每训练完一轮后,用验证集来测试,看看训练的效果如何
    print(f"------------------------------------------第{i + 1}轮测试开始------------------------------------------")
    #测试步骤开始
    total_test_loss=0
    total_accuracy=0
    with torch.no_grad(): #不需要调优了,利用现有模型------>with里面的代码就没有了梯度,能保证不会对它进行调优(即使不调用也会累计梯度,会使进程变慢)
        for data in test_dataloader:
            imgs,targets=data
            outputs=model_classification(imgs)
            #求损失
            loss=loss_func(outputs,targets)
            total_test_loss+=loss.item()
            #求正确数(分类特有的)
            accuracy=(outputs.argmax(1)==targets).sum()
            total_accuracy+=accuracy
    print(f"整体测试集的Loss:{total_test_loss}")
    print(f"整体测试集的正确率:{total_accuracy/test_set_size}")
    writer.add_scalar("test_total_loss",total_test_loss,i+1)
    writer.add_scalar("test_total_accuracy",total_accuracy/test_set_size,i+1)

    #保存每一轮的模型训练结果
    torch.save(model_classification,f"model{i+1}.pth")
    print("模型已保存")

writer.close()
相关推荐
余炜yw2 分钟前
【LSTM实战】跨越千年,赋诗成文:用LSTM重现唐诗的韵律与情感
人工智能·rnn·深度学习
drebander9 分钟前
使用 Java Stream 优雅实现List 转化为Map<key,Map<key,value>>
java·python·list
莫叫石榴姐19 分钟前
数据科学与SQL:组距分组分析 | 区间分布问题
大数据·人工智能·sql·深度学习·算法·机器学习·数据挖掘
威威猫的栗子32 分钟前
Python Turtle召唤童年:喜羊羊与灰太狼之懒羊羊绘画
开发语言·python
如若12341 分钟前
利用 `OpenCV` 和 `Matplotlib` 库进行图像读取、颜色空间转换、掩膜创建、颜色替换
人工智能·opencv·matplotlib
YRr YRr1 小时前
深度学习:神经网络中的损失函数的使用
人工智能·深度学习·神经网络
ChaseDreamRunner1 小时前
迁移学习理论与应用
人工智能·机器学习·迁移学习
Guofu_Liao1 小时前
大语言模型---梯度的简单介绍;梯度的定义;梯度计算的方法
人工智能·语言模型·矩阵·llama
我爱学Python!1 小时前
大语言模型与图结构的融合: 推荐系统中的新兴范式
人工智能·语言模型·自然语言处理·langchain·llm·大语言模型·推荐系统
墨染风华不染尘1 小时前
python之开发笔记
开发语言·笔记·python