基于pytorch完整的训练一个神经网络并进行验证(代码片段)

Sol-itude Sol-itude     2022-12-06     531

关键词:

原视频链接:Pytorch深度学习快速入门教程(绝对通俗易懂!)【小土堆】

土堆老师的Github地址

之前学的也不少了,现在要去训练一个完整的神经网络,利用Pytorch和CIFAR10数据集

准备数据集

import torchvision#导入torchvision
##准备数据集
train_data=torchvision.datasets.CIFAR10(root="../data",train=True,transform=torchvision.transforms.ToTensor(),
                                        download=True)##数据集的目录,是否训练,将PIL型变为Tensor型,需要下载
test_data=torchvision.datasets.CIFAR10(root="../data",train=False,transform=torchvision.transforms.ToTensor(),
                                        download=True)

测试数据集长度

#length 长度
train_data_size=len(train_data)
test_data_size=len(test_data)
#如果train_data_size为10,训练集的长度为:10
print("训练数据集长度为:".format(train_data_size))#,会被替换为后面的值,把他变成字符串了
print("测试数据集长度为:".format(test_data_size))#,会被替换为后面的值,把他变成字符串了

输出结果

Files already downloaded and verified
Files already downloaded and verified
训练数据集长度为:50000
测试数据集长度为:10000

用DataLoader加载数据

#利用dataloader来加载数据集
train_dataloader=DataLoader(train_data,batch_size=64)#一次训练所抓取的数据样本数量为64
test_dataloader=DataLoader(test_data,batch_size=64)

搭建神经网络


这是CIFAR10 model的结构

class NetWork(nn.Module):
    def __init__(self):
        super(NetWork, self).__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

将此程序放入另一个新创建的python文件中,注意在同一个文件夹下

from torch import nn
import torch
class NetWork(nn.Module):
    def __init__(self):
        super(NetWork, self).__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__':
     network=NetWork()
     input=torch.ones((64,3,32,32))
     output=network(input)
     print(output.shape)

输出结果:

torch.Size([64, 10])

输出了64行,每一行上有10个数据,10代表了我们每一张图片在我们十个类别中的概率

创建损失函数

loss_fn=nn.CrossEntropyLoss()#交叉熵

创建优化器

learning_rate=0.01#学习速率
optimizer=torch.optim.SGD(network.parameters(),lr=learning_rate)#随机梯度下降,先填网络模型,然后是学习速率

开始训练

#设置训练网络的一些参数
total_train_step=0#记录训练次数
#记录测试的次数
total_test_step=0
#训练的轮数
epoch=10

for i in range(epoch):
    print("----------------第轮训练开始-------------".format(i+1))

    #训练步骤开始
    for data in train_dataloader:
        imgs,targets=data
        outputs=network(imgs)
        loss=loss_fn(outputs,targets)
        #优化器优化模型
        optimizer.zero_grad()#优化器梯度清零
        loss.backward()#反向传播
        optimizer.step()#优化器进行优化

        total_train_step=total_train_step+1 #记录训练次数
        print("训练次数:,Loss:".format(total_train_step,loss.item()))

输出结果

Files already downloaded and verified
Files already downloaded and verified
训练数据集长度为:50000
测试数据集长度为:10000
----------------1轮训练开始-------------
训练次数:1,Loss:2.31258487701416
训练次数:2,Loss:2.312842607498169
训练次数:3,Loss:2.302748918533325
训练次数:4,Loss:2.3247387409210205
训练次数:5,Loss:2.307778835296631
训练次数:6,Loss:2.311138868331909
训练次数:7,Loss:2.290013551712036
训练次数:8,Loss:2.302402973175049
训练次数:9,Loss:2.293430805206299
训练次数:10,Loss:2.2981677055358887

这里如果不停止会一直输出,所以,我们要把训练过程改善一下

    for data in train_dataloader:
        imgs,targets=data
        outputs=network(imgs)
        loss=loss_fn(outputs,targets)
        #优化器优化模型
        optimizer.zero_grad()#优化器梯度清零
        loss.backward()#反向传播
        optimizer.step()#优化器进行优化

        total_train_step=total_train_step+1 #记录训练次数
        if total_train_step %100==0:#每100次才打印
            print("训练次数:,Loss:".format(total_train_step,loss.item()))

每100次才打印数据

开始测试步骤

训练完毕之后,我们接下来采用测试数据进行测试

