Pytorch学习笔记-第四章

本文是PyTorch学习笔记的第四章,深入探讨nn模块,包括注意事项、全连接层、多层子模块、卷积层、池化层、BN层、dropout、激活函数、序列化网络、RNN、embedding层、损失函数、优化器、nn.functional、初始化策略、深入理解nn.Module,以及模型保存、GPU运行和nn与autograd的关系。


记录一下个人学习和使用Pytorch中的一些问题。强烈推荐 《深度学习框架PyTorch:入门与实战》.写的非常好而且作者也十分用心,大家都可以看一看,本文记录按照该书学习Pytorch时在第四章nn模块遇到的一些问题。

第四章nn

仅使用autograd也可实现深度学习模型,但其抽象程度较低,如果用其来实现深度学习模型,则需要编写的代码量极大。orch.nn应运而生,其是专门为深度学习而设计的模块。torch.nn的核心数据结构是Module,它是一个抽象概念,既可以表示神经网络中的某个层(layer),也可以表示一个包含很多层的神经网络。

注意事项

  1. 自定义layer对输入形状都有假设:输入的不是单个数据,而是一个batch。输入只有一个数据,则必须调用tensor.unsqueeze(0) 或 tensor[None]将数据伪装成batch_size=1的batch

全连接层


class Linear(nn.Module): # 继承nn.Module
    def __init__(self, in_features, out_features):
        super(Linear, self).__init__() # 等价于nn.Module.__init__(self)
        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) # x.@(self.w)
        return x + self.b.expand_as(x)
  1. 自定义层Linear必须继承nn.Module,并且在其构造函数中需调用nn.Module的构造函数,即super(Linear, self).init() 或nn.Module.init(self),推荐使用第一种用法,尽管第二种写法更直观。
  2. 在构造函数__init__中必须自己定义可学习的参数,并封装成Parameter,如在本例中我们把w和b封装成parameter。parameter是一种特殊的Tensor,但其默认需要求导(requires_grad = True),感兴趣的读者可以通过nn.Parameter??,查看Parameter类的源代码。
  3. forward函数实现前向传播过程,其输入可以是一个或多个tensor。
  4. 无需写反向传播函数,nn.Module能够利用autograd自动实现反向传播,这点比Function简单许多。
  5. 使用时,直观上可将layer看成数学概念中的函数,调用layer(input)即可得到input对应的结果。它等价于layers.call(input),在__call__函数中,主要调用的是 layer.forward(x),另外还对钩子做了一些处理。所以在实际使用中应尽量使用layer(x)而不是使用layer.forward(x),关于钩子技术将在下文讲解。
  6. Module中的可学习参数可以通过named_parameters()或者parameters()返回迭代器,前者会给每个parameter都附上名字,使其更具有辨识度。

多层子module

class Perceptron(nn.Module):
    def __init__(self, in_features, hidden_features, out_features):
        nn.Module.__init__(self)
        self.layer1 = Linear(in_features, hidden_features) # 此处的Linear是前面自定义的全连接层
        self.layer2 = Linear(hidden_features, out_features)
    def forward(self,x):
        x = self.layer1(x)
        x = t.sigmoid(x)
        return self.layer2(x)
  1. 构造函数__init__中,可利用前面自定义的Linear层(module),作为当前module对象的一个子module,它的可学习参数,也会成为当前module的可学习参数。
  2. 对于子Module中的parameter,会其名字之前加上当前Module的名字。如对于self.sub_module = SubModel(),SubModel中有个parameter的名字叫做param_name,那么二者拼接而成的parameter name 就是sub_module.param_name。

卷积层

# 输入是一个batch,batch_size=1
input = to_tensor(lena).unsqueeze(0) 

# 锐化卷积核
kernel = t.ones(3, 3)/-9.
kernel[1][1] = 1
conv = nn.Conv2d(1, 1, (3, 3), 1, bias=False)
#输入通道数,输出通道数,卷积核,步长
conv.weight.data = kernel.view(1, 1, 3, 3)

out = conv(input)

池化层

池化层可以看作是一种特殊的卷积层,用来下采样。但池化层没有可学习参数,其weight是固定的。

pool = nn.AvgPool2d(2,2)
list(pool.parameters())#输出为空[]

BN层

# 4 channel,初始化标准差为4,均值为0
bn 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值