目录
3. Batch Normalizaion批量规范化层--------批量归一化
BN层,就残差块;有自己的参数:具体在第二章中的具体做法
一.简述
1.作用: RseNet可以缓解深度神经网络中深度带来的“梯度消失、梯度爆炸”,还有一个退化问题
也就是深度神经网络中,叠加的层数越多,反而会导致结果的准确率变差;
而ResNet则使用了残差块解决了该问题
2. 同时使用Batch Normalization加速训练(丢弃dropout)-----------BN层
其中文是批标准化:主要目的是解决神经网络训练过程中数据分布的变化问题,即所谓的“内部协变量偏移”; 最终能够确保数据在经过神经网络的不同层厚仍然保持相对稳定的分布,从而提高训练的稳定性和效率
二. 残差块-residual block
1. 两种不同的残差块
图片有误,1x1卷积核是步幅为1,填充为0
2.原理和相加操作的细节
原理:数据不管处理成什么样,通过加上原始数据,视图保留未处理的信息,以达到不丢失信息的效果;同时就算保留了冗余的信息,也可以通过反向传播等手段进行剔除
残差块所得的最终输出大小要与最一开始的输入大小一致,这样才能保证最后的相加操作
最后的操作是相加,不是叠放,所以通道数不会发生变化,而是特征图内部的值发生变化
如果想改变通道数,就需要引入一个额外的1x1卷积层来将输入变换成需要的形状后再做相加运算
3. Batch Normalizaion批量规范化层--------批量归一化
本质:归一化就是让所有特征的影响权重更加平衡,防止某些特征影响过大
① 概述:
其目的就是将输出进行归一化处理;因为在原来的神经网络中都只对一开始的输入进行了归一化处理,而没有对每个模块的输出进行归一化(现在的优化方法都是小批量梯度下降,所以可以对输出进行归一化)
批量归一化(Batch Normalization,简称 BN)是一种在深度学习中广泛使用的技术,旨在加速神经网络的训练并改善模型的稳定性。它通过对每一层的输入进行标准化,使得每层的输入分布保持稳定,从而减少内部协变量偏移(Internal Covariate Shift)。
② 原理:
③ 具体做法:
第一步,求均值; 第二步,求方差; 第三步,归一化;
第四步,利用求得的归一化参数进行尺度变换和偏移
④ BN层--残差块总结
BN的目的就是使Feature map满足均值为0,方差为1的分布规律
⑤ 跳转连接
就是将输入经过残差块的结果与一开始的输入进行相加,残差块旁边的操作
三. ResNet网络参数详解
在残差块内的参数详解
四. 具体代码示例
1. 创建残差块
# ----------------------------创建残差块---------------------------------
class Residual(nn.Module): # 输入通道数 输出通道数 是否使用1x1卷积核 步幅(默认为1,此处定义是为了方便修改)---用到1x1卷积核的时候需要步幅为2
# -----这里是初始化各个层------
def __init__(self, input_channels, output_channels, use_conv=False, strides=1):
super(Residual, self).__init__()
self.ReLu = nn.ReLU() # 这里第二个卷积层通道数没有改变是故意的,卷积块中都这样
self.conv1 = nn.Conv2d(in_channels=input_channels, out_channels=output_channels, kernel_size=3, stride=strides)
self.conv2 = nn.Conv2d(in_channels=output_channels, out_channels=output_channels, kernel_size=3, stride=1)
# 创建残差块-------残差块不改变大小和通道数,需要的参数是需输入的通道数
self.bn1 = nn.BatchNorm2d(output_channels)
self.bn2 = nn.BatchNorm2d(output_channels)
# 如果使用1x1卷积块
if use_conv:
self.conv3 = nn.Conv3d(in_channels= input_channels, out_channels=output_channels, kernel_size=1, stride=strides)
else:
self.conv3 = None
# -----前向传播,卷积块整体流程-----
def forward(self, x):
y = self.ReLu(self.bn1(self.conv1(x))) # 残差块中第一个卷积层
y = self.bn2(self.conv2(y))
# 如果1x1卷积层存在
if self.conv3:
x = self.conv3(x) # 将输入进行卷积再返回
# 将正常的输出与跳转连接的输出相加,得到最终输出
y = self.ReLu(y+x)
return y
五. ResNet详解---------引用参考
残差网络(ResNet)
一、网络亮点:
超深的网络结构(突破1000层)
如果简单堆叠(不是层数越深效果越好):
a. 梯度消失:假设每一层的误差梯度是小于1的数,反向传播过程中每向前传播一层,都要乘以一个小于1的误差梯度。当网络越来越深时,所乘的小于1的系数就越多,梯度就越趋近于0。
b. 梯度爆炸:假设每一层的误差梯度是大于1的数,反向传播过程中每向前传播一层,都要乘以一个大于1的误差梯度。当网络越来越深时,梯度越来越大。
c. 解决梯度消失和梯度爆炸的方法:数据进行标准化处理,权重初始化,BN
d. 退化问题:层数深没有层数浅的网络效果好
解决方法:提出残差结构
① 提出residual模块
② 使用Batch Normalization加速训练(丢弃dropout)
二、残差结构:
1.左边针对与网络层数较少的的网络所使用的的残差结构(34),右边主要针对与网络层数较多的网络所使用的结构(50/101/152)。主分支与侧分支的输出矩阵特征shape必须相同(高宽通道数相同)。右边在输入和输出都加上了1X1的卷积层,降维再升维(256→64→256),保证shape相同的情况下减少参数。使用的残差结构越多,减少的参数就越多。
以34层为例(常用)
2.实线残差结构和虚线残差结构:
实线残差结构:输入输出shape相同,可以直接相加。
虚线残差结构:输入输出矩阵shape不同,输入:【56,56,64】
输出:【28,28,128】,只有将虚线残差结构的输出输入到实线残差结构,才能保证输入输出矩阵的shape相同。
不同之处:
① 第一个3X3卷积层步距变化:通过步距=2来使特征向量的高宽变为原来的一半,使用128个卷积核来改变特征矩阵的深度。
② 分支卷积层步距=2,128个卷积核保证shape相同
更深层处理方法相似
虚线残差结构使输入特征矩阵的高宽深度发生变化
→ 对于浅层网络(18 34):
conv3x,conv4x,conv5x的第一层均采用虚线残差结构
通过最大池化下采样得到的输出【56,56,64】,刚好是实线残差结构所需要的输入shape,此时conv2x第一层不需要使用虚线残差结构。
→对于深层网络(50/101/152):
通过最大池化下采样得到的输出【56,56,64】,而所需的shape为【56,56,256】,此时conv2x第一层需要使用虚线残差结构,但仅改变特征矩阵的深度,不改变高宽。
三、Batch Normalization
1. 目的:使我们的一批(Batch)数据所对应的数据的feature map(所对应的特征矩阵)每一个通道所对应的维度满足均值为0,方差为1的分布规律。
能够加速网络的收敛并提高准确率
2. 在图像预处理的过程通常会对图像进行标准化处理对于Conv1来说输入就是满足某一分布的特征矩阵,但对Conv2来说输入的feature map就不一定瞒足某一分布规律(整个训练样本集所对应的feature map的数据要满足分布规律)。BN的目的就是使Feature map满足均值为0,方差为1的分布规律。
γ,β是通过反向传播得到的学习率,初始值分别为1,0,使效果更好,ε防止分母为0。
例子:
将特征矩阵按通道生成向量,分别计算均值,方差(正向传播中得到)。根据标准差计算公式计算每个通道的值。
3. 使用BN时需要注意的问题:
(1)训练时要将training参数设置为True,在验证时将training参数设置为False.在Pytorch中可通过创建模型的model.train()和model.eval()方法控制。
(2)Batch size尽可能设置大一点,设置小后表现可能很糟糕,设置越大求的均值和方差越接近整个训练集的均值和方差。
(3)建议将bn层放在卷积层和激活层之间,且卷积层不要使用偏置,使用偏置后求出的结果也是一样的。
四、迁移学习
1. 优势:
① 能够快速的训练出一个理想的结果(减少训练时间)
② 当数据集较小时也能训练出理想的效果(使用别人之前预训练好的模型参数去训练比较小的数据集)
注:使用别人预训练模型参数时,要注意别人的预处理方式
2. 迁移学习简介
对于浅层卷积层所学习的一些角点信息/纹理信息等通用信息,在其他网络中仍然适用。所以将学习好的网络的浅层网络的一些参数迁移到新的网络当中。这样新的网络就也拥有了识别底层通用特征的能力。这样新的网络就能更快速的学习新的数据集的高维特征。
3. 常见的迁移学习方式
①载入权重后训练所有参数(最后一层无法载入)→第三种方法
②载入权重之后只训练最后几层参数
③载入权重后在原网络基础上再添加一层全连接层,仅训练最后一个全连接层。
②③更快速,①效果更好