当前位置:网站首页>基于Pytorch完整的训练一个神经网络并进行验证
基于Pytorch完整的训练一个神经网络并进行验证
2022-07-01 02:40:00 【Sol-itude】
原视频链接:Pytorch深度学习快速入门教程(绝对通俗易懂!)【小土堆】
之前学的也不少了,现在要去训练一个完整的神经网络,利用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",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
torch.save(network,"network_{}.pth".format(i))#保存每一轮的训练结果
print("模型已保存")
writer.close()
利用GPU去训练神经网络
只需要稍作改动
#创建网络模型
network=NetWork()
if torch.cuda.is_available():
network=network.cuda()#利用gpu进行训练
损失函数改成cuda
#损失函数
loss_fn=nn.CrossEntropyLoss()#交叉熵
loss_fn=loss_fn.cuda()#利用gpu训练
在训练和测试那里,吧imgs和targets改成cuda就OK了
imgs=imgs.cuda()
targets=targets.cuda()
跟CPU跑的比较了下,CPU跑100轮用了4.9s,GPU用了3.2s,确实会快
验证网络模型
万事俱备只欠东风,现在我们可以去拿训练好的网络去预测一只狗狗了,
首先从网上找一个狗狗的照片,这里就不展示了
将狗狗的照片放入你的Pytorch文件夹下,然后就可以编写代码了
import torch
import torchvision.transforms
from PIL import Image
from torch import nn
image_path="你的狗狗照片的绝对路径"
image=Image.open(image_path)
image=image.convert('RGB')#保持其颜色通道
transform=torchvision.transforms.Compose([torchvision.transforms.Resize((32,32)),
torchvision.transforms.ToTensor()])## 将输入图片resize成统一尺寸,# 将PIL Image或numpy.ndarray转换为tensor,并归一化到[0,1]之间
image=transform(image)
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
model=torch.load("network_gpu_9.pth",map_location=torch.device('cpu'))#保存模型,从gpu映射到cpu上,读取之前训练好的模型,我用的是训练10轮的
image=torch.reshape(image,(1,3,32,32))#batch_size,3个颜色通道 32*32
model.eval()
with torch.no_grad():
output=model(image)
print(output)
print(output.argmax(1))
输出结果
tensor([[-0.5509, -0.1295, 1.7645, 3.3668, -3.0762, 4.5566, 3.2504, 0.9605,
-6.5720, -1.3539]])
tensor([5])
对照表格,我们可以发现,经过训练,电脑大概知道了狗狗的样子
边栏推荐
- Mouse over effect I
- (summary I) Halcon Foundation's target finding features + becoming a regular
- 鼠标悬停效果八
- Optimal Transport系列1
- 股票开户安全吗?上海股票开户步骤。
- 我的PMP学习考试心得
- Pytoch -- foundation refers to the north_ II. What high school students can understand [back propagation and gradient descent]
- (总结一)Halcon基础之寻找目标特征+转正
- js防抖和节流
- 基于OPENCV和图像减法的PCB缺陷检测
猜你喜欢
手机edge浏览器无法打开三方应用
SWT / anr problem - storagemanagerservice stuck
The mobile edge browser cannot open the third-party application
Nacos configuration center tutorial
Image preloading in JS
Detailed data governance knowledge system
5款主流智能音箱入门款测评:苹果小米华为天猫小度,谁的表现更胜一筹?
Pycharm 打开远程目录 Remote Host
[JS] [Nuggets] get people who are not followers
Leetcode interview question 17.10 Main elements
随机推荐
Open source basic software companies, looking for you to create the future together (api7.ai)
Lenovo x86 server restart management controller (xclarity controller) or TSM method
C # generates PPK files in putty format (supports passphrase)
js中的原型和原型链
What is project management?
鼠标悬停效果十
鼠标悬停效果六
[multi source BFS] 934 Shortest Bridge
Mouse over effect II
零基础自学SQL课程 | 窗口函数
How to use Jieba participle in unity
Desai wisdom number - other charts (parallel coordinate chart): employment of fresh majors in 2021
十大券商有哪些?另外想问,现在在线开户安全么?
记一次服务部署失败问题排查
[wechat applet development] style summary
SWT / anr problem - deadlock
A preliminary understanding of operator overloading
VirtualBox installation enhancements
My PMP learning test experience
SAP ALV summary is inconsistent with exported excel summary data