一、ResNet
1.梯度消失问题
深层网络有个梯度消失问题:模型变深时,其错误率反而会提升,该问题非过拟合引起,主要是因为梯度消失而导致参数难以学习和更新。
2. 网络创新
2015年何凯明等人提出deep residual network。在加入残存后,网络效果如下:
3. Residual结构
Residual结构是残差结构,在文章中给了两种不同的残差结构,
在ResNet-18和ResNet-34中,用的如下图中左侧图的结构,
在ResNet-50、ResNet-101和ResNet-152中,用的是下图中右侧图的结构。
上图左图可看到输入特征的channels是64,经过一个3x3的卷积核卷积之后,进行Relu激活,再经过一个3x3的卷积核进行卷积,但并没有直接激活。并且可以看到,在主分支上有一个圆弧的线从输入特征矩阵直接到加号,这个圆弧线是shortcut(捷径分支),它直接将输入特征矩阵加到经过第二次3x3的卷积核卷积之后的输出特征矩阵,再经过Relu激活函数进行激活。
上图右侧图输入特征的channels是256,要先经过一个1x1的卷积,降维到64,然后用3x3的卷积进行特征提取,并通过1x1的卷积进行升维到256,之后和shortcut的输入矩阵进行对应维度加法运算,在相加之后,再经过Relu激活。
如果遇到主分支的输出特征矩阵和shortcut的输出特征矩阵并不相同如何处理?
# [3, 4, 6, 3]
# BasicBlock 64 3
for _ in range(1, blocks):
layers.append(
block(
self.inplanes,
planes,
groups=self.groups,
base_width=self.base_width,
dilation=self.dilation,
norm_layer=norm_layer,
)
)
把上面两个框框放大如下:
上图右侧图主分支上步长=2,导致矩阵的宽和高都减半,同时由于卷积核的个数是128,channels从64升到了128,channels也不一样了,所以主分支的输出特征矩阵是[28,28,128],如果将shortcut分支上加一个卷积运算,卷积核个数为128,步长为2,那么经过shortcut分支的输出矩阵也同样为[28,28,128],那么两个输出矩阵又可以进行相加了。
4. 网络的结构
ResNet18,ResNet34,ResNet50,ResNet101,ResNet152
5. 性能
通过使用残差连接,使得更深的网络具有更低的错误率。
6. 变换策略影响
不同尺度的特征相加时,采用不同的维度变换策略。
三种变换策略:
(A):在升维时使用补零
(B):在升维时使用1x1卷积进行映射
©:所有残差连接使用1x1卷积进行映射
7. 代码实现
7.1 ResNet18代码实现
直接看源代码
7.2 ResNet50 代码实现
直接看源代码