total_test_loss=0
    with torch.no_grad():
        for data in test_dataloader:
            imgs,targets =data
            outputs =network(imgs)#输入放到网络当中我们可以得到对应输出
            loss =loss_fn(outputs,targets)#计算误差
            total_test_loss=total_test_loss+loss.item()
    print("整体测试集上的Loss:".format(total_test_loss))

输出结果

Files already downloaded and verified
Files already downloaded and verified
训练数据集长度为:50000
测试数据集长度为:10000
----------------1轮训练开始-------------
训练次数:100,Loss:2.2861547470092773
训练次数:200,Loss:2.273378372192383
训练次数:300,Loss:2.238002300262451
训练次数:400,Loss:2.1429920196533203
训练次数:500,Loss:2.050020694732666
训练次数:600,Loss:2.005511522293091
训练次数:700,Loss:2.015151262283325
整体测试集上的Loss:314.1541121006012
----------------2轮训练开始-------------
训练次数:800,Loss:1.8569183349609375

训练结果可视化

为了使得我们可以清晰地看到训练结果,我们用Tensorboard把他画出来

需要在训练步骤和测试步骤里面加上一句代码

开头启用Tensorboard

writer=SummaryWriter("logs_train")

训练步骤下

    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)##标题,loss值,训练次数
            writer.add_scalar("train_loss",loss.item(),total_train_step)##标题,loss值,训练次数

测试步骤下

writer.add_scalar("test_loss",total_test_loss,total_test_step)##标题,测试误差值,测试次数
total_test_step=total_test_step+1

最后加上

writer.close()

在Terminal中加上启动tensorboard的代码,要在pytorch的环境下

tensorboard --logdir=logs_train

打开连接后,画出的图像如下

输出结果

train_loss

test_loss

loss一直在下降,证明训练有一定效果

拓展

二分类问题求准确率

先来了解一个函数叫做Argmax()

import torch
outputs=torch.Tensor([[0.1,0.2],
                      [0.3,0.4]])
print(outputs.argmax(1))#1表示横向,0表示纵向比较

输出结果

tensor([1, 1])

表示在横向上,0.2比0.1大,为1,0.4比0.3大,也为1,如果将argmax换成0

import torch
outputs=torch.Tensor([[0.1,0.2],
                      [0.05,0.4]])
print(outputs.argmax(0))#1表示横向,0表示纵向比较

输出结果

tensor([0, 1])

在纵向上,0.05比0.1小,所以是0,另一纵向同理

再将其与真实结果比较,计算其总和

import torch
outputs=torch.Tensor([[0.1,0.2],
                      [0.05,0.4]])
print(outputs.argmax(0))#1表示横向,0表示纵向比较

preds=outputs.argmax(1)
targets =torch.Tensor([0,1])
print((preds==targets).sum())

输出结果

tensor([1, 1])
tensor(1)

测试模型的准确率

通过以上的内容,我们可以优化我们的模型,计算其准确率

 total_test_loss=0
    total_accuracy=0#整体正确率
    with torch.no_grad():
        for data in test_dataloader:
            imgs,targets =data
            outputs =network(imgs)#输入放到网络当中我们可以得到对应输出
            loss =loss_fn(outputs,targets)#计算误差
            total_test_loss=total_test_loss+loss.item()
            accuracy=(outputs.argmax(1)==targets).sum()#横向准确率
            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=total_test_step+1

输出结果

----------------1轮训练开始-------------
训练次数:100,Loss:2.2833285331726074
训练次数:200,Loss:2.2706451416015625
训练次数:300,Loss:2.203575849533081
训练次数:400,Loss:2.102896213531494
训练次数:500,Loss:2.012601852416992
训练次数:600,Loss:2.006645441055298
训练次数:700,Loss:1.9837690591812134
整体测试集上的Loss:309.36241841316223
整体测试集上的正确率:0.2946999967098236

在Tensorboard中显示

准确率是在上升的

以上就是训练一个完整的模型的步骤了

完整代码

#######################一个完整的神经网络 准备数据,加载数据,准备模型,设置损失函数,设置优化器,开始训练,最后验证,结果聚合展示

import torchvision
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

from model import *#引入model中的所有import
##准备数据集
train_data=torchvision.datasets.CIFAR10(root="../data",train=True,transform=torchvision.transforms.ToTensor(),
                                        download=True)##数据集的目录,是否训练,将PIL型变为Tensor型,需要下载

