Identity Mappings in Deep Residual Networks2016【论文理解】
前言
此论文是对Deep residual networks [1]残差网络模块结构的改进和实验,提出了残差模块第二版,此新的模块形式不管是在前向传播或者是反向传播都有很好的优势,并且在网络训练上更加的容易,收敛更快,精度更高,泛化性更低!
原始的残差模块
如下图,为输入,为输出,有如下公式在下图所示的结构中 为残差函数,如下图红色方框中的部分,其中为**函数。
改进的残差模块
文中尝试创造一个直接的信息传递通道,推导表明,如果和都是恒等映射,那么信号可以直接从一个单元传播到任何其他单元,包括向前和向后传递。实验表明使用此结构能够使训练变得更加容易,如下图
绿色方框内的改进是经过了多种实验得到的结果,但最初的设想是为了构造一个的单位映射,我们将**函数(ReLU和BN)视为权重层的“预**”,而不是传统意义上的“后**”。此时的公式:
模块分析
对新的模块两公式结合可以得到对此公式进行循环递归从浅层模块到深层模块的公式如下:
此时可以发现有两个特别有意思的性质:(1)对于L个模块的特征都可以由浅层特征加上一系列的残差函数求得;(2)任何特征都可以从求得,不管是前向传播和反向传播,信息都能到达网络的最底层,对梯度而言,不管梯度是有多小。
对于loss假设为,则根据链式法则求得反向传播:
每一个部分的梯度都只有两个部分构成,说明梯度不管多小都可以回传到最前层。其中直接传播信息而不涉及任何权重层,经过之前的权重层传递信息。所以,直接保证了信息会之前传送到前层的每一层!!防止了梯度消失的问题!
结果图
不仅训练更加容易,而且精度更加高!
模块代码
keras
def BatchActivate(x):
x = BatchNormalization()(x)
x = Activation('relu')(x)
return x
def convolution_block(x, filters, size, strides=(1,1), padding='same', activation=True):
x = Conv2D(filters, size, strides=strides, padding=padding)(x)
if activation == True:
x = BatchActivate(x)
return x
def residual_block(blockInput, num_filters=16, batch_activate = False):
x = BatchActivate(blockInput)
x = convolution_block(x, num_filters, (3,3) )
x = convolution_block(x, num_filters, (3,3), activation=False)
x = Add()([x, blockInput])
if batch_activate:
x = BatchActivate(x)
return x
参考
[1]He, K., Zhang, X., Ren, S., Sun, J.: Deep residual learning for image recognition. In: CVPR. (2016)