PyTorch网络搭建教程与步骤详解
最近发现身边不少刚入门的朋友,捧着一本PyTorch教程,一边看一边敲代码,敲着敲着就成了打字员。整段代码跑完,输出结果跟书上一模一样,哦,没错,然后翻到下一章。半天工夫能打完一本书,可合上书脑子里空空如也。有的甚至看了两三遍,连个简单的网络都搭不出来——这种学法确实要不得。 如果你正好是这种情况,
最近发现身边不少刚入门的朋友,捧着一本PyTorch教程,一边看一边敲代码,敲着敲着就成了打字员。整段代码跑完,输出结果跟书上一模一样,哦,没错,然后翻到下一章。半天工夫能打完一本书,可合上书脑子里空空如也。有的甚至看了两三遍,连个简单的网络都搭不出来——这种学法确实要不得。
如果你正好是这种情况,这篇文章或许能帮到你。要是已经进阶了,直接关掉页面就好,不用浪费时间。

PyTorch的网络搭建,比TensorFlow简单得多,格式很容易理解。
想搭建一个网络,首先得定义一个Class,继承nn.Module(这是必须的,所以开头要import torch.nn as nn,nn就是个工具箱,很好用)。这个Class的名字可以随便起,比如就叫Net。
Class Net(nn.Module):
这个Class里主要写两个函数:一个是初始化的__init__,另一个是forward。随便搭一个例子:
def __init__(self):
super().__init__()
self.conv1=nn.Conv2d(1,6,5)
self.conv2=nn.Conv2d(6,16,5)
def forward(self, x):
x=F.max_pool2d(F.relu(self.conv1(x)),2)
x=F.max_pool2d(F.relu(self.conv2(x)),2)
return x
__init__里主要定义卷积层。当然,先得super()一下,给父类nn.Module做初始化(算是Python的基础知识)。在这里定义卷积层,比如第一层叫conv1,把它定义成输入1通道、输出6通道、卷积核5×5的卷积层;conv2同理。
神经网络“深度学习”实际上主要学习的就是卷积核里的参数。像激活函数relu()这种不需要学习的,不用非得放在__init__里——当然,你非放进去也成,给它起个名字叫myrelu也是可以的。
forward函数才是真正执行数据流动的地方。比如上面那段代码:输入的x先经过定义的conv1(名字是你自己起的),再经过激活函数F.relu()(这不是自己起的名字,最早要import torch.nn.functional as F,F.relu是官方提供的函数)。当然,如果你在__init__里把relu定义成了myrelu,那这里第一句就成了x=F.max_pool2d(myrelu(self.conv1(x)),2)。后面的池化也一样,不多啰嗦。经过一系列流动后,最后把x返回到外面。
定义Net这个Class时主要注意两点:
第一,前后输出通道和输入通道要保持一致。不能第一个卷积层输出4通道,第二个输入6通道,那样会直接报错。
第二,它和常规的Python Class还有些不同——发现了没有?该怎么使用这个Net呢?
先定义一个Net的实例(毕竟Net只是一个类,不能直接传参数——output=Net(input)肯定不行):
net=Net()
然后就可以往里传x了。假设你已经有输入数据input(得定义成tensor类型),传入时是:
output=net(input)
再看前面的定义:
def __init__(self):……
def forward(self, x):……
这里有点奇怪?常规Python里,向Class传入一个数据x,应该把这个x作为形参传入__init__函数;但上面的定义中,x是传入forward函数的。其实不矛盾:定义net的时候是net=Net(),并没有往里传参数。如果你想初始化时按需传入,就把需要的参数放进__init__。输入数据x并不是初始化需要的——初始化一个网络,不一定非要输入数据对吧?只是当你把input传给net时,PyTorch会自动认为这个input是喂给forward的。也就是说,output=net(input)可以理解为等同于output=net.forward(input),两者是一码事。
损失函数与优化
网络定义好之后,就涉及传入参数、算误差、反向传播、更新权重……这些东西的格式和顺序确实容易记混。
传入方式上面已经介绍了,相当于一次正向传播,一路算出了每层的输出。
想让神经网络的输出跟期望的ground truth接近,就要不断减小两者之间的差异。这个差异由你自己定义,也就是目标函数(或损失函数)。如果损失函数loss趋近于0,自然就达到目的了。当然,loss基本不可能到0,但希望它尽可能小,也就是按梯度下降。
梯度下降的公式大家应该熟悉,不熟悉的话建议看看相关理论。这里不讲公式(谁喜欢看公式呢?)。
输入由你决定,神经网络能学习和决定什么呢?它只能决定每一层卷积层的权重。所以神经网络只能不断修改权重——比如y=wx+b,x是你给的,它只能改变w和b,让最后的y尽可能接近你期望的值,这样loss就越来越小。
如果loss对于输入x的偏导数接近0,就说明到达了一个极值。而在loss计算方式给定的情况下,loss对输入x偏导数的减小,只能通过更新卷积层参数W来实现(别的它决定不了,都是你给的)。
所以,通过下面几步实现对W的更新:
- 先算
loss对于输入x的偏导(注意,网络有好几层,这里的x是每一层的输入,不是最开始的input)。 - 对第一步的结果乘以一个步长(得到对参数
W的修改量)。 - 用
W减掉这个修改量,完成一次对W的修改。
说得不太严谨,但大致意思如此。这个过程可以手动实现,但大规模神经网络怎么手动实现?不可能。所以要靠框架PyTorch和工具箱torch.nn。
先定义损失函数,以MSEloss为例:
compute_loss=nn.MSELoss()
这明显也是个类,不能直接传数据,所以loss=nn.MSEloss(target,output)不对。要把这个函数赋给一个实例,叫成compute_loss。然后就可以把神经网络的输出和标准答案target传入:
loss=compute_loss(target,output)
算出loss,下一步就是反向传播:
loss.backward()
这一步实际上就把【1】算完了,得到对参数W一步的更新量,算一次反向传播。
这里注意:loss.backward()是啥?如果是自定义的loss(比如def loss(x,y): return y-x),直接backward会出错。所以要用nn里提供的函数。当然,深度学习不可能只用官方提供的loss函数,如果想用自己的loss,必须也把loss定义成类似Net的样子(继承nn.Module,把传入的参数放进forward,具体的loss在forward里算,最后return loss。__init__空着,写个super().__init__就行)。不过现在最新版本已经支持自定义loss直接backward,基本不需要这么做了。
反向传播之后,【2】和【3】怎么实现?通过优化器——让优化器自动更新网络权重W。
所以在Net定义完后,需要写一个优化器的定义(以SGD为例):
from torch import optim
optimizer=optim.SGD(net.parameters(),lr=0.001,momentum=0.9)
同样,优化器也是一个类,先定义实例optimizer,后面用。注意定义时要传入net.parameters,这样优化器就掌握了网络参数的控制权,之后才能修改它们。学习率lr也一并传入。
训练循环
在每次迭代之前,先把优化器里存的梯度清零(因为W已经更新过,“更新量”下一次就不需要了):
optimizer.zero_grad()
loss.backward()
反向传播之后,更新参数:
optimizer.step()
所以整个顺序是:
- 先定义网络:写网络
Net的Class,声明实例net=Net()。 - 定义优化器:
optimizer=optim.xxx(net.parameters(),lr=xxx)。 - 定义损失函数(自己写Class或用官方的,
compute_loss=nn.MSELoss()等)。 - 之后开始一次一次循环:
- ①清空优化器里的梯度:
optimizer.zero_grad(); - ②输入
input,output=net(input),正向传播; - ③算损失:
loss=compute_loss(target,output)(target是参考标准值GT,需要自己准备,和input一一对应); - ④误差反向传播:
loss.backward(); - ⑤更新参数:
optimizer.step()。
这样就实现了一个基本的神经网络。大部分神经网络的训练都可以简化为这个过程,无非是传入的内容更复杂、网络定义更复杂、损失函数更复杂等等。
以上就是PyTorch网络搭建的基本套路。说得不对的地方欢迎指正。
你是一名 AI 行业编辑,请围绕下面这条热点输出一份资讯解读:
热点:PyTorch网络搭建教程与步骤详解要求:
1. 先用一句话解释这条热点在讲什么
2. 再总结它为什么重要
3. 说明会影响哪些 AI 产品或内容方向
4. 最后给出 3 个适合资讯站使用的标题
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
相关热点Dzine是一款强调构图控制与风格管理的AI图像设计工具,提供样式库、图层操作、定位和素描工具,支持文生图与图生图,具备生成填充编辑、一键修复增强及最高6144像素超高清导出功能,降低设计门槛,兼顾新手与专业用户。
3D虚拟空间的搭建,过去往往依赖专业建模软件和大量手动操作,技术门槛相当高。但现在,一款名为Arrival的云端SaaS解决方案正凭借AI与拖放功能,将这件事变得像搭积木一样轻松便捷。 什么是Arrival? Arrival本质上是一套专业的软件工具,核心目标就是帮助用户快速构建一个3D虚拟空间。它
ZENAI通过AI自动完成用户访谈,省去人工招募与主持流程,并自动总结用户场景、痛点及人物画像。产品经理、设计师、研究员可借此快速验证假设、提炼场景、获取市场洞察,加速产品市场契合度(PMF)达成,提供基础与专业两种套餐。
MeshcapadeMe基于SMPL人体模型技术,提供API接口支持图像、视频、测量及3D扫描输入,自动生成统一格式的逼真数字分身,无需专业建模技能即可将各类素材转化为可动画、跨平台使用的数字人类,适用于虚拟现实、游戏与影视等领域。
- 日榜
- 周榜
- 月榜
热点快看