test_data=torchvision.datasets.CIFAR10(root="../data",train=False,transform=torchvision.transforms.ToTensor(),
                                        download=True)
#length 长度
train_data_size=len(train_data)
test_data_size=len(test_data)
#如果train_data_size为10,训练集的长度为:10
print("训练数据集长度为:".format(train_data_size))#,会被替换为后面的值,把他变成字符串了
print("测试数据集长度为:".format(test_data_size))#,会被替换为后面的值,把他变成字符串了


#利用dataloader来加载数据集
train_dataloader=DataLoader(train_data,batch_size=64)#一次训练所抓取的数据样本数量为64
test_dataloader=DataLoader(test_data,batch_size=64)

#创建网络模型
network=NetWork()

#损失函数
loss_fn=nn.CrossEntropyLoss()#交叉熵

#优化器
learning_rate=0.01#学习速率
optimizer=torch.optim.SGD(network.parameters(),lr=learning_rate)#随机梯度下降,先填网络模型,然后是学习速率


#设置训练网络的一些参数
total_train_step=0#记录训练次数
#记录测试的次数
total_test_step=0
#训练的轮数
epoch=10

#添加tensorboard
writer=SummaryWriter("logs_train")

for i in range(epoch):
    print("----------------第轮训练开始-------------".format(i+1))

    #训练步骤开始
    network.train()
    for data in train_dataloader:
        imgs,targets=data
        outputs=network(imgs)
        loss=loss_fn(outputs,targets)
        #优化器优化模型
        optimizer.zero_grad()#优化器梯度清零
        loss.backward()#反向传播
        optimizer.step()#优化器进行优化

        total_train_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)##标题,loss值,训练次数
    #测试步骤开始
    network.eval()
    total_test_loss=0
    total_accuracy=0#整体正确率
    with torch.no_grad():#网络模型没有梯度,不需要梯度优化
        for data in test_dataloader:
            imgs,targets =data
            outputs =network(imgs)#输入放到网络当中我们可以得到对应输出
            loss =loss_fn(outputs,targets)#计算误差
            total_test_loss=total_test_loss+loss.item()
            accuracy=(outputs.argmax(1)==targets).sum()#横向准确率
            total_accuracy=total_accuracy+accuracy
    print("整体测试集上的Loss:".format(total_test_loss))
    print("整体测试集上的正确率:".format(total_accuracy/test_data_size))
    writer.add_scalar("test_loss"[深度学习][pytorch]pytorch实现一个简单得线性回归模型并训练

一个典型的神经网络的训练过程如下:定义具有学习参数(或权重)的神经网络迭代输入数据集根据神经网络对输入数据集进行运算计算损失(输出与真实结果的距离,损失越小说明模型越准确)将梯度反... 查看详情

pytorch定义并训练自己的数字数据集

这一篇主要讲解Pytorch搭建一个卷积神经网络识别自己的数字数据集基本流程。注:一开始接触很多教程都是直接加载datasets已有的MNIST等,如果想要训练自己的数据就可以采用这个方法。基本步骤:获取并读取数据-->定义网络... 查看详情

pytorch实现gat(基于pytorch实现)(代码片段)

...完整代码前言大家好,我是阿光。本专栏整理了《图神经网络代码实战》,内包含了不同图神经网络的相关代码实现(PyG以及自实现),理论与实践相结合,如GCN、GAT、GraphSAGE等经典图网络,每一个代... 查看详情

小白学习pytorch教程九基于pytorch训练第一个rnn模型(代码片段)

...,而不是从零开始理解每个单词。这可以称为记忆。卷积神经网络模型(CNN)不能实现这种记忆,因此引入了递归神经网络模型(RNN)来解决这一问题。RNN是带有循环的网络,允许信息持久存在。RNN的应用有:情绪分析(多对一... 查看详情

pt之transformer:基于pytorch框架利用transformer算法针对imdb数据集实现情感分类的应用案例代码解析(代码片段)

...表达的情感倾向。Transformer模型是一种基于注意力机制的神经网络模型,可以有效地处理自然语言处理任务。这个代码可以对电影评论进行情感分类,输出评论的情感极性(正面 查看详情

在 PyTorch 中使用 DataLoaders 进行 k 折交叉验证

】在PyTorch中使用DataLoaders进行k折交叉验证【英文标题】:k-foldcrossvalidationusingDataLoadersinPyTorch【发布时间】:2020-07-0801:20:57【问题描述】:我已将我的训练数据集拆分为80%的训练数据和20%的验证数据,并创建了如下所示的DataLoader... 查看详情

基于pytorch平台分类模型训练调式心得

参考技术A使用pytorch的心得及结论(一些定理):训练学习速率学习速率的调整对效果影响显著学习速率过大,则无法找到最优点,局部最优点也无法定位,因此无法收敛;学习速率过小,则只能徘徊在一段空间附近,只能找到... 查看详情

深度学习6.多层感知机及pytorch实现

....MLP多层感知机(MultilayerPerceptron)缩写为MLP,也称作前馈神经网络(FeedforwardNeuralNetwork)。它是一种基于神经网络的机器学习模型,通过多层非线性变换对输入数据进行高级别的抽象和分类。与单层感知机相比,MLP有多个隐藏层... 查看详情

PyTorch:在训练中添加验证错误

】PyTorch:在训练中添加验证错误【英文标题】:PyTorch:Addvalidationerrorintraining【发布时间】:2018-10-1620:01:53【问题描述】:我正在使用PyTorch训练一个cnn模型。这是我的网络架构:importtorchfromtorch.autogradimportVariableimporttorch.nnasnnimport... 查看详情

基于pytorch的神经网络之regression(代码片段)

目录1.引言2.神经网络搭建2.1准备工作2.2搭建网络2.3训练网络3.效果4.完整代码1.引言我们之前已经介绍了神经网络的基本知识,神经网络的主要作用就是预测与分类,现在让我们来搭建第一个用于拟合回归的神经网络吧。2... 查看详情

pytorch(网络模型训练)(代码片段)

上一篇目录标题网络模型训练小插曲训练模型数据训练GPU训练第一种方式方式二:查看GPU信息完整模型验证网络模型训练小插曲区别importtorcha=torch.tensor(5)print(a)print(a.item())importtorchoutput=torch.tensor([[0.1,0.2],[0.05,0.4]])print(ou... 查看详情

4.使用预训练的pytorch网络进行图像分类(代码片段)

4.使用预训练的PyTorch网络进行图像分类这篇博客将介绍如何使用PyTorch预先训练的网络执行图像分类。利用这些网络只需几行代码就可以准确地对1000个常见对象类别进行分类。这些图像分类网络是开创性的、最先进的图像分类网... 查看详情

4.使用预训练的pytorch网络进行图像分类(代码片段)

4.使用预训练的PyTorch网络进行图像分类这篇博客将介绍如何使用PyTorch预先训练的网络执行图像分类。利用这些网络只需几行代码就可以准确地对1000个常见对象类别进行分类。这些图像分类网络是开创性的、最先进的图像分类网... 查看详情

cv基础基于pytorch-unet训练二类别分割并测试

前言本文是基于pytorch_unet训练数据集进行二类语义分割,并完成测试;操作步骤: 问题:  参考1.github_Pytorch_Unet;2. 完 查看详情

从零开始学习深度学习35.门控循环神经网络之门控循环单元(gatedrecurrentunit,gru)介绍pytorch实现gru并进行训练预测

在循环神经网络中,当时间步数较大或者时间步较小时,循环神经网络的梯度较容易出现衰减或爆炸。上一篇文章中介绍的裁剪梯度可以应对梯度爆炸,但无法解决梯度衰减的问题。因此,循环神经网络在实际中... 查看详情

小白学习pytorch教程十一基于mnist数据集训练第一个生成性对抗网络(代码片段)

@Author:RunsenGAN是使用两个神经网络模型训练的生成模型。一种模型称为生成网络模型,它学习生成新的似是而非的样本。另一个模型被称为判别网络,它学习区分生成的例子和真实的例子。生成性对抗网络2014࿰... 查看详情

小白学习pytorch教程十一基于mnist数据集训练第一个生成性对抗网络(代码片段)

@Author:RunsenGAN是使用两个神经网络模型训练的生成模型。一种模型称为生成网络模型,它学习生成新的似是而非的样本。另一个模型被称为判别网络,它学习区分生成的例子和真实的例子。生成性对抗网络2014࿰... 查看详情

pytorch实现基于charrnn的文本分类与生成(代码片段)

Pytorch实现基于CharRNN的文本分类与生成标签:deep-learningpytorchnlp1简介本篇主要介绍使用pytorch实现基于CharRNN来进行文本分类与内容生成所需要的相关知识,并最终给出完整的实现代码。2相关API的说明pytorch框架中每种网络... 查看详情