Pytorch——神经网络工具箱nn

一、神经网络工具箱nn

torch.nn是专门为深度学习设计的模块。torch.nn 的核心数据结构是Module, 他是一个抽象的概念,既可以表示神经网络的某个层(layer),也可以表示一个包含很多层的神经网络。
在实际使用中,最常见的做法是继承nn,Module,撰写自己及的网络/层

下面来看看如何使用nn.Module实现自己的全连接层。
全连接层,又名仿射层,输出 y 和输入 x 满足 y = W x + 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): #构造函数,需要调用nn.Mudule的构造函数
        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)   #mm(mat2) -> Tensor  =>矩阵乘法:x=x*w
        return x+self.b.expand_as(x)  #b.expand_as(a)就是将b进行扩充,扩充到a的维度


layer=Linear(4,3)  #定义并初始化模型参数
input=V(t.randn(2,4))
output=layer(input)  #前向传播 执行forward()
print(output)
for name,parameter in layer.named_parameters():
    print(name, parameter)

运行结果为:

tensor([[ 2.5089, -1.2151, -0.3574],
        [ 0.3139, -0.4002, -1.2473]])
w Parameter containing:
tensor([[-0.2625,  1.5595, -0.3886],
        [ 0.8469,  0.1103,  1.1023],
        [-1.3694, -0.9084,  0.2651],
        [ 0.4894, -0.4386,  0.7529]])
b Parameter containing:
tensor([ 2.0638, -0.2871, -0.0683])

注意:
1).自定义层Linear 必须继承nn.Module,并且在其构造函数中调用nn.Module 的构造函数,即
super(Linear,self).__init__() 或于nn.Module.__init__(self)
2)在构造函数__init__() 中必须自己定义可学习的参数,并封装成Parameter.
如在本例题中我们把 W b 封装成Parameter
Parameter是一种特殊的Variable, 但其默认需要求导(requires_grad=True).
可以通过nn.Parameter?? 查看Parameter类的源码。
3) forward() 函数实现前向传播过程,其输入可以是一个或多个Variable, 对x 的任何操作也必须是Variable 支持的操作。
4). 无需写反向传播函数,因为其前向传播都是对Variable 进行操作,nn.Module能够利用autograd自动实现反向传播。
5). 使用时,直观上可以将layer看成数学概念中的函数,调用layer(input)即可得到input 对应的结果。
他等价于layer.__call__(input).
6). Module中的可学习参数可以通过named_parameters()或者paramaters()返回迭代器,前者或给每个parameter附上名字,使其更具有辨识度。。

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


二、Pytorch模块下的数学操作符:

  1. torch.numel() 返回一个tensor变量内所有元素个数,可以理解为矩阵内元素的个数

  2. torch.squeeze() 对于tensor变量进行维度压缩,去除维数为1的的维度。例如一矩阵维度为A*1*B*C*1*D,通过squeeze()返回向量的维度为A*B*C*D。squeeze(a),表示将a的维数位1的维度删掉,squeeze(a,N)表示,如果第N维维数为1,则压缩去掉,否则a矩阵不变

  3. torch.unsqueeze() 是squeeze()的反向操作,增加一个维度,该维度维数为1,可以指定添加的维度。例如unsqueeze(a,1)表示在1这个维度进行添加

  4. torch.stack(sequence, dim=0, out=None),做tensor的拼接。sequence表示Tensor列表,dim表示拼接的维度,注意这个函数和concatenate是不同的,torch的concatenate函数是torch.cat,是在已有的维度上拼接,而stack是建立一个新的维度,然后再在该纬度上进行拼接。

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

三、多层感知机

由全连接层组成,层与层之间采用sigmoid函数作为激活函数。

# -*- coding: utf-8 -*-
"""
Created on Fri Jul  6 16:53:53 2018

@author: Duan
"""


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): #构造函数,需要调用nn.Mudule的构造函数
        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)   #mm(mat2) -> Tensor  =>矩阵乘法:x=x*w
        return x+self.b.expand_as(x)  #b.expand_as(a)就是将b进行扩充,扩充到a的维度

class Perceptron(nn.Module):
    def __init__(self, in_features, hidden_features, out_features): #构造函数,需要调用nn.Mudule的构造函数
        super(Perceptron,self).__init__()  #等价于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)  

perceptron=Perceptron(3,4,1)  #定义并初始化模型参数

for name,param in perceptron.named_parameters():
    print(name, param.size())

运行结果:

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

猜你喜欢

转载自blog.csdn.net/zhenaoxi1077/article/details/80938855
今日推荐