05 ResNet的简单理解

本文详细阐述了ResNet如何通过恒等快捷连接应对深度网络中梯度消失问题,以及其结构设计,包括残差块和两种快捷连接策略。还讨论了深度增加带来的挑战和可能的退化现象。
摘要由CSDN通过智能技术生成

通过引入所谓的“恒等快捷连接”(identity shortcut connections),ResNet能够建立比以往更深的网络结构而不会受到梯度消失问题的影响。

退化现象与对策

在介绍ResNet之前首先需要理解,为何我们需要这样一个结构。传统的DCNN在层数加深时会面临梯度消失的问题,即随着层数的增加,梯度在反向传播过程中逐渐减小,导致深层网络参数难以更新。ResNet通过引入快捷连接来缓解这个问题,这些连接可以让一些层直接传递较低层的特征到较高层,从而减轻梯度消失的影响。

ResNet网络架构

如果我们考虑ResNet的单个层作为一个操作F(x) + x,其中x是输入,这个层试图学习残差函数 F(x) = H(x) - x,H(x)是期望的映射。这里可以这么理解:在H(x)是输出值,将其看作真值,在原先值的基础上加上真值和假设值之间的差值即残差,模型的训练主要训练残差值,使的输入的x更加贴近H(x)。同时,在方向传播过程中由于添加了原始参数,继而使得梯度理论上不会消失。
在这里插入图片描述

按照这个思路,ResNet团队分别构建了带有“快捷连接(Shortcut Connection)”的ResNet构建块、以及降采样的ResNet构建块,区降采样构建块的主杆分支上增加了一个1×1的卷积操作。左图对应的是浅层网络,而右图对应的是深层网络。对于短路连接,当输入和输出维度一致时,可以直接将输入加到输出上。但是当维度不一致时(对应的是维度增加一倍),这就不能直接相加。有两种策略:(1)采用zero-padding增加维度,此时一般要先做一个downsamp,可以采用strde=2的pooling,这样不会增加参数;(2)采用新的映射(projection shortcut),一般采用1x1的卷积,这样会增加参数,也会增加计算量。短路连接除了直接使用恒等映射,当然都可以采用projection shortcut。

在这里插入图片描述
! [在这里插入图片描述] (https://i-blog.csdnimg.cn/blog_migrate/9934969b057e650eea79e87639352159.png)

需要注意的是当神经网络达到一定层数时,模型还是会存在退化的现象。
这里可能的原因有:

  1. 虽然残差结构可以缓解梯度消失问题,但当网络非常深时,模型变得更加复杂,它的参数空间也更加庞大和复杂,导致优化算法难以找到良好的最小值。
  2. 简单的残差块可能无法充分提取复杂的特征,导致模型在面对复杂任务时表现不佳。
  3. 过深的网络更容易过拟合训练数据,导致模型在测试集上的泛化能力下降。
  4. 虽然残差连接可以部分解决梯度消失问题,但随着网络层数的增加,信号在经过多个残差块后仍然会发生衰减,导致信息丢失,影响模型的学习能力。

基于Tensorflow的代码块

import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, Add

def resnet_identity_block(input_tensor, kernel_size, filters, stage, block):
    filters1, filters2, filters3 = filters

    conv_name_base = 'res_stage' + str(stage) + '_block' + str(block) + '_branch'
    bn_name_base = 'bn_stage' + str(stage) + '_block' + str(block) + '_branch'

    x = Conv2D(filters1, (1, 1), name=conv_name_base + '2a')(input_tensor)
    x = BatchNormalization(name=bn_name_base + '2a')(x)
    x = Activation('relu')(x)

    x = Conv2D(filters2, kernel_size, padding='same', name=conv_name_base + '2b')(x)
    x = BatchNormalization(name=bn_name_base + '2b')(x)
    x = Activation('relu')(x)

    x = Conv2D(filters3, (1, 1), name=conv_name_base + '2c')(x)
    x = BatchNormalization(name=bn_name_base + '2c')(x)

    x = Add()([x, input_tensor])
    x = Activation('relu')(x)
    return x

# 示例用法:
input_tensor = Input(shape=(224, 224, 3))
x = resnet_identity_block(input_tensor, kernel_size=3, filters=[64, 64, 256], stage=2, block='a')
model = Model(inputs=input_tensor, outputs=x)
model.summary()
  • 13
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值