一、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里的所有参数的梯度进行规范化
梯度裁剪解决的是梯度消失或爆炸的问题,即设定阈值,如果梯度超过阈值,那么就截断,将梯度变为阈值。
三个参数: 每一次迭代中,梯度处理的过程应该是: 就是一个节省空间,节省内存,节省不必要计算的方法 当requires_grad设置为False时,反向传播时就不会自动求导了,因此大大节约了显存或者说内存。 这个函数是二维卷积最常用的卷积方式,在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。 作用:卷积层之后总会添加BatchNorm2d进行数据的归一化处理,这使得数据在进行Relu之前不会因为数据过大而导致网络性能的不稳定
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)
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)
参数解释
七、nn.BatchNorm2d()
torch.nn.BatchNorm2d(num_features, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)