赞
踩
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、反向传播解决梯度消失问题
之所以可以避免梯度消失问题,是因为反向传播时,ε 代表的是 loss 方程,由链式求导法得:
可以看出,反向传播的梯度由2项组成的:
即使新增的多层神经网络的梯度为0,那么输出结果也不会比传播前的x更差。同时也避免了梯度消失问题。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。