赞
踩
nn.Module是PyTorch提供的神经网络类,并在类中实现了网络各层的定义及前向计算与反向计算机制。在初始化中定义模型结构与参数,在函数forward()中编写网络前向过程即可。
nn.Parameter:
torch.nn.Parameter是继承自torch.Tensor的子类,其主要作用是作为nn.Module中的可训练参数使用。它与torch.Tensor的区别就是nn.Parameter会自动被认为是module的可训练参数,即加入到parameter()这个迭代器中去;而module中非nn.Parameter()的普通tensor是不在parameter中的。注意到,nn.Parameter的对象的requires_grad属性的默认值是True,即是可被训练的,这与torch.Tensor对象的默认值相反。在nn.Module类中,Pytorch也是使用nn.Parameter来对每一个module的参数进行初始化的。
perception.py:
import torch from torch import nn #首先建立一个全连接的子module,继承nn.Module class Linear(nn.Module): def __init__(self, in_dim, out_dim): #初始化实例的值,这些值一般要供其他方法调用 #首先找到Linear的父类(父类是类nn.Module); #然后把类Linear的对象self转换为类nn.Module的对象; #当需要继承父类构造函数中的内容,并且子类需要在父类的基础上补充时,使用super().__init__()方法 #这里的补充则是参数in_dim、out_dim super(Linear, self).__init__() #使用nn.Parameter来构造需要学习的参数 self.w = nn.Parameter(torch.randn(in_dim, out_dim)) #全连接层中的w 维度(in_dim,out_dim) self.b = nn.Parameter(torch.randn(out_dim)) #全连接层中的b 维度out_dim #在forward中实现向前传播过程 def forward(self, x): x = x.matmul(self.w) #使用Tensor.matmul实现矩阵相乘 y = x + self.b.expand_as(x) #使用Tensor.expand_as()来保证矩阵形状一致 return y #构建感知机类,继承nn.Module,并调用了Linear的子module class Perception(nn.Module): def __init__(self, in_dim, hid_dim, out_dim): super(Perception, self).__init__() self.layer1 = Linear(in_dim, hid_dim) #维度是(in_dim,hid_dim) (2,3) self.layer2 = Linear(hid_dim, out_dim) #维度是(hid_dim,out_dim) (3,2) def forward(self, x): x = self.layer1(x) y = torch.sigmoid(x) #使用torch中的sigmoid作为激活函数 y = self.layer2(y) y = torch.sigmoid(y) return y #in_dim=2、hid_dim=3、out_dim=2
终端:
>>> import torch >>> from perception import Perception #调用上述模块 >>> #实例化一个网络,并赋值全连接中的维数,最终输出二维代表了二分类 >>> perception = Perception(2,3,2) >>> #可以看到perception中包含上述定义的layer1与layer2 >>> perception Perception( (layer1): Linear() (layer2): Linear() ) >>> #named_parameters()可以返回学习参数的迭代器,分别为参数名与参数值 >>> for name,parameter in perception.named_parameters(): ... print(name,parameter) ... layer1.w Parameter containing: tensor([[ 1.4509, -0.6111, -0.5108], [-0.3818, -2.0542, 0.3184]], requires_grad=True) layer1.b Parameter containing: tensor([-1.5274, 0.1767, -0.5369], requires_grad=True) layer2.w Parameter containing: tensor([[ 0.1622, -0.3417], [ 0.7079, -1.1008], [-1.4995, 0.1793]], requires_grad=True) layer2.b Parameter containing: tensor([-0.2565, 0.8857], requires_grad=True) >>> #随机生成数据,注意这里的4代表了样本数为4,每个样本有两维 >>> data = torch.randn(4,2) >>> data tensor([[ 1.2537, 0.3754], [-0.6795, 1.6050], [-0.3249, 0.1087], [-2.7153, -0.6721]]) >>> #将输入数据传入perception,perception()相当于调用perception中的forward()函数 >>> output = perception(data) >>> output tensor([[0.3986, 0.6280], [0.2546, 0.7122], [0.3818, 0.5815], [0.3646, 0.4857]], grad_fn=<SigmoidBackward>)
forward()
forward()函数用来进行网络的前向传播,并需要传入相应的Tensor,例如在上面的代码中perception(data)即是直接调用了forward()。在具体底层实现中,perception.call(data)将类的实例perception变成了可调用对象perception(data),而在perception.call(data)中主要调用了forward()函数
nn.Module可以自动利用Autograd机制实现反向传播,不需要自己手动实现
多个Module嵌套
在Module的搭建时,可以嵌套包含子Moudle,上例的Perception中调用了Linear这个类。PyTorch也提供了绝大多数的网络层,如全连接、卷积网络中的卷积、池化等,并自动实现前向与反向传播
nn.Module与nn.functional库
在PyTorch中,还有一个库为nn.functional,同样也提供了很多网络层与函数功能,但与nn.Module不同的是,利用nn.functional定义的网络层不可自动学习参数,还需要使用nn.Parameter封装。nn.functional的设计初衷是对于一些不需要学习参数的层,如激活函数层、BN(Batch Normalization)层,可以使用nn.functional,这样这些层就不需要在nn.Module中定义了
nn.Sequential()模块
当模型中只是简单的前馈网络时,即上一层的输出直接作为下一层的输入,这是可以采用nn.Sequential()模块来快读搭建模型,而不必手动在forward()函数中一层一层地前向传播。因此,如果想快速搭建模型而不考虑中间过程的话,推荐使用nn.Sequential
在上面的例子中,Perception类中的layer1与layer2是直接传递的,因此该Perception类可以使用nn.Sequential()快速搭建
perception_sequential.py:
from torch import nn class Perception(nn.Module): def __init__(self, in_dim, hid_dim, out_dim): super(Perception, self).__init__() #利用nn.Squential()快速搭建网络模块 self.layer = nn.Sequential( nn.Linear(in_dim, hid_dim), nn.Sigmoid(), nn.Linear(hid_dim, out_dim), nn.Sigmoid() ) def forward(self, x): y = self.layer(x) return y
终端
>>> import torch >>> #从上述文件中引入Perception类 >>> from perception_sequential import Perception >>> model = Perception(100,1000,10) #构建类的实例,可以在尾部加上.cuda(),表明在CUDA上 >>> #打印model结构,会显示Sequential中每一层的具体参数配置 >>> model Perception( (layer): Sequential( (0): Linear(in_features=100, out_features=1000, bias=True) (1): Sigmoid() (2): Linear(in_features=1000, out_features=10, bias=True) (3): Sigmoid() ) ) >>> input = torch.randn(100) #可以在尾部加上.cuda(),表明在CUDA上 >>> output = model(input) #将输入传入实例化的模型 >>> output.shape torch.Size([10])
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。