对于多层感知机而言,整个模型做的事情就是接收输入生成输出。但是并不是所有的多层神经网络都一样,所以为了实现复杂的神经网络就需要神经网络块,块可以描述单个层、由多个层组成的组件或整个模型本身。使用块进行抽象的一个好处是可以将一些块组合成更大的组件。
从编程的角度来看,块由类(class)表示。它的任何子类都必须定义一个将其输入转换为输出的正向传播函数,并且必须存储任何必需的参数。注意,有些块不需要任何参数。最后,为了计算梯度,块必须具有反向传播函数。幸运的是,在定义我们自己的块时,由于autograd 中引入)提供了一些后端实现,我们只需要考虑正向传播函数和必需的参数。
这一部分我们就要自定义自己的层和块。
先用实现一个简单的多层感知机:
1
2
3
4
5
6
7
8
|
import torch from torch import nn from torch.nn import functional as F net = nn.Sequential(nn.Linear( 20 , 256 ), nn.ReLU(), nn.Linear( 256 , 10 )) X = torch.rand( 2 , 20 ) net(X) |
这个多层感知机包含一个具有256个单元和ReLU激活函数的全连接的隐藏层,然后是一个具有10个隐藏单元且不带激活函数的全连接的输出层。
通过实例化nn.Sequential来构建我们的模型,层的执行顺序就是传入参数的顺序。
- nn.Sequential定义了一种特殊的Module,即在PyTorch中表示一个块的类。它维护了一个由Module组成的有序列表(Linear类是Module的子类)。
- 正向传播(forward)函数:将列表中的每个块连接在一起,将每个块的输出作为下一个块的输入。
- 通过net(X)调用我们的模型来获得模型的输出。是net.__call__(X)的简写。(这一句先不管他有什么,继续往下看。)
我们也可以自己手写一个多层感知机:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class MLP(nn.Module): def __init__( self ): # 调用`MLP`的父类的构造函数来执行必要的初始化。 # 这样,在类实例化时也可以指定其他函数参数,例如模型参数`params`(稍后将介绍) super ().__init__() self .hidden = nn.Linear( 20 , 256 ) # 隐藏层 self .out = nn.Linear( 256 , 10 ) # 输出层 # 定义模型的正向传播,即如何根据输入`X`返回所需的模型输出 def forward( self , X): # 注意,这里我们使用ReLU的函数版本,其在nn.functional模块中定义。 return self .out(F.relu( self .hidden(X))) net = MLP() net(X) |
通过super().__init__()调用父类的__init__函数,省去了重复编写适用于大多数块的模版代码的痛苦。
实例化两个全连接层,分别为self.hidden和self.out。
除非我们实现一个新的运算符,否则我们不用担心反向传播函数或参数初始化,系统将自动生成这些。
前边说调用net() 就相当于调用net.__call__(X),因为我们在自己的MLP中写了forward,但是我们没有调用,只使用net() 他就自动执行forward了。就是因为会自动调用.__call__函数使forward执行。
说完后两条说第一条:
有序是怎么实现的,构建构一个简化的MySequential:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
class MySequential(nn.Module): def __init__( self , * args): super ().__init__() for block in args: # 这里,`block`是`Module`子类的一个实例。我们把它保存在'Module'类的成员变量 # `_modules` 中。`block`的类型是OrderedDict。 self ._modules[block] = block def forward( self , X): # OrderedDict保证了按照成员添加的顺序遍历它们 for block in self ._modules.values(): X = block(X) return X |
MySequential类提供了与默认Sequential类相同的功能。
1
2
|
net = MySequential(nn.Linear( 20 , 256 ), nn.ReLU(), nn.Linear( 256 , 10 )) net(X) |
用MySequential类实现的多层感知机和Sequential类实现的一样。
注意这里只是写出了其执行顺序,是简化版的Sequential类!
到此这篇关于人工智能学习PyTorch教程之层和块的文章就介绍到这了,更多相关PyTorch 层和块内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://blog.51cto.com/Lolitann/4682377