详解resnet解决梯度消失问题

1、ResNet 起源

ResNet 的出发点是,在一个浅层的网络模型上进行改造,将新的模型与原来的浅层模型相比较,改造后的模型至少不应该比原来的模型表现要差,极端情况下,新加层的结果为 0,这样它就等同于原来的模型了。

 

2、瓶颈结构

对于每个残差函数 f,使用3个层叠层,分别为1×1、3×3和1×1卷积,其中1×1层负责减小/增加尺寸,3×3层为瓶颈层。

假设现在有一个由3个卷积层堆叠的卷积栈,将这个栈的输入/输出之间的原始映射称为 underlying mapping,ResNet 用 residual mapping 去替换underlying mapping。而将 underlying mapping 标记为 H(x) ,将经过堆叠的非线性层产生的residual mapping 标记为 F(x)=H(x)−x ,最原始的映射就被强制转换成 F(x)+x,这种恒等映射学习起来更容易。

 

3、瓶颈结构主要代码:

def bottleneck(inputs,
               depth,
               depth_bottleneck,
               stride,
               rate=1,
               outputs_collections=None,
               scope=None):
  with variable_scope.variable_scope(scope, 'bottleneck_v1', [inputs]) as sc:
    depth_in = utils.last_dimension(inputs.get_shape(), min_rank=4)
    if depth == depth_in:
      shortcut = resnet_utils.subsample(inputs, stride, 'shortcut')
    else:
      shortcut = layers.conv2d(
          inputs,
          depth, [1, 1],
          stride=stride,
          activation_fn=None,
          scope='shortcut')

    residual = layers.conv2d(
        inputs, depth_bottleneck, [1, 1], stride=1, scope='conv1')
    residual = resnet_utils.conv2d_same(
        residual, depth_bottleneck, 3, stride, rate=rate, scope='conv2')
    residual = layers.conv2d(
        residual, depth, [1, 1], stride=1, activation_fn=None, scope='conv3')

    output = nn_ops.relu(shortcut + residual)

    return utils.collect_named_outputs(outputs_collections, sc.name, output)

 

4、反向传播解决梯度消失问题

  • 输入是x;
  • F(x)相当于residual,它只是普通神经网络的正向传播;
  • 输出是这两部分的加和H(x) = F(x)(就是residual) + x(就是shortcut,此代码shortcut部分做了一次卷积,也可以不做);

之所以可以避免梯度消失问题,是因为反向传播时,ε 代表的是 loss 方程,由链式求导法得:

可以看出,反向传播的梯度由2项组成的:

  • 对x的直接映射,梯度为1;
  • 通过多层普通神经网络映射结果为:

即使新增的多层神经网络的梯度为0,那么输出结果也不会比传播前的x更差。同时也避免了梯度消失问题。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值