2 神经网络工具箱nn

1.实际使用中,最常见的做法是继承nn.Module,撰写自己的网络层。下面将介绍如何使用nn.Module实现自己的全连接层。

全连接层,又称仿射层,输入y和x满足y=Wx+b,W,b是可学习参数。

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

class Linear(nn.Module):#继承nn.Module
    def __init__(self,in_features,outfeatures):
        super(Linear,self).__init__()#等价于nn.Module.__init__(self)
        self.w=nn.Parameter(t.randn(in_features,outfeatures))
        self.b=nn.Parameter(t.randn(outfeatures))
    def forward(self, x):
        x=x.mm(self.w)
        return x+self.b.expand_as(x)

    # expand_as (a)
    # 这是tensor变量的一个内置方法,如果使用b.expand_as (a)
    # 就是将b进行扩充,扩充到a的维度,需要说明的是a的低维度需要比b大,例如b的shape是3 * 1,如果a的shape是3 * 2
    # 不会出错,但是是2 * 2 就会报错了
layer=Linear(4,3)
input=V(t.randn(2,4))
output =layer(input)
print(output)

输出:

tensor([[-3.0932,  1.7944, -0.4888],
        [-1.8203,  1.4885, -0.2306]], grad_fn=<AddBackward0>)

可见,全连接层实现简单,但需要注意以下几点:

1)自定义层Linear必须继承nn.Module,并且在其构造函数中调用nn.Module的构造函数,即super(Linear,self)__init__(self)。

2)在构造函数__init__中必须自己定义可学习的参数,并封装成Parameter,如在本例中我们把w,b封装成Parameter。它是一种特殊的Variable,但其默认需要求导(required_grad=True)。

3)forward函数实现前向传播过程,其输入可以是一个或者多个variable,对x的任何一个操作也必须是variable支持的操作。

4)无须写反向传播函数,因其前向传播都是对variable进行操作,nn.Module能够利用autograd自动实现反向传播,这一点比Function简单许多。

 

2.Module能够自动检测到自己的parameter,并且作为学习参数。除了parameter,Module还包含子Module,主Module能够递归查找子Module中的parameter。

多层感知机,由两个全连接层组成,采用sigmoid函数作为激活函数。

class Perceptron(nn.Module):
    def __init__(self,in_features,hidden_features,out_features):
        nn.Module.__init__(self)
        #super (Perceptron, self).__init__ ()
        self.layer1=Linear(in_features,hidden_features)
        self.layer2 = Linear (hidden_features, out_features)
    def forward(self, x):
        x=self.layer1(x)
        x=t.sigmoid(x)
        return self.layer2(x)
perceptron =Perceptron(3,4,1)
for name,parameter in perceptron.named_parameters():
    print(name,parameter.size())#w,b

输出:

layer1.w torch.Size([3, 4])
layer1.b torch.Size([4])
layer2.w torch.Size([4, 1])
layer2.b torch.Size([1])

1)构造函数__init__中,可利用前面自定义的Linear层(Module)作为当前Module的对象的一个子Module,他的可学习参数,也会成为当前Module的可学习参数。

2)在前向传播函数中,我们有意识地将输出变量都命名成x,是为了能让Python回收一些中间层的输出,从而节省内存

3)Module中parameter的全局命名规范如下:

Parameter直接命名。例如self.param_name=nn.Parameter(t.randn(3,4)),命名为param_name。

子Module中的parameter,会在其名字之前加入当前Module的名字。例如:self.sub_module=SubModel(),SubModel中有一个parameter的名字也叫作param_name,那么两者拼起来的parameter name就是sub_module.param_name。

4)构造函数的参数,如nn.Linear(in_feature,out_feature,bias),需要关注这三个参数的作用。

属性、可学习参数和子Module。如nn.Linear中有weight和bias两个可学习参数,不包含子Module。

输入输出的形状,如nn.linear的输入形状是(N,input_features),输出为(N,output_features),N是batch_size。

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值