深度学习中依赖Pytorch搭建的几个必不可少的模块:
- 数据
- 模型
- 损失函数
- 优化器
这里重点总结深度学习中CV模型的基础模块,如卷积层,池化层等…
1 卷积层
目前卷积分为:
- 1. 普通卷积:一般用来提取特征,下采样
- 2. 反置卷积:一般用来上采样
- 3. 空洞卷积:提高感受野
- 4. 分组卷积:用于模型加速技术——轻量化模型设计
- 5. DW卷积:在MobileNet中首次使用,用来降低计算量
- 6. 可变卷积:更准确地提取到我们想要的特征
1.1 普通卷积
1.1.1 原理
三个通道分别与权重矩阵做点成然后相加
1.1.2 Pytorch实现
导入
import torch.nn as nn
构造
def __init__( self, in_channels: int, out_channels: int, kernel_size: _size_2_t, stride: _size_2_t = 1, padding: _size_2_t = 0, dilation: _size_2_t = 1, groups: int = 1, bias: bool = True, padding_mode: str = 'zeros' # TODO: refine this type )
参数
- 1. in_channel:输入的深度
- 2. out_channels:输出的深度/卷积核的个数
- 3. kernel_size:卷积核的大小
- 4. stride:步长
- 5. padding:填充多少像素
- 6. dilation:使用空洞,默认为0,在空洞卷积中使用。
- 7. groups:分组,指的是对输入通道进行分组,如果groups=1,那么输入就一组,输出也为一组。如果groups=2,那么就将输入分为两组,那么相应的输出也是两组。另外需要注意的是in_channels和out_channels必须能整除groups。如果group=out_channels,即是DW卷积。
- 8. bias:bool,是否使用偏置
- 9. padding_mode:填充模式, padding_mode=‘zeros’表示的是0填充
1.2 可变卷积
卷积的位置是可变形的,并非在传统的N × N的网格上做卷积,这样的好处就是更准确地提取到我们想要的特征。
2 池化层
2.1 原理
这里接触最多的就是最大池化层
假设是2x2的池化,那么用2x2的过滤器遍历图像,每次取值最大的
2.2 函数
构造
class.torch.nn.MaxPool2d( kernel_size, stride=None, padding=0,dilation=1, return_indices=False, ceil_mode=False )
参数
- 1. kernel_size:过滤器大小,类似卷积核
- 2. stride:窗口的移动步长,默认kernel_size(起到下采样kernel_size倍的作用)
- 3. padding:输入的每一条边补充0的层数,主要用于边缘处填充。
- 4. dilation:核使用空洞,默认为0。在普通卷积核中不使用。
- 5. return_idices:如果等于True,会返回输出最大值对应的序号序列。
- 6. ceil_mode:如果等于True,计算输出数据大小的时候,会使用向上取整,代替默认的向下取整的操作
3 激活函数
激活函数种类很多,主要遇到的是ReLU和ReLU6,其它的遇到再总结
3.1 ReLU
3.1.1 原理
函数为f(x) = max{0, x}
ReLu梯度函数为:
可以看到,其当函数值为0时梯度小于0,即停止该参数的更新。当函数值为正数时,梯度为1不变,则不会出现梯度消失和爆炸的问题。
3.1.2 函数
构成
torch.nn.ReLU(inplace=True)
参数
- 1. inplace 默认为False,计算得到的值不会覆盖之前的值,如果设置为True,则会把计算得到的值直接覆盖到输入中,这样可以节省内存/显存。
- 举个例子,假设inplace为True,相当于执行x=x+1,直接将结果赋予原变量,实现覆盖如果为False,则会执行y=x+1,多使用一个变量储存结果。
3.2 ReLU6
3.2.1 原理
函数为f(x) = min{6, max{0, x}}
3.2.2 原理
构造
torch.nn.ReLU6(inplace=True) # 参数与上述一致
3.3 sigmod
3.3.1 原理
函数如下:
该函数梯度曲线是:
可以看到最大时才1/4,在反向传播过程中,会出现梯队消失的问题。因此,现在很少用sigmod作为激活函数。
3.3.2
构造:torch.sigmod(input, out=None)->Tensor
- 1. input:输入tensor
例子:
a = torch.rand(4) torch.sigmod(a)
4 Dropout
随机失活,用于防止过拟合
构造
torch.nn.Dropout(p=0.5, inplace=False) # p 元素归0的概率 # inplace 详细见激活函数
5 全连接层
目前接触到的好像线性全连接层(result=ax+by+c),用来对网络进行分类,其实基本已经被卷积代替。
5.1 原理
输入矩阵input_dimX1与权重矩阵output_dimXimput_dim相乘,得到output_dimX1。
5.1 构造
构造
torch.nn.Linear(in_features, out_features, bias=True, device=None, dtype=None)
参数
- 1. in_features:输入尺寸
- 2. out_features:输出尺寸
- 3. bias:是否使用偏置,默认为True
5.2 输入
Pytorch中shape=(batch_size, in_features)的张量,前面特征提取后一般是(batch_size,channel, height, width),因此需要经过一次展平操作,将维度变成(batch_size, channelheightwidth)。用到函数torch.flatten
torch.flatten(x, start_dim) # x 需要展开的数据 # start_dim 从哪一维度开始展开
5.3 输出
shape=(batch_size, out_features)
6 Batch Normalization(BN层)
6.1 使用的原因
- 1. **加快网络的训练和收敛的速度:**卷积层输出后由于特征图的变化,图像特征的分布就不一样,使得网络难以收敛。BN层将每层的数据都转换在均值为0,方差为1的状态,收敛更加容易。
- 2. **防止过拟合:**批量归一化是针对每个Batch的,因此归一化后batch中的图像不再只取决于自己,而是与同一个batch的所有图片都有关系,一定程度上缓解了过拟合。
- 3. 解决在训练过程中,中间层数据分布发生改变的问题,以防止梯度消失或爆炸。
6.2 原理
6.3 构造
torch.nn.BatchNorm2d(input_channels) # input_channels 输入的通道数
6.4 使用
一般位于卷积层和激活函数之间,为什么?
非线性单元的输出分布形状会在训练过程中变化,归一化无法消除他的方差偏移,相反的,全连接和卷积层的输出一般是一个对称,非稀疏的一个分布,更加类似高斯分布,对他们进行归一化会产生更加稳定的分布。
基本上其余所有结构都是这些结构的堆叠和变化!!!