如何使用Pytorch搭建模型


Posted in Python onOctober 26, 2020

1  模型定义

和TF很像,Pytorch也通过继承父类来搭建模型,同样也是实现两个方法。在TF中是__init__()和call(),在Pytorch中则是__init__()和forward()。功能类似,都分别是初始化模型内部结构和进行推理。其它功能比如计算loss和训练函数,你也可以继承在里面,当然这是可选的。下面搭建一个判别MNIST手写字的Demo,首先给出模型代码:

import numpy as np
import matplotlib.pyplot as plt 
import torch 
from torch import nn,optim 
from torchsummary import summary 
from keras.datasets import mnist
from keras.utils import to_categorical
device = torch.device('cuda') #——————1——————
 
class ModelTest(nn.Module):
 def __init__(self,device):
  super().__init__() 
  self.layer1 = nn.Sequential(nn.Flatten(),nn.Linear(28*28,512),nn.ReLU())#——————2——————
  self.layer2 = nn.Sequential(nn.Linear(512,512),nn.ReLU()) 
  self.layer3 = nn.Sequential(nn.Linear(512,512),nn.ReLU())
  self.layer4 = nn.Sequential(nn.Linear(512,10),nn.Softmax()) 

  self.to(device) #——————3——————
  self.opt = optim.SGD(self.parameters(),lr=0.01)#——————4——————
 def forward(self,inputs): #——————5——————
  x = self.layer1(inputs)
  x = self.layer2(x)
  x = self.layer3(x)
  x = self.layer4(x)
  return x 
 def get_loss(self,true_labels,predicts): 
  loss = -true_labels * torch.log(predicts) #——————6——————
  loss = torch.mean(loss)
  return loss
 def train(self,imgs,labels): 
  predicts = model(imgs) 
  loss = self.get_loss(labels,predicts)
  self.opt.zero_grad()#——————7——————
  loss.backward()#——————8——————
  self.opt.step()#——————9——————
model = ModelTest(device)
summary(model,(1,28,28),3,device='cuda') #——————10——————

#1:获取设备,以方便后面的模型与变量进行内存迁移,设备名只有两种:'cuda'和'cpu'。通常是在你有GPU的情况下需要这样显式进行设备的设置,从而在需要时,你可以将变量从主存迁移到显存中。如果没有GPU,不获取也没事,pytorch会默认将参数都保存在主存中。

#2:模型中层的定义,可以使用Sequential将想要统一管理的层集中表示为一层。

#3:在初始化中将模型参数迁移到GPU显存中,加速运算,当然你也可以在需要时在外部执行model.to(device)进行迁移。

#4:定义模型的优化器,和TF不同,pytorch需要在定义时就将需要梯度下降的参数传入,也就是其中的self.parameters(),表示当前模型的所有参数。实际上你不用担心定义优化器和模型参数的顺序问题,因为self.parameters()的输出并不是模型参数的实例,而是整个模型参数对象的指针,所以即使你在定义优化器之后又定义了一个层,它依然能优化到。当然优化器你也可以在外部定义,传入model.parameters()即可。这里定义了一个随机梯度下降。

#5:模型的前向传播,和TF的call()类似,定义好model()所执行的就是这个函数。

#6:我将获取loss的函数集成在了模型中,这里计算的是真实标签和预测标签之间的交叉熵。

#7/8/9:在TF中,参数梯度是保存在梯度带中的,而在pytorch中,参数梯度是各自集成在对应的参数中的,可以使用tensor.grad来查看。每次对loss执行backward(),pytorch都会将参与loss计算的所有可训练参数关于loss的梯度叠加进去(直接相加)。所以如果我们没有叠加梯度的意愿的话,那就要在backward()之前先把之前的梯度删除。又因为我们前面已经把待训练的参数都传入了优化器,所以,对优化器使用zero_grad(),就能把所有待训练参数中已存在的梯度都清零。那么梯度叠加什么时候用到呢?比如批量梯度下降,当内存不够直接计算整个批量的梯度时,我们只能将批量分成一部分一部分来计算,每算一个部分得到loss就backward()一次,从而得到整个批量的梯度。梯度计算好后,再执行优化器的step(),优化器根据可训练参数的梯度对其执行一步优化。

#10:使用torchsummary函数显示模型结构。奇怪为什么不把这个继承在torch里面,要重新安装一个torchsummary库。

2  训练及可视化

接下来使用模型进行训练,因为pytorch自带的MNIST数据集并不好用,所以我使用的是Keras自带的,定义了一个获取数据的生成器。下面是完整的训练及绘图代码(50次迭代记录一次准确率):

import numpy as np
import matplotlib.pyplot as plt 
import torch 
from torch import nn,optim 
from torchsummary import summary 
from keras.datasets import mnist
from keras.utils import to_categorical
device = torch.device('cuda') #——————1——————
 
class ModelTest(nn.Module):
 def __init__(self,device):
  super().__init__() 
  self.layer1 = nn.Sequential(nn.Flatten(),nn.Linear(28*28,512),nn.ReLU())#——————2——————
  self.layer2 = nn.Sequential(nn.Linear(512,512),nn.ReLU()) 
  self.layer3 = nn.Sequential(nn.Linear(512,512),nn.ReLU())
  self.layer4 = nn.Sequential(nn.Linear(512,10),nn.Softmax()) 

  self.to(device) #——————3——————
  self.opt = optim.SGD(self.parameters(),lr=0.01)#——————4——————
 def forward(self,inputs): #——————5——————
  x = self.layer1(inputs)
  x = self.layer2(x)
  x = self.layer3(x)
  x = self.layer4(x)
  return x 
 def get_loss(self,true_labels,predicts): 
  loss = -true_labels * torch.log(predicts) #——————6——————
  loss = torch.mean(loss)
  return loss
 def train(self,imgs,labels): 
  predicts = model(imgs) 
  loss = self.get_loss(labels,predicts)
  self.opt.zero_grad()#——————7——————
  loss.backward()#——————8——————
  self.opt.step()#——————9——————
def get_data(device,is_train = True, batch = 1024, num = 10000):
 train_data,test_data = mnist.load_data()
 if is_train:
  imgs,labels = train_data
 else:
  imgs,labels = test_data 
 imgs = (imgs/255*2-1)[:,np.newaxis,...]
 labels = to_categorical(labels,10) 
 imgs = torch.tensor(imgs,dtype=torch.float32).to(device)
 labels = torch.tensor(labels,dtype=torch.float32).to(device)
 i = 0
 while(True):
  i += batch
  if i > num:
   i = batch 
  yield imgs[i-batch:i],labels[i-batch:i] 
train_dg = get_data(device, True,batch=4096,num=60000) 
test_dg = get_data(device, False,batch=5000,num=10000) 

model = ModelTest(device) 
summary(model,(1,28,28),11,device='cuda') 
ACCs = []
import time
start = time.time()
for j in range(20000):
 #训练
 imgs,labels = next(train_dg)
 model.train(imgs,labels)

 #验证
 img,label = next(test_dg)
 predicts = model(img) 
 acc = 1 - torch.count_nonzero(torch.argmax(predicts,axis=1) - torch.argmax(label,axis=1))/label.shape[0]
 if j % 50 == 0:
  t = time.time() - start
  start = time.time()
  ACCs.append(acc.cpu().numpy())
  print(j,t,'ACC: ',acc)
#绘图
x = np.linspace(0,len(ACCs),len(ACCs))
plt.plot(x,ACCs)

准确率变化图如下:

如何使用Pytorch搭建模型

3   注意事项

需要注意的是,pytorch的tensor基于numpy的array,它们是共享内存的。也就是说,如果你把tensor直接插入一个列表,当你修改这个tensor时,列表中的这个tensor也会被修改;更容易被忽略的是,即使你用tensor.detach.numpy(),先将tensor转换为array类型,再插入列表,当你修改原本的tensor时,列表中的这个array也依然会被修改。所以如果我们只是想保存tensor的值而不是整个对象,就要使用np.array(tensor)将tensor的值复制出来。

以上就是如何使用Pytorch搭建模型的详细内容,更多关于Pytorch搭建模型的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python读大数据txt
Mar 28 Python
简单谈谈Python中的反转字符串问题
Oct 24 Python
python 动态加载的实现方法
Dec 22 Python
初探TensorFLow从文件读取图片的四种方式
Feb 06 Python
python实现简易内存监控
Jun 21 Python
python 异或加密字符串的实例
Oct 14 Python
django使用admin站点上传图片的实例
Jul 28 Python
基于Python解密仿射密码
Oct 21 Python
基于python读取.mat文件并取出信息
Dec 16 Python
Python变量、数据类型、数据类型转换相关函数用法实例详解
Jan 09 Python
django使用channels实现通信的示例
Oct 19 Python
关于python tushare Tkinter构建的简单股票可视化查询系统(Beta v0.13)
Oct 19 Python
使用python-cv2实现视频的分解与合成的示例代码
Oct 26 #Python
python递归函数用法详解
Oct 26 #Python
Python实现LR1文法的完整实例代码
Oct 25 #Python
Python操作word文档插入图片和表格的实例演示
Oct 25 #Python
python时间time模块处理大全
Oct 25 #Python
使用AJAX和Django获取数据的方法实例
Oct 25 #Python
Python Tkinter实例——模拟掷骰子
Oct 24 #Python
You might like
jQuery Mobile + PHP实现文件上传
2014/12/12 PHP
PHP实现使用DOM将XML数据存入数组的方法示例
2017/09/27 PHP
Javascript 学习书 推荐
2009/06/13 Javascript
Javascript合并表格中具有相同内容单元格示例
2013/08/11 Javascript
js代码实现随机颜色的小方块
2015/07/30 Javascript
JS实现unicode和UTF-8之间的互相转换互转
2017/07/05 Javascript
微信小程序tabBar模板用法实例分析【附demo源码下载】
2017/11/28 Javascript
基于Vuex无法观察到值变化的解决方法
2018/03/01 Javascript
axios使用拦截器统一处理所有的http请求的方法
2018/11/02 Javascript
基于vue2的canvas时钟倒计时组件步骤解析
2018/11/05 Javascript
JavaScript变量提升和严格模式实例分析
2019/01/27 Javascript
vue子路由跳转实现tab选项卡
2019/07/24 Javascript
解决使用layui的时候form表单中的select等不能渲染的问题
2019/09/18 Javascript
layui动态渲染生成左侧3级菜单的方法(根据后台返回数据)
2019/09/23 Javascript
通过layer实现可输入的模态框的例子
2019/09/27 Javascript
react基本安装与测试示例
2020/04/27 Javascript
Vue中的this.$options.data()和this.$data用法说明
2020/07/26 Javascript
vue 通过绑定事件获取当前行的id操作
2020/07/27 Javascript
nuxt静态部署打包相对路径操作
2020/11/06 Javascript
[02:34]肉山说——泡妞篇
2014/09/16 DOTA
python实现通过代理服务器访问远程url的方法
2015/04/29 Python
python脚本爬取字体文件的实现方法
2017/04/29 Python
numpy中loadtxt 的用法详解
2018/08/03 Python
Django错误:TypeError at / 'bool' object is not callable解决
2019/08/16 Python
PyCharm+Pipenv虚拟环境开发和依赖管理的教程详解
2020/04/16 Python
python中selenium库的基本使用详解
2020/07/31 Python
python实现简单的井字棋游戏(gui界面)
2021/01/22 Python
HTML5打开本地app应用的方法
2016/03/31 HTML / CSS
乌克兰网上珠宝商店:GoldSoveren
2020/03/31 全球购物
介绍一下grep命令的使用
2015/06/12 面试题
实习老师个人总结的自我评价
2013/09/28 职场文书
大学生自荐书范文
2013/12/10 职场文书
食堂标语大全
2014/06/11 职场文书
承德避暑山庄导游词
2015/02/03 职场文书
2019邀请函格式及范文
2019/05/20 职场文书
服务器nginx权限被拒绝解决案例
2022/09/23 Servers