ResNet基础概念

1. 简介

  随着神经网络的进一步加深,可能会出现如下问题:

   (1)梯度消失、梯度爆炸

   (2)退化问题--训练集上准确率下降(不等于过拟合--表现为在训练集上表现更好

  ResNet2015ILSVRC 比赛2015第一名的算法。主要是针对更深的神经网络难以训练的问题,提出了一种残差学习的结构,不仅增加了网络的深度,而且减少了参数的数量,易于训练,取得了很好的效果。

2. 残差学习结构(residual learning

                                 ResNet基础概念

  在上图中,通过引入深度残差学习框架(上述也称为’shortcut connections’)解决了退化问题。(具体来说:假设模块的输入为x,卷积层参数为F(x),输出为H(x),那么经过上述模块:输出H(x)=F(x)+x。则,F(x)=H(x)-x,网络block F(x)可以看成是在学习实际输出和输入x之间的残差。

  因此:

    (1)解决退化问题:如果一个恒等映射是最优的,那么将残差置为零(即F(x)=0)比通过一堆非线性层来拟合恒等映射更容易。通过残差学习的重构,如果恒等映射是最优的,求解器可能简单地将多个非线性连接的权重推向零来接近恒等映射,大大减少了冗余卷积层的影响。

    (2)解决梯度消失问题:...

  具体到应用中,形成了以下两种结构:

                             ResNet基础概念

  如左图:输入是64通道,经过3×3的卷积核(64通道)--->relu线性激活--->3×3的卷积核(64--->加上64通道的输入--->relu。

  右图中多出来的1×1卷积核,主要是为了调整输入的通道与卷积后的结果同维度,便于相加操作(不同于GoogLeNet的拼接!)

 

3. ResNet 

                                              ResNet基础概念

 

 

 

  上图中最右边是一个34层的ResNet,实线是表示将输入直接加到卷积后的结果。虚线是表示通过不同通道数的1×1卷积核来调整输入的维度,便于与卷积后的结果相加操作。

在最后采用了平均池化,然后是1000维度的全连接层。

 

4. 代码参考(Keras定义一个卷积块)

   部分参考自网络,添加批规范化(Batch Normalnizations)处理

def identity_block(X, f, filters, stage, block):
    """
    ##参数说明
    ## X:输入
    ## f:整数,中间conv2D的维度
    ##filter:卷积核的维度
    ## block 用于命名网络中的层
    ##返回值: 维度为(n_H, n_W, n_C)
    """
    
    ##定义变量名
    conv_name_base = res + str(stage) + block + _branch
    bn_name_base = bn + str(stage) + block + _branch
    
    #过滤核
    F1, F2, F3 = filters
    
    #保存输入的值
    X_shortcut = X
    
    X = Conv2D(filters = F1, kernel_size = (1, 1), strides = (1,1), padding = valid, name = conv_name_base + 2a, kernel_initializer = glorot_uniform(seed=0))(X)
    X = BatchNormalization(axis = 3, name = bn_name_base + 2a)(X)
    X = Activation(relu)(X)
    
   #中间层卷积 X = Conv2D(filters = F2, kernel_size = (f, f), strides = (1,1), padding = same, name = conv_name_base + 2b, kernel_initializer = glorot_uniform(seed=0))(X) X = BatchNormalization(axis=3, name = bn_name_base + 2b)(X) X = Activation(relu)(X) X = Conv2D(filters = F3, kernel_size = (1, 1), strides = (1,1), padding = valid, name = conv_name_base + 2c, kernel_initializer = glorot_uniform(seed=0))(X) X = BatchNormalization(axis=3, name = bn_name_base + 2c)(X) #将输入与卷积后的结果相加 X = layers.add([X, X_shortcut]) X = Activation(relu)(X) return X

ResNet基础概念

上一篇:jQuery的选择器中的通配符总结


下一篇:使用BeetleX在Linux下部署.NET多站点服务