卷积神经网络之残差网络ResNet详解
程序员文章站
2022-06-24 10:18:24
卷积神经网络之残差网络ResNet详解理论上,在网络中添加新的层得到的新模型可能会更好地拟合训练数据集,因此添加层似乎更容易降低训练误差。然而在事件中,添加过多的层后训练误差反而会升高。针对这一问题,何凯明团队于2015年提出了残差网络(ResNet)在一定程度上解决了这一问题。残差块如下图所示,输入为x,理想映射为f(x)。左图需要直接拟合出该映射f(x),右图则需要拟合出残差映射f(x)-x。残差映射在实际中往往更容易优化。右图是ResNet的基础块(残差块Residual bloc...
卷积神经网络之残差网络ResNet详解
理论上,在网络中添加新的层得到的新模型可能会更好地拟合训练数据集,因此添加层似乎更容易降低训练误差。然而在事件中,添加过多的层后训练误差反而会升高。针对这一问题,何凯明团队于2015年提出了残差网络(ResNet)在一定程度上解决了这一问题。
残差块
如下图所示,输入为x,理想映射为f(x)。
左图需要直接拟合出该映射f(x),右图则需要拟合出残差映射f(x)-x。残差映射在实际中往往更容易优化。
右图是ResNet的基础块(残差块Residual block)。残差块中,输入可通过跨层的数据线路更快向前传播。
残差块的组成:
两个有相同输出通道的卷积层,将输入跳过这两个卷积运算后直接加在最后的Relu前。
现在我们会得到一个H(x)=f(x)+x,我们需要f(x)=H(x)-x,
通过训练参数,得到H(x)-x,即残差,这样要比学习H(x)简单得多。
瓶颈(BottleNeck)模块
瓶颈是指block的输入和输出的通道数一样,再block中间的通道数是小于输入或输出,即采用先降维再升维。
比如右图的带瓶颈模块共使用参数个数:1*1*256*64+3*3*64*64+1*1*64*256=69632
未使用瓶颈共需要参数:3*3*256*256*2=1179648
很明显数据量减少了很多。
代码
import d2lzh as d2l
from mxnet import gluon, init, nd
from mxnet.gluon import nn
class Residual(nn.Block): # 本类已保存在d2lzh包中方便以后使用
def __init__(self, num_channels, use_1x1conv=False, strides=1, **kwargs):
super(Residual, self).__init__(**kwargs)
self.conv1 = nn.Conv2D(num_channels, kernel_size=3, padding=1,
strides=strides)
self.conv2 = nn.Conv2D(num_channels, kernel_size=3, padding=1)
if use_1x1conv:
self.conv3 = nn.Conv2D(num_channels, kernel_size=1,
strides=strides)
else:
self.conv3 = None
self.bn1 = nn.BatchNorm()
self.bn2 = nn.BatchNorm()
def forward(self, X):
Y = nd.relu(self.bn1(self.conv1(X)))
Y = self.bn2(self.conv2(Y))
if self.conv3:
X = self.conv3(X)
return nd.relu(Y + X)
残差网络的背后原理
详见:详解残差网络
参考资料:<<动手学深度学习>>
其他经典网络结构:
卷积神经网络之 LeNet卷积神经网络之(稠密连接网络)DenseNet
本文地址:https://blog.csdn.net/qq_36766560/article/details/110672378