PyTorch Tips (三):nn.Module

本文是节选自陈云《深度学习框架PyTorch入门与实践》第四章,我有在自己电脑上亲自测试其代码

因为使用autograd可实现深度学习模型,但其抽象程度较低,如果用其来实现深度学习模型,则需要编写的代码量极大。在这种情况下,torch.nn应运而生,其是专门为深度学习设计的模块。torch.nn和核心数据结构是Module,它是一个抽象的概念,既可以表示神经网络中的某个层(layer),也可以表示一个包含很多层的神经网络。在实际使用中,最常见的做法是继承nn.Module,撰写自己的网络层。下面来先看看如何用nn.Module实现自己的全连接层。全连接层,又名仿射层,输出y和输入x满足y=Wx + b,W和b是可学习的参数。
先看代码:

import  torch as t
from  torch import nn
from torch.autograd import Variable as V

class Linear (nn.Module):
    def __init__(self,in_features,out_features):
        super(Linear,self).__init__()
        self.w = nn.Parameter(t.randn(in_features,out_features))
        self.b = nn.Parameter(t.randn(out_features))
        
    def forward(self,x):
        x = x.mm(self.w)
        return x + self.b.expand_as(x)
    
    
layer = Linear(4,3)
input = V(t.randn(2,4))
output = layer(input)
output


for name,Parameter in layer.named_parameters():
    print(name,Parameter) # w and b

输出如下:

output
Out[6]: 
tensor([[-1.7864,  2.4755, -1.8025],
        [-0.9060,  1.6661, -0.1183]], grad_fn=<AddBackward0>)
for name,Parameter in layer.named_parameters():
    print(name,Parameter) # w and b
w Parameter containing:
tensor([[-0.1576,  1.5763,  0.9441],
        [ 0.5559, -0.1769,  1.3767],
        [-0.7356,  1.7642, -0.4010],
        [ 0.3247, -0.7567,  0.4535]], requires_grad=True)
b Parameter containing:
tensor([-0.1011, -0.2682,  0.1915], requires_grad=True)

可见,全连接层的实现非常简单,其代码量不超过10行,但须注意以下几点:
a.自定义层Linear必须继承nn.Module,并且在其构造函数中需要用nn.Module的构造函数,即:
super(Linear,self). init()或nn.Module.init(self)。
b.在构造函数—init—中必须自己定义可学习的参数,并封装成Parameter,如在本例我们把w和b封装成parameter。parameter是一种特殊的Variable,但其默认需要求导(requires_grad = True),感兴趣的读者可以通过查询nn.parameter查看parameter类的源代码。
c.forward函数实现前向传播过程,其输入可以是一个或多个variable,对x的任何操作也必须是variable支持的操作。
d.无需写反向传播函数,因其前向传播都是对variable进行操作,nn.Module能够利用autograd自动实现反向传播,这一点比Function简单地多。
e.使用时,直观上可将layer看成数学概念中的函数,调用layer(input)即可得到input对应的结果。它等价于layers.–call–(input),在–call–函数中,主要调用的是layer.forward(x),另外还对钩子做了一些处理。所以在实际使用中应尽量使用layer(x)而不是使用layer.forward(x)。
f.Module中的可学习参数可以通过named_parameters()或者parameter()返回迭代器,前者会给每个parameter附上名字,使其更具有辨识度。

可见利用Module实现的全连接层,比利用Function实现的更简单,因其不再需要写反向传播函数。
Module能够自动检测到自己的parameter,并将其作为学习参数。除了parameter,Module还包含子Module,主Module能够递归查找子Module中的parameter。下面再来看看稍微复杂一点的网络:多层感知机。
多层感知机的网络结构如下图所示,它由两个全连接层组成,采用sigmoid函数作为激活函数()
在这里插入图片描述
为了方便用户使用,PyTorch实现了神经网络中绝大多数的layer,这些layer都继承于nn.Module,封装了可学习参数parameter,并实现了forward函数,且专门针对GPU运算进行了CuDNN优化,其速度和性能都十分优异。具体内容可参照文档,阅读文档时主要关注以下几点
1.构造函数的参数。
2.属性、可学习参数和子module。
3.输入输出的形状。

这些自定义layer对输入形状都有假设:输入的不是单个数据,而是一个batch。若想输入一个数据,必须调用unsqueeze(0)函数将数据伪装成batch_size = 1的batch。

如果想要更深入地理解nn.Module,研究其原理是很有必要的。首先来看看nn,Module基类的构造函数:

def __init__(self):
    self._parameters = OrderedDict()
    self._modules = OrderedDict
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值