nn的相关

一、nn.Sequential

torch.nn.Sequential是一个Sequential容器,模块将按照构造函数中传递的顺序添加到模块中。通俗的话说,就是根据自己的需求,把不同的函数组合成一个(小的)模块使用或者把组合的模块添加到自己的网络中。主要使用方法:

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv_module = nn.Sequential(
          nn.Conv2d(1,20,5),
          nn.ReLU(),
          nn.Conv2d(20,64,5),
          nn.ReLU()
        )
    def forward(self, input):
        out = self.conv_module(input)
        return out

二、nn.Linear

这个的理解需要线性代数的矩阵乘法作为基础。
nn.Linear定义一个神经网络的线性层,方法签名如下:

torch.nn.Linear(in_features, # 输入的神经元个数
           out_features, # 输出神经元个数
           bias=True # 是否包含偏置
           )

可以实际试一下:

model = nn.Linear(3, 2) # 3个输入,2个输出
#i=3,o=2
#Y=X(d*i)W(i*o)+b
#即Y=X(d*3)W(3*2)+b
#算出来,Y就是有d行,有2列 ,即 Y(d*2)
#    …           **                  …
#    ***         **                 **
#    …           **                  …

i:输入神经元个数,也就是输入特征的个数,如:in_feature=93
o:输出神经元个数,我们想让下一层的神经元个数为1,如:out_feature=1
d:输入向量的行数,也就是样本个数,如:batch_size为2700
b:一个o维的向量
如定义X:

x = [
    [1,2,3], 0.5903
    [2,1,3],
    [5,7,4],
    [3,6,4],
    [1,3,9],
]
y= model(torch.Tensor(x))
print(y)

打印出的Y的形状就是 :
**
**
**
**
**
此时,可以查看模型参数验证一下上述的式子(就是看一下w和b):

for param in model.parameters():
    print(param)

输出的参数:(前面的那个转置一下才是w,后面的就是b):

Parameter containing:
tensor([[-0.5347, -0.0278, -0.0505],
        [ 0.1761, -0.2649, -0.5702]], requires_grad=True)
Parameter containing:
tensor([0.5003, 0.1981], requires_grad=True)

三、nn.MSELoss

MSE是mean squared error的缩写,即平均平方误差,简称均方误差。

MSE是逐元素计算的,计算公式为:



reduction的意思是维度要不要缩减,以及怎么缩减,有三个选项:
"none":不应用缩减
"mean":输出的总和将除以输出中的元素数
"sum" : 将对输出进行求和。(默认值)
如果不设置reduction参数,默认是'mean'。
程序示例:

import torch
import torch.nn as nn

a = torch.tensor([[1, 2], [3, 4]], dtype=torch.float)
b = torch.tensor([[3, 5], [8, 6]], dtype=torch.float)

loss_fn1 = torch.nn.MSELoss(reduction='none')
loss1 = loss_fn1(a.float(), b.float())
print(loss1)   # 输出结果:tensor([[ 4.,  9.],
               #                 [25.,  4.]])

loss_fn2 = torch.nn.MSELoss(reduction='sum')
loss2 = loss_fn2(a.float(), b.float())
print(loss2)   # 输出结果:tensor(42.)


loss_fn3 = torch.nn.MSELoss(reduction='mean')
loss3 = loss_fn3(a.float(), b.float())
print(loss3)   # 输出结果:tensor(10.5000)

四、nn.utils.clip_grad_norm_()

pytorch中梯度剪裁方法为 torch.nn.utils.clip_grad_norm_(parameters, max_norm, norm_type=2)
这个函数的主要目的是对parameters里的所有参数的梯度进行规范化
梯度裁剪解决的是梯度消失或爆炸的问题,即设定阈值,如果梯度超过阈值,那么就截断,将梯度变为阈值。

三个参数:
parameters:希望实施梯度裁剪的可迭代网络参数
max_norm:该组网络参数梯度的范数上限
norm_type:范数类型
设parameters里所有参数的梯度的范数为total_norm,
若max_norm>total_norm,parameters里面的参数的梯度不做改变;
若max_norm

每一次迭代中,梯度处理的过程应该是:
计算梯度 → 裁剪梯度 → 更新网络参数
因此 torch.nn.utils.clip_grad_norm_() 的使用应该在loss.backward() 之后,optimizer.step()之前。

五、with torch.no_grad():

就是一个节省空间,节省内存,节省不必要计算的方法
在pytorch中,tensor有一个requires_grad参数,如果设置为True,则反向传播时,该tensor就会自动求导。tensor的requires_grad的属性默认为False,若一个节点(叶子变量:自己创建的tensor)requires_grad被设置为True,那么所有依赖它的节点requires_grad都为True(即使其他相依赖的tensor的requires_grad = False)

当requires_grad设置为False时,反向传播时就不会自动求导了,因此大大节约了显存或者说内存。
with torch.no_grad的作用
在该模块下,所有计算得出的tensor的requires_grad都自动设置为False。

  • requires_grad=True 要求计算梯度

  • requires_grad=False 不要求计算梯度

  • with torch.no_grad()或者@torch.no_grad()中的数据不需要计算梯度,也不会进行反向传播

六、nn.Conv2d()

nn. Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=1)

这个函数是二维卷积最常用的卷积方式,在pytorch的nn模块中,封装了nn.Conv2d()类作为二维卷积的实现。使用方法和普通的类一样,先实例化再使用。

参数解释

in_channels:输入的四维张量[N, C, H, W]中的C,也就是说输入张量的channels数。这个形参是确定权重等可学习参数的shape所必需的。

out_channels:也很好理解,即期望的四维输出张量的channels数,不再多说。

kernel_size:卷积核的大小,一般我们会使用5x5、3x3这种左右两个数相同的卷积核,因此这种情况只需要写kernel_size = 5这样的就行了。如果左右两个数不同,比如3x5的卷积核,那么写作kernel_size = (3, 5),注意需要写一个tuple,而不能写一个列表(list)。

stride = 1:卷积核在图像窗口上每次平移的间隔,即所谓的步长。这个概念和Tensorflow等其他框架没什么区别,不再多言。

padding:指图像填充,后面的int型常数代表填充的多少(行数、列数),默认为0。需要注意的是这里的填充包括图像的上下左右,以padding=1为例,若原始图像大小为32×32,那么padding后的图像大小就变成了34×34,而不是33×33。

七、nn.BatchNorm2d()

作用:卷积层之后总会添加BatchNorm2d进行数据的归一化处理,这使得数据在进行Relu之前不会因为数据过大而导致网络性能的不稳定

torch.nn.BatchNorm2d(num_features, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)

你可能感兴趣的:(nn的相关)