• 【残差网络 论文泛读】……DenseNet……(Densely Connected Convolutional Networks)


    ResNet回顾:

    ResNet主要是解决网络退化现象而提出的模块。

    结构图:
    在这里插入图片描述

    可以看到x输入之后有两条路可以走,右边一条路还有中间一条路 。右边的路 identity 称为恒等映射(shortcut connection & skip connection ),恒等映射 不引入额外的参数量和计算量,所以此时总的输出映射为 F ( x ) + x .

    设最终得到的映射为 H ( s ) ,则 F ( x ) = H ( x ) − x ,即学习的是 应有的映射与原始输入之间的差值。因此被称为残差映射(residual mapping)。

    这块顺带说一下,我在查资料的时候看到很多博主都将网络退化直接说成梯度消失,这样明显是不对的,在ResNet原论文中作者明确说明网络退化现象不是梯度消失或者爆炸或者过拟合引起的,网络退化更不等于梯度消失,ResNet的作者是为了解决网络退化现象而提出的模型,只是附带着在一定程度上解决了梯度消失。

    论文提出的背景:

    ResNet虽然解决了网络退化现象,也附带了诸多优点,比如一定程度解决梯度消失问题,加速模型收敛,提升准确率等,但也有一定的缺点,比如参数量大,

    而且我在读的时候发现,这篇论文开头并没有明确指出前人或者ResNet的重大缺点,作者只是简单的说了一下,梯度消失问题,参数量问题等等,更多是对比了之前模型显现出Dense的优点,不像ZFnet那样指出黑箱问题,RCNN系列那样特别重点的强调前人的不足。就感觉好像Dense的作者突然灵光一现,觉得自己可以优化Resnet,然后就开始了。

    作者的改进方法

    改进一: Dense Block

    为了进一步改善层之间的信息流,提出了不同的连接模式。

    传统的连接方式:

    在这里插入图片描述

    ResNet连接方式:

    在这里插入图片描述

    DenseNet连接方式:

    这张图就是 Dense Block。
    在这里插入图片描述

    这三张图非常清晰的对比了Res和Dense的连接方式,传统就是一路到底,而ResNet的输出还要add之前某层的输出,DenseNet的输出还要concat/concatenation上之前所有层的输出。

    并且DenseNet是直接Concat来自不同层的特征图,这可以实现特征重用,提高效率,这一特点是DenseNet和ResNet最主要的区别。

    这里要注意此处用的add和concat/concatenation。这俩一个是add可以理解成相加,而concat可以理解成连接。
    使用公式表示这三者的区别:

    传统层的输出:
    在这里插入图片描述

    对于ResNet,理解成 传统的+上一层的输出:

    在这里插入图片描述

    对于DenseNet,可以看到并没有像Res那样直接相加,而是像并列一样连接起来了:
    在这里插入图片描述

    上面公式中的H代表非线性转换函数,可能包含很多个操作,比如BN Relu 卷积池化等等。本文中采用 BN+ReLU+3x3 Conv的组合。

    这里也有一个点顺带提一下,通常模型是 卷积在前 ,BN和Relu在后(也称作post-activation),而这个模型是 BN和Relu在前,卷积在后(称作pre-activation)。作者后续实验证明 post-activation性能不好。

    改进二:bottleneck

    因为Densenet中要进行并联操作,所以所有DenseBlock中各个层卷积之后均输出k个特征图,这样输出相同的shape才能保证后续的并联操作。所以导致当网络变深之后,K将堆叠的越来越大。为了解决这个问题,作者在DenseBlock内部提出采用bottleneck层来减少计算量。bottleneck层:BN+ReLU+1x1 Conv+BN+ReLU+3x3 Conv,称为DenseNet-B结构。

    其中k在DenseNet称为growth rate,这是一个超参数。一般情况下使用较小的k(比如12),就可以得到较佳的性能。假定输入层的特征图的channel数为k ,那么 i i i 层输入的channel数为 k 0 + k ( i − 1 ) k_0 +k(i -1) k0+k(i1)

    bottleneck结构图:

    在这里插入图片描述

    改进三:Translation

    作者为了进一步压缩模型,在Dense block之间加入Translation 层。
    其结构为BN+ReLU+1x1 Conv+2x2 AvgPooling。

    假设 Dense block 输出K个特征,则经过Translation输出特征为xk,其中x为压缩系数。x=1 显然是无压缩,若x<1 则是有压缩,将x<1的模型称做 DenseNet-C。

    若既有bottleneck层,又有x<1的Translation层(文中使用x = 0.5),则此时模型结构称为DenseNet-BC。

    DenseNet总体结构:
    在这里插入图片描述

    连续的跨层 Concat 操作仅存在于每个 Dense Block 之内。

    每个 Dense Block 之内有bottleneck块。

    小总结:

    1.ResNet所用方法为add,DenseNet所用方法为concat。
    2. 由于DenseNet的concat方式,建立了不同层之间的连接关系,充分利用了feature,进一步减轻了梯度消失问题,并且具有更好的特征重用,进而减少计算量,提高计算效率,有效抑制过拟合。
    3. concat方式也更好的保留了低维特征,这也是为什么Densenet在数据不足时也能表现较好的原因。
    4. 最佳性能为 DenseNet-BC (Dense Block+bottleneck+Translation )
    5. 文章的最后作者通过一系列实验表明,transition 层的特征对本阶段最后一层的贡献很小,及transition 中冗余特征很多,这也是DenseNet-BC即使经过压缩,性能依然强劲的原因。
    6. Densenet因为在一个块内的多次concat操作,数据需要多次复制,所以对显存压力较大,并且他是一个ResNet的特殊改版,因此并没有ResNet的应用范围广泛。

    Pytorch实现DenseNet:

    实现 bottleneck块:
    在这里插入图片描述

    实现DenseBlock块:

    在这里插入图片描述

    实现transition连接处:
    在这里插入图片描述

  • 相关阅读:
    UVM中uvm_config_db非直线的设置与获取
    AHR亚马逊账户健康评级多久更新,如何查看解决
    hadoop HDFS分布式计算概述,MapReduce概述,YARN概述
    shell变量
    python算法
    JS-DOM BOM(未完)
    JavaSE - 调用和重写Object类中的toString方法、equals方法以及理解Arrays类中的toString方法
    Android Lottie动画
    mysql8.0英文OCP考试第31-40题
    Jmeter常用参数化技巧总结
  • 原文地址:https://blog.csdn.net/qq_38737428/article/details/125500026