在VGG中,卷积网络达到了19层,在GoogLeNet中,网络史无前例的达到了22层。那么,网络的精度会随着网络的层数增多而增多吗?在深度学习中,网络层数增多一般会伴着下面几个问题
- 计算资源的消耗
- 模型容易过拟合
- 梯度消失/梯度爆炸问题的产生
问题1可以通过GPU集群来解决,对于一个企业资源并不是很大的问题;问题2的过拟合通过采集海量数据,并配合Dropout正则化等方法也可以有效避免;问题3通过Batch Normalization也可以避免。貌似我们只要无脑的增加网络的层数,我们就能从此获益,但实验数据给了我们当头一棒。
作者发现,随着网络层数的增加,网络发生了退化(degradation)的现象:随着网络层数的增多,训练集loss逐渐下降,然后趋于饱和,当你再增加网络深度的话,训练集loss反而会增大。注意这并不是过拟合,因为在过拟合中训练loss是一直减小的。
当网络退化时,浅层网络能够达到比深层网络更好的训练效果,这时如果我们把低层的特征传到高层,那么效果应该至少不比浅层的网络效果差,或者说如果一个VGG-100网络在第98层使用的是和VGG-16第14层一模一样的特征,那么VGG-100的效果应该会和VGG-16的效果相同。所以,我们可以在VGG-100的98层和14层之间添加一条直接映射(Identity Mapping)来达到此效果。
从信息论的角度讲,由于DPI(数据处理不等式)的存在,在前向传输的过程中,随着层数的加深,Feature Map包含的图像信息会逐层减少,而ResNet的直接映射的加入,保证了l+1l+1l+1层的网络一定比 lll层包含更多的图像信息。
基于这种使用直接映射来连接网络不同层直接的思想,残差网络应运而生。
残差网络
残差块
残差网络是由一系列残差块组成的(图1)。一个残差块可以用表示为:
xl+1=xl+F(xl,Wl)(1)x_{l+1} = x_l + \mathcal{F}(x_l, W_l) \tag{1}xl+1=xl+F(xl,Wl)(1)
残差块分成两部分直接映射部分和残差部分。h(xl)h(x_l)h(xl) 是直接映射,反应在图1中是左边的曲线; $ \mathcal{F}(x_l, W_l)$是残差部分,一般由两个或者三个卷积操作构成,即图1中右侧包含卷积的部分。

图中的Weight在卷积网络中是指卷积操作,addition是指单位加操作。
在卷积网络中,xlx_lxl 可能和xl+1x_{l+1}xl+1 的Feature Map的数量不一样,这时候就需要使用 卷积进行升维或者降维(图2)。这时,残差块表示为:
xl+1=h(xl)+F(xl,Wl)(2)x_{l+1} = h(x_l) + \mathcal{F}(x_l, W_l) \tag{2}xl+1=h(xl)+F(xl,Wl)(2)
其中h(xl)=Wl′xh(x_l)=W^{'}_l xh(xl)=Wl′x 。其中 Wl′W^{'}_lWl′ 是 1×11 \times 11×1 卷积操作,但是实验结果1×11 \times 11×1 卷积对模型性能提升有限,所以一般是在升维或者降维时才会使用。

一般,这种版本的残差块叫做resnet_v1,keras代码实现如下:
def res_block_v1(x, input_filter, output_filter):
res_x = Conv2D(kernel_size=(3,3), filters=output_filter, strides=1, padding='same')(x)
res_x = BatchNormalization()(res_x)
res_x = Activation('relu')(res_x)
res_x = Conv2D(kernel_size=(3,3), filters=output_filter, strides=1, padding='same')(res_x)
res_x = BatchNormalization()(res_x)
if input_filter == output_filter:
identity = x
else: #需要升维或者降维
identity = Conv2D(kernel_size=(1,1), filters=output_filter, strides=1, padding='same')(x)
x = keras.layers.add([identity, res_x])
output = Activation('relu')(x)
return output
残差网络
残差网络的搭建分为两步:
- 使用VGG公式搭建Plain VGG网络
- 在Plain VGG的卷积网络之间插入Identity Mapping,注意需要升维或者降维的时候加入 1×11 \times 11×1 卷积。
在实现过程中,一般是直接stack残差块的方式。
def resnet_v1(x):
x = Conv2D(kernel_size=(3,3), filters=16, strides=1, padding='same', activation='relu')(x)
x = res_block_v1(x, 16, 16)
x = res_block_v1(x, 16, 32)
x = Flatten()(x)
outputs = Dense(10, activation='softmax', kernel_initializer='he_normal')(x)
return outputs
参考
https://zhuanlan.zhihu.com/p/42706477
本文探讨了深度学习网络中随着层数增加出现的退化现象,即训练集loss先下降后趋于饱和甚至上升。作者提出,通过引入Identity Mapping,可以缓解这一问题。残差网络由此诞生,其核心是残差块,确保信息能够有效地在深层网络中传递。通过在卷积层之间添加直接映射和残差部分,网络的性能得到提升,解决了深度学习中的梯度消失和过拟合等问题。
3159

被折叠的 条评论
为什么被折叠?



