精华内容
下载资源
问答
  • 第三章 基于密集连接卷积网络改进的目标分类算法 最近的研究表明,如果卷积网络包含接近输入的层和接近输出的层之间的较短连接,则卷积网络可以更深入,更精确和更有效地进行训练。在本章中,论文首先研究密集卷积...

    第三章 基于密集连接卷积网络改进的目标分类算法

    最近的研究表明,如果卷积网络包含接近输入的层和接近输出的层之间的较短连接,则卷积网络可以更深入,更精确和更有效地进行训练。在本章中,论文首先研究密集卷积网络(DenseNet)的结构和工作原理,随后本人提出一些改进意见,包括增加密集块中的层数、使用复合型综合函数、使用不同尺寸的卷积核和池化核、使用变化的增长率、压缩模型使其紧凑等方式对网络进行了改进。实验表明改进后的网络在物体分类任务上表现更好。DenseNet以前馈的方式将每层连接到每个其他层。传统的具有L层的卷积网络具有L个连接,每个层与其后一个层之间,DenseNet具有 个直接连接。对于每一层,前面所有图层的特征映射都被用作输入,并且它自己的特征映射被用作所有后续图层的输入。DenseNet有几个引人注目的优点:它们可以缓解消失梯度问题,加强特征传播,鼓励特征重用以及大幅减少参数数量。论文在识别基准任务(CIFAR-10,CIFAR-100,SVHN)的上验证了改进后网络的准确率。 DenseNet在其中大部分技术上都取得了显着的改进,同时需要较少的计算来实现高性能。

    3.1 DenseNet基本原理

    3.1.1 DenseNet结构

    近几年, 卷积神经网络(CNN)已经成为视觉对象识别的主要机器学习方法。虽然它们最初是在20多年前推出的,但计算机硬件和网络结构的改进使得最近才开始真正深入CNN。最初的LeNet5由5层组成,而VGG有19层,仅Highway网络和残差网络(ResNet)超过了100层网络结构。

    随着CNN网络结构的日益加深,出现了一个新的研究问题:随着有关输入或梯度的信息经过许多层,在到达网络的末端(或开始)时,它可能损耗或者消失。许多最近的论文解决了这个以及相关问题。ResNets和Highway Networks通过跳跃连接将来自一个层的信号传递给下一层。随机深度通过在训练期间随机丢弃一些层来缩短ResNets结构以保证更好的信息和梯度传递。 FractalNet通过多次合并具有不同数量的卷积块的并行层序列以获得大的标称深度,同时在网络中保持许多短路径。虽然这些不同的方法在网络拓扑和训练过程中各不相同,但是它们都具有一个关键特征:它们创建从早期层到后期层的短路径。

    在本章中,我们对这种将这种见解提炼成简单连接模式的体系结构加以验证,并尝试改进策略。为了确保网络中各层之间的最大信息流,直接连接所有的网络层。为了保留前馈特性,每一层都从前面的所有层获得附加输入,并将其自身的特征映射传递到所有后续层。图3-1示意性地说明了这种布局。最重要的是,与ResNets相比,DenseNet从未将特征通过求和组合到一个层中,相反地,DenseNet通过连接它们来组合特征。因此,第 层有l个输入,由前面所有卷积块的特征映射组成。它自己的特征映射被传递给所有的 后续层。这在一个L层网络中引入了 个连接,而不仅仅是像在传统架构中一样的L个连接。由于其密集的连接性模式,我们将这种方法称为密集卷积网络(DenseNet)。
    在这里插入图片描述
    图3-1 DenseNet(左)与ResNet(右)部分结构对比

    这种密集连接可能是反直觉效应模式是它比传统需要更少的参数卷积网络,因为不需要重新学习多余的特征图(feature maps)。传统的前馈架构可以被看作是具有状态的算法,其中信息从一层到下一层进行传递,每层从它的前一层读取状态然后写入后续层。这种节后改变了状态,但也传递了需要被保存的信息。ResNets通过增加性标识转换使得信息被保留。ResNets最近的变化显示了许多层次贡献很小,并且事实上可以在训练中随机丢弃。这使ResNets的状态类似到递归神经网络,但ResNets的参数数量要大得多,因为每一层都有自己的权重。DenseNet架构明确区分被添加到网络中的信息和保留的信息。DenseNet的层非常狭窄(例如,每一层有12个特征图),通过向网络中增加一小部分特征图,并保持其余特征映射不变,最后的分类器基于网络中所有的特征图做决策。

    除了更好的参数使用效率外,DenseNet还有一大优势就是他们改进的信息流和梯度流经整个网络,这使得他们很容易训练。每个层都可以直接访问损失函数的梯度和原始输入信号,使得网络包含了隐式的深度监督。这有助于训练更深的网络架构。此外,我们还观察到密集的连接具有正则化效果,这减轻了训练集规模较小时产生的过度拟合问题。

    论文使用几个标准数据集(CIFAR-10,CIFAR-100,SVHN)来评估DenseNet。实验达到了与现有算法相媲美的准确性,而且往往需要更少的参数。并且,性能优于目前的最新技术水平大部分基准测试任务的结果。

    3.1.2 相关研究

    自神经网络问世以来,网络架构的探索一直是其中重要的一部分。最近神经网络的普及也恢复了这一研究领域。层数越来越多在现代网络中放大了网络之间的差异架构,并激发对不同连接性的探索模式和对旧研究思路的重新审视。

    级联结构类似于密集网络布局,该结构自20世纪80年代起已经在神经网络中进行了研究贡献。他们的开创性工作侧重于完全连接的多层感知器在层与层之间训练。最近,完全连接的级联网络受到批梯度下降训练算法的影响。尽管对小数据集有效,但这一方法只能扩展到具有几百个参数的网络。利用多级特征在CNN通过跳跃连接(skip-connnections)被证明是适用于各种视觉任务的。

    Highway Networks是提出训练端到端网络最早的架构之一,网络首次超过100层。通过使用绕过路径与门控单元,Highway Networks网络有效地使用SGD优化数百个图层。被绕过的路径被认为是简化了这些非常深的网络训练的关键因素。这一点在ResNet中得到进一步支持,ResNet在挑战图像识别,定位和检测任务等方面取得了令人印象深刻的创纪录的表现,如ImageNet和COCO目标检测。最近,随机深度作为一种成功的方法训练了一个1202层深的ResNet网络结构。随机深度通过随机丢弃一些层(Dropout机制)来改善深度残留网络的训练。这表明不是所有层都是必须的,并强调在深度(残差)网络中存在着比较大的冗余量。DenseNet正是受到这一观点的启发。

    一种使网络层数更深的正交方法(例如,在跳过连接的帮助下)是增加网络宽度。 GoogLeNet使用了“Inception module”。该模块连接了由不同大小的过滤器生成的特征映射。ResNet的一个变种提出了更广泛的残差块。在实际上,简单的增加ResNet每一层的过滤器数量能提升网络的表示能力。

    DenseNet通过特征重用(feature reuse)来探索网络的潜力,以产生易于训练和高参数效率的密集模型,而不是从极端的图形表示力深层或广泛的架构。通过连接不同的层中学习到的特征映射会增加后续层输入的变化并提高效率,这形成了DenseNet和ResNet之间的一个主要区别。与同样也是连接由不同层提取的特征的InceptionNet相比,DenseNets更简单,更高效。

    还有其他值得注意的网络体系结构创新,他们同样取得了有竞争力的结果。Network In Network(NIN)结构包括微型多层感知器进入卷积层的滤波器中以提取更复杂的特征。在深度监督网络(DSN)中,内部层直接受到辅助分类器的监督,这可以加强由较早的层传递来的梯度。Ladder Network引入横向连接到自动编码器(autoencoder),获得了在半监督学习任务方面较高的准确性。Deeply-Fused Net(DFNs)被引出的目的是为了提升信息的流动,通过组合中间层不同的基础网络。通过增加路径来减少重建损失的网络也被证明可以改善图像分类模型。

    3.2 改进的DenseNet结构

    现在考虑一个通过卷积网络传递的单个图像 。这个网络包含L层,每一层实现一个非线性变换 ,其中l表示层数。 可以是一个符合函数,诸如批量标准化(Batch Normalization)、整流线性单元(ReLU)、卷积(Conv)或者赤化(Pooling)。定义 层的输出为 。DenseBlock的结构如图3-2所示:
    在这里插入图片描述
    图3-2 一个5层Dense Block模型

    传统前馈卷积网络将 层的输出直接作为 层的输入,得到这个传递函数: 。而ResNet在进行非线性转换时添加了跳跃连接(skip-connection),得到下面的转换方程: 。ResNet的一个明显优点就是梯度直接从后面的层流向前面的层。然而,非线性变换及其输出是以加法结合在一起,这将影响网络中信息的流动。

    3.2.1 密集连接(Dense connectivity)

    为了进一步提升网络中信息的流动性,模型使用一种不同的连接方式:将每一层直接与后面的每一层相连接。因此,第 层会获取前面所有层的特征图,公式如下,其中 表示由第0,1, ,l-1层产生的特征图组成的向量。
    (3-1)
    因为使用了密集连接(Dense connectivity),这种网络结构称之为Dense Convolution Network(DenseNet)。为了便于实施,合并多输入的 为一个简单向量。

    3.2.2 综合函数(Composite function)

    定义 为一个包含了三个连续操作的复合函数:批量标准化(Batch Normalization),整流线性单元(ReLU)和一个 卷积(Conv)。

    3.2.3 池化层(Pooling layer)

    图3-2中使用的级联操作在特征映射的大小发生变化时变得不可行。但是,卷积网络的一个重要组成部分是汇集可改变特征映射大小的层。为了便于在体系结构中合并,将网络分成多个密集连接的密集块(dense blocks)。密集块之间的层称为过渡层,它们进行卷积和池化操作。 在我们的实验中使用的过渡层包括批量标准化层和1×1卷积层,然后是2×2平均池化层。

    3.2.4 增长率(Growth rate)

    如果每一层的函数 生成k个特征图作为输出,那么第 层有 个输入特征图,其中 是原始输入图像的通道数。为了防止网络增长太宽,并改善参数效率,限制k为一个小的整数,例如k=12。我们引入超参数k作为网络的增长率,并且相对较小的增长率就足够了在我们测试的数据集上获得最新的结果。对此的一种解释是每个层都有到其他密集块特征映射的访问权限,另一种解释是将特征图看做网络的全局状态,即每一层为自己增加k个特征图。增长率调节每一层贡献给全局状态的新信息量。全局状态一旦写入,就可以从网络的任何地方访问它,这与传统网络体系结构不同,我们不需要一层一层地复制它。

    3.2.5 瓶颈层(Bottleneck layers)

    尽管每一层只产生k个输出特征图,它通常有更多的输入。前面我们提到,可以引入1×1卷积作为每次3×3卷积之前的瓶颈层(Bottleneck layer),以减少输入特征图的数量,从而减少输入特征图的数量,提高计算效率。我们发现这个设计对DenseNet非常有效,并将Bottleneck layer引入我们的网络,即BN-ReLU-Conv(1×1)-BN-ReLU-Conv(3×3)版本的综合函数,作为DenseNet-B。除非另有规定,每个1×1卷积减少在所有实验中输入到4k特征映射。

    3.2.6 压缩(Compression)

    为了进一步提高模型的紧凑性,我们可以减少过渡时的特征映射的数量层。 如果密集块包含m个特征映射,我们让下一个过渡层生成不超过 的最大整数个输出特征图,其中 被称为压缩因子。当 时,转换过程中的特征映射的数量保持不变。我们称DenseNet当 时为DenseNet-C,我们在实验中设定 。当同时使用了瓶颈层(Bottleneck layers)和压缩(Compression)方法时,我们称我们的模型为DenseNet-BC。
    在这里插入图片描述
    图3-3 包含3个Dense Block的DenseNet结构

    3.3 DenseNet卷积网络的实现与测试

    3.3.1 Tensorflow框架

    TensorFlow是Google推出的一套机器学习系统,使用其简单灵活的架构可以轻松构建各种复杂的算法模型。其高效的执行系统和分布式架构保证了在模型训练和执行时的高性能。再加上其跨平台可移植性及实验可复现,支持快速产品化等特点,逐渐成为主流的机器学习平台。

    TensorFlow是一个基于计算图(Computational Graph)的数值计算系统。计算图是一个有向图,图中的节点表示数学计算操作的算子(operations)。节点之间的连接的边代表参与计算的高维数组,成为tensor。计算图的执行可以看做数据tensor按照计算图的拓扑结构顺序,从输入节点逐步流过所有中间节点,最后到达输出节点的过程。Session(会话)系统执行的入口,其负责完成节点布置和传输节点的添加等任务。

    本节DenseNet的结构正是用到了TensorFlow来实现。

    3.3.2 DenseNet网络实现

    DenseNet网络的结构如图3-3所示,其中N表示 卷积和 卷积的组合。我们可以看到,具有不同层的网络也有一个大致相似的结构。网络首先在输入图像上做一次卷积和池化操作,然后进入第一个DenseBlock,DenseBlock里面就是在做密集的连接运算。第一个DenseBlock后是一个Transition Layer,同样还是一个卷积和池化操作。再往后就是与前面类似的结构,只不过通过卷积得出的特征图尺寸越来越小,深度越来越大。网络的最后一层就是分离N类的Softmax层,采用全连接结构。

    网络结构代码由TensorFlow框架实现。和通常使用一样,我们从输入图像开始一步一步构建网络的拓扑结构。代码实现的关键点在于如何实现“跳跃连接”,在DenseBlock中,我们将前面层的特征图全都传到后面层中。我们注意到,不同尺寸的特征图进入DenseBlock,每一个DenseBlock中的特征图的尺寸是一样的,我们使用框架提供的一个合并函数:tf.concat(concat_dim, values, name=’concat’)。该函数的第一个参数concat_dim必须是一个数,表明在哪个维度上进行连接操作,第二个参数values就是两个或者一组待连接的tensor。举个例子,DenseBlock中的第一层特征图a是一个[16,32,32,16]维的数组,经过一次卷积得到中间特征图b是一个[16,32,32,6]维的数组,调用函数c= tf.concat(3, (a,b))得到一个[16,32,32,22]维的向量,作为第二层的输入特征图。在DenseBlock中,每一层都调用该函数将上一层的特征图和本层产生的特征图进行合并,最终DenseBlock中最后一层就得到前面多有特征图的组合。

    表3-1 DenseNet网络结构图
    Layer Feature Size DenseNet-121 DenseNet-169 DenseNet-201 DenseNet-161
    Conv 112×112 7×7 conv
    Pooling 56×56 3×3 max pool
    DenseBlock1 56×56 N×6
    N×6
    N×6
    N×6

    L1 56×56 1×1 conv
    28 × 28 2×2 avg pool
    DenseBlock2 28 × 28 N×12 N×12 N×12 N×12
    L2 28 × 28 1×1 conv
    14 × 14 2×2 avg pool
    DenseBlock3 14 × 14 N×24 N×32 N×48 N×36
    L3 14 × 14 1×1 conv
    7 × 7 2×2 avg pool
    DenseBlock4 7 × 7 N×16 N×32 N×32 N×24
    Classification 7 × 7 ,Average Pooling
    1000D full connection

    3.3.3 网络训练

    我们凭经验证明了它的有效性,DenseNet在几个基准数据集上进行比较具有最先进的网络架构,尤其是与ResNet及其变体相比。

    1、数据库
    模型训练使用CIFAR-10数据集。CIFAR-10数据集是一个经典的物体识别数据集,该数据集是由60000张 的RGB彩色图片构成,共有10个分类,每一类有6000张图像。其中包含50000张训练图片和10000张测试图片。

    数据集被分为5个Training Batch和1个Test Batch,每个Batch有10000张图像。测试批次包含来自每个类的恰好1000个随机选择的图像。训练批次以随机顺序包含剩余图像,但一些训练批次可能包含来自一个类的图像比另一个更多。这10类物体分别是:飞机,汽车,鸟,猫,麋鹿,狗,青蛙,马,船和卡车。这些分类完全互斥,汽车和卡车之间没有重叠。汽车包括轿车、SUV等,卡车只包括大卡车。两者都不包含皮卡车。

    2、开始训练
    所有的网络均使用随机梯度下降算法(SGD)进行训练。在CIFAR数据集上我们使用小批量训练大小为64,并使用300和40作为训练周期。初始学习率设为0.1,并且在训练周期的50%和75%阶段再除以10。在ImageNet上,我们使用256的小批量训练集和90个训练周期。初始学习率设为0.1,并且在训练周期为30和60的阶段再除以10。由于GPU内存的限制,我们使用的小批量训练尺寸为128,作为补偿,我们训练100个周期,并且在90周期时将学习率除以10。

    随后,我们使用一个 的权重衰减,并使用高斯分布来初始化权重。在没有数据增量的三个数据集里,我们在每一个卷积层(除了第一个)后加上一个Dropout层,并设随机丢弃率(dropout rate)为0.2。测试误差仅对一项任务进行一次评估。

    3、训练结果
    我们使用不同的深度L和不同的增长率k。在CIFAR和SVHN数据集上的主要测试结果图表3-2所示。

    表3-2 CIFAR和SVHN数据集上的错误率
    Method Depth Params C10 C10+ C100 C100+ SVHN
    ResNet 110 38.6M — 6.61 — — —
    ResNet2 164 1.7M 11.26 5.46 35.58 24.33 —
    DenseNet(k=12) 40 1.0M 7.00 5.24 27.55 24.42 1.79
    DenseNet(k=12) 100 7.0M 5.77 4.10 23.79 20.20 1.67
    DenseNet(k=24) 100 27.2M 5.83 3.74 23.42 19.25 1.59
    DenseNet-B(k=12) 100 0.8M 5.92 4.51 24.15 22.27 1.76
    DenseNet-B(k=24) 250 15.3M 5.19 3.62 19.64 17.60 1.74
    DenseNet-B(k=40) 190 25.6M — 3.46 — 17.18 —

    首先来看准确率。可能最引人注目的是表3-2最下面的一行,可以看出当L=190,k=40时的DenseNet-BC在CIFAR数据库上表现地比现有的最好的算法还要出色。最终的错误率是3.46%(C10+)和17.18%(C100+),这一结果明显低于宽度ResNet架构得到的错误率。我们在C10和C100(均没有图像增量)上的最好结果甚至有更多令人鼓舞的地方:两者都以丢弃路径的正则化方式得到比FractalNet低30%的结果。DenseNet在SVHN数据集上以L=100,k=24的结构超过了ResNet取得最好成绩。然而,250层的DenseNet-BC并不能进一步改进短连接带来的变现,可能是由于SVHN是个比较容易解释的任务,并且及其深的模型容易过拟合。

    再来看参数量,如果没有压缩层或者瓶颈层的话,网络会有一个趋势就是性能会随着L和k的增加而变现更好。我们将此归因于相应的模型容量的增长。最好的证明就是在C10数据集上随着错误率从5.24%下降到4.10%,最后降到3.74%,参数的数量从1.0M到7.0M,再到27.2M。在C100数据集上也能观察到这一趋势。这表明DenseNet可以利用更大更深层模型的持续增长的变现力。也表明网络不会受到ResNet中过拟合或者优化难等问题的困扰。

    表中的结果表明DenseNet比其他架构模型(尤其是对比了ResNet)有更高效的参数利用率。具有Bottleneck结构的DenseNet-BC结构具有显著的参数利用率。比如,最深的模型仅有15.3M的参数量,但它始终优于其他模型,比如ResNet的参数量超过了30M。需要强调的是,超参数L=100和k=12的DenseNet-BC结构能达到与1001层的ResNet相当的性能(C10错误率4.51%vs 4.62%,C100错误率22.27%vs22.71%),但是参数量却少了90%。图3-4表明了两种网络在C10数据集上的训练损失(Training loss)和测试误差(Test Error)。

    最后研究一下过拟合现象。高效利用参数的一个积极的作用就是能够减轻过拟合现象。我们注意到,在没有进行增强的数据集上,DenseNet架构相比于之前的工作的改进尤为明显。在C10上,改进意味着相对误差从7.33%降至5.19%,相对减少29%。在C100上,减小幅度为30%,从28.2%降至19.64%。在我们的实验中,我们观察到潜在的过拟合出现在一个单一的设置:在C10中,通过增加k=12到k=24所产生的参数4倍增长导致误差从5.77%小幅增加到5.83%。DenseNet-BC的Bottleneck层和压缩层是对付这种趋势的有效方法。
    在这里插入图片描述
    图3-4 DenseNet测试图

    3.3.4 与同类方法对比

    从表面看,DenseNet网络与ResNet非常相似,只有功能函数由 变成了加法。然而,这个看起来很小的修改的影响导致两种网络架构的行为大不相同。
    在这里插入图片描述
    图3-5 DenseNet与ResNet错误率比较

    1、模型紧凑
    作为输入级联的直接结果,DenseNet任何层获得的特征映射可以被所有后续层访问。这鼓励了整个网络中的特征重用,并导致更紧凑的模型。图3-5中的图显示了这是一个旨在比较所有DenseNet参数效率和一个可比较的ResNet体系结构的实验结果。模型在C10上训练多个不同深度的小网络,并将它们的测试精度作为网络参数的一个函数。与其他流行的网络结构(比如AlexNet和VGGNet)相比,带有预激活的ResNet使用较少的参数,同时通常可获得更好的结果。因此,我们比较DenseNet(k=12)与ResNet。DenseNet的训练参数设置与上一节保持一致。

    图3-5显示DenseNet-BC始终是DenseNet的最高参数的有效变体。此外,为了达到相同的准确度,DenseNet-BC只需要ResNet大约1/3的参数量。这一结果与我们在表3-2中呈现的ImageNet上的结果一致。表3-2显示一个仅有0.8M可训练的DenseNet-BC就能够实现与1001层ResNet相当的准确度,后者具有10.2M的参数量。

    2、隐含的深度监督。
    提高密集卷积网络准确性的一个解释可能是单个层通过较短的连接从损失函数外接收额的监督。可以理解为DenseNets在进行一种“深度监督”。前面在深度监督网络中展示了“深度监督”的好处,它们将分类器附加到每个隐藏层,强制中间层学习判别特征。

    DenseNet以隐含的方式执行类似的深层监督:网络顶部的单个分类器通过至多两个或三个过渡层直接监督所有层。然而,DenseNets的损失函数和梯度实质上并不复杂,因为所有层之间共享相同的损失函数。

    3、随机连接与确定性连接。
    密集卷积网络和残余网络的随机深度正则化之间有一定的联系。在随机深度中,ResNet中的层随机丢弃,从而在周围层之间建立直接连接。由于池化层永远不会被丢弃,因此网络会产生与DenseNet类似的连接模式:如果所有中间层都是随机丢弃的,则在任何两层之间有一个小概率可以直接连接。 尽管这些方法与以往完全不同,但DenseNet对随机深度的解释可能会提供正规化一种正确的启示。

    4、特征重用
    按照设计,DenseNet允许每层访问来自其前面所有层的特征图(尽管有时会通过过渡层)。我们进行一项实验来验证一个被训练过的网络是否利用了这一优势。我们首先在C10上训练一个DenseNet,令L=40和k=12。对于密集块中的每一个卷积层l,我们计算分配给层s连接的平均绝对权重。平均绝对权重充当卷积层所依赖的前面层的替代物。位置 处的点表示层l使用前面s层生成的特征图的平均情况。可以得到以下观测结果:

    (a)所有图层将其权重分布在同一个块内的许多输入上。 这表明非常早期的层提取的特征实际上直接被整个同一密集块中的深层使用。

    (b)过渡层的权重也将它们的权重分散到前一个密集块内的所有层上,从而通过少量间接指示从DenseNet的第一层到最后一层的信息流。

    (c)第二个和第三个密集块内的图层始终将最小权重分配给过渡图层(三角形顶部行)的输出,表明过渡图层输出许多冗余特征(平均具有低权重)。 这与DenseNet-BC的强大结果保持一致,在这些结果中正好压缩了这些输出。

    (d)尽管最右侧的分类层也使用了整个密集块中的权重,但似乎还是会集中在最终的特征图上,这表明网络后期可能会产生更多的高级特征。

    3.3.5 DenseNet小结

    DenseNet将具有相同特征图大小的任何两个图层之间进行直接连接。我们发现DenseNet可以自然扩展到数百层,同时不会出现优化问题。在实验中,随着参数数量的增加,DenseNet倾向于提高准确度的一致性,没有任何性能下降或过度拟合的迹象。在多个设置下,它在多个高度竞争的数据集上实现了最先进的结果。而且,DenseNet需要实质上更少的参数和更少的计算来实现最新的性能。因为本研究中采用了针对残留网络优化的超参数设置,所以我们相信通过更详细地调整超参数和学习速率计划,可以获得DenseNet准确性的进一步提高。

    在遵循简单的连接规则的同时,DenseNets自然地整合了身份映射的属性,深度监督和多样化的深度。它们允许在整个网络中重用特征,并因此可以学习更紧凑。由于其紧凑的内部表示和减少的特征冗余,DenseNet可能是用于构建在卷积特征上的各种计算机视觉任务的良好特征提取器。

    3.4 本章小结

    本章首先讲述了密集卷积网络(DenseNet)的结构和原理,并通过组合优化策略将其改造成高质量的特征提取器。实验表明经过不断地增加层数可以有效提高准确率,并且不会产生过拟合的现象。实验成功将算法应用在分类问题上,下一章我们将该网络作为基础网络用于图像检测。

    展开全文
  • 针对这些问题,提出多维加权密集连接卷积神经网络模型实现对多光谱卫星云图的云检测。跨层连接能够实现网络中所有层之间的信息流,从而减少训练过程中的梯度消失导致收敛困难的问题。特征图之间连接的权值不同使得...
  • 前言在计算机视觉领域,卷积神经网络(CNN)已经成为最主流的方法,比如最近的GoogLenet,VGG-19,Incepetion等模型。CNN史上的一个里程碑事件是ResNet模型的出现,ResNet可以训练出更深的CNN模型,从而实现更高的准确...

    前言

    在计算机视觉领域,卷积神经网络(CNN)已经成为最主流的方法,比如最近的GoogLenet,VGG-19,Incepetion等模型。CNN史上的一个里程碑事件是ResNet模型的出现,ResNet可以训练出更深的CNN模型,从而实现更高的准确度。ResNet模型的核心是通过建立前面层与后面层之间的“短路连接”(shortcuts,skip connection),这有助于训练过程中梯度的反向传播,从而能训练出更深的CNN网络。今天我们要介绍的是DenseNet模型,它的基本思路与ResNet一致,但是它建立的是前面所有层与后面层的密集连接(dense connection),它的名称也是由此而来。DenseNet的另一大特色是通过特征在channel上的连接来实现特征重用(feature reuse)。这些特点让DenseNet在参数和计算成本更少的情形下实现比ResNet更优的性能,DenseNet也因此斩获CVPR 2017的最佳论文奖。本篇文章首先介绍DenseNet的原理以及网路架构,然后讲解DenseNet在Pytorch上的实现。

    设计理念

    我们常用的有 GoogleNet、VGGNet、ResNet 模型,但随着网络层数的加深,网络在训练过程中的前传信号和梯度信号在经过很多层之后可能会逐渐消失。先前有一些非常好的工作来解决这一问题。如在 Highway 和 ResNet 结构中均提出了一种数据旁路(skip-layer)的技术来使得信号可以在输入层和输出层之间高速流通,核心思想都是创建了一个跨层连接来连通网路中前后层。在本文中,作者基于这个核心理念设计了一种全新的连接模式。为了最大化网络中所有层之间的信息流,作者将网络中的所有层两两都进行了连接,使得网络中每一层都接受它前面所有层的特征作为输入。由于网络中存在着大量密集的连接,作者将这种网络结构称为 DenseNet。其结构示意图如下左图所示:

    它主要拥有以下两个特性:

    1)一定程度上减轻在训练过程中梯度消散的问题。因为从上左图我们可以看出,在反传时每一层都会接受其后所有层的梯度信号,所以不会随着网络深度的增加,靠近输入层的梯度会变得越来越小。

    2)由于大量的特征被复用,使得使用少量的卷积核就可以生成大量的特征,最终模型的尺寸也比较小。

    上右图所示的是构成 DenseNet 的单元模块,看上去和 ResNet 的单元模块非常相似,但实际上差异较大。我对结构设计上的细节进行了以下总结:

    1)为了进行特征复用,在跨层连接时使用的是在特征维度上的 Concatenate 操作,而不是 Element-wise Addition 操作。

    2)由于不需要进行 Elewise-wise 操作,所以在每个单元模块的最后不需要一个 1X1 的卷积来将特征层数升维到和输入的特征维度一致。

    3)采用 Pre-activation 的策略来设计单元,将 BN 操作从主支上移到分支之前。(BN->ReLU->1x1Conv->BN->ReLU->3x3Conv)

    4)由于网络中每层都接受前面所有层的特征作为输入,为了避免随着网络层数的增加,后面层的特征维度增长过快,在每个阶段之后进行下采样的时候,首先通过一个卷积层将特征维度压缩至当前输入的一半,然后再进行 Pooling 的操作。如下图所示:

    5)增长率的设置。增长率指的是每个单元模块最后那个 3x3 的卷积核的数量,记为 k。由于每个单元模块最后是以 Concatenate 的方式来进行连接的,所以每经过一个单元模块,下一层的特征维度就会增长 k。它的值越大意味着在网络中流通的信息也越大,相应地网络的能力也越强,但是整个模型的尺寸和计算量也会变大。作者在本文中使用了 k=32 和 k=48 两种设置。

    作者基于以上原则针对于 ImageNet 物体识别任务分别设计了 DesNet-121(k=32)、DesNet-169(k=32)、DesNet-201(k=32) 和 DesNet-161(k=48) 四种网络结构。其网络的组织形式和 ResNet 类似,也是分为 4 个阶段,将原先的 ResNet 的单元模块进行了替换,下采样过程略有不同。整体结构设计如下所示:

    在 ImageNet 上的实验结果如下:

    上左图表示的是参数量和错误率的关系,上右图表示的是模型测试的计算量和错误率的关系。我们不难看出,在达到相同精度时,DenseNet 的参数量和计算量均为 ResNet 的一半左右。

    总的来说,这是一篇非常有创新性的工作,提出了共享特征、任意层间互连的概念很大程度上减轻了深层网络在训练过程中梯度消散而难以优化的问题,同时也减小了模型的尺寸和计算量,在标准数据集上获得了非常好的性能。唯一可能的不足是网络不能设计地特别「深」,因为随着 DenseNet 网络层数的增加,模型的特征维度会线性增长,使得在训练过程中的计算量和显存开销也会爆发地增长。

    Q&A:

    1.DenseNet 是否可以在物体检测任务中使用?效果如何?

    A:当然,DenseNet 可以通过和 ResNet 一样的方法被应用到物体检测任务中。但是作者并没有在物体检测任务上进行实验,如果关注 DenseNet 在物体检测任务上的效果,可以参考第三方的将 DenseNet 用在物体检测任务上的实验结果。

    2.通过图表可以看到,DenseNet 在相对较小计算量和相对较小的模型大小的情况下,相比同等规模的 ResNet 的准确率提升会更明显。是否说明 DenseNet 结构更加适合小模型的设计?

    A:确实,在小模型的场景下 DenseNet 有更大的优势。同时,作者也和近期发表的 MobileNet 这一针对移动端和小模型设计的工作进行了对比,结果显示 DenseNet(~400MFlops)可以在更小的计算量的情况下取得比 MobileNet(~500MFlops)更高的 ImageNet 分类准确率。

    3.DenseNet 中非常关键的连续的跨层 Concatenate 操作仅存在于每个 Dense Block 之内,不同 Dense Block 之间则没有这种操作,是怎样一种考虑?

    A:事实上,每个 Dense Block 最后的特征图已经将当前 Block 内所有的卷积模块的输出拼接在一起,整体经过降采样之后送入了下一个 Dense Block,其中已经包含了这个 Dense Block 的全部信息,这样做也是一种权衡。

    4.DenseNet 这样的模型结构在训练过程中是否有一些技巧?

    A:训练过程采用了和 ResNet 的文章完全相同的设定。但仍然存在一些技巧,例如因为多次 Concatenate 操作,同样的数据在网络中会存在多个复制,这里需要采用一些显存优化技术,使得训练时的显存占用可以随着层数线性增加,而非增加的更快,相关代码会在近期公布。

    为者常成,行者常至

    展开全文
  • 通过3D卷积神经网络密集连接从MR图像中估计年龄
  • 文章目录0 引言 0 引言 DenseNet论文链接:https://arxiv.org/pdf/1608.06993.pdf Github学习地址:https://github.com/liuzhuang13/DenseNet

    0 引言

    DenseNet论文链接:https://arxiv.org/pdf/1608.06993.pdf

    Github代码学习地址:https://github.com/liuzhuang13/DenseNet

    1 论文学习

    DenseNet论文拜读(中文):https://blog.csdn.net/MRZHUGH/article/details/105901717

    2 源码学习

    Caffe: https://github.com/shicai/DenseNet-Caffe

    Pytorch: PyTorch documentation on models

    Keras, Tensorflow and Theano: https://github.com/flyyufelix/DenseNet-Keras

    MXNet: https://github.com/miraclewkf/DenseNet

    3 Tensorflow2.1 使用

    目前我主要在kaggle的一个比赛上用的DenseNet201,用于图像分类;
    安装并导入相关库:

    # Install and import necessary libraries
    import tensorflow as tf
    import tensorflow.keras.layers as L
    from keras.applications.densenet import DenseNet201
    
    from sklearn import metrics
    from keras.callbacks import ModelCheckpoint
    
    

    不同数据集不同的处理方法,这里就不细说了,得到相应的train_dataset,valid_dataset,test_dataset;
    设置好EPOCHS,BATCH_SIZE,IMAGE_SIZE,Learning rate,lr_schedule;
    其中我用的是EfficientNerB7,就把IMAGE_SIZE=768;
    lr_schedule由keras.callbacks.LearningRateSchedule()得到的;
    之后就可以迁移DenseNet201进行训练了;

    # model
    with strategy.scope():
        model = tf.keras.Sequential([
            DenseNet201(
                input_shape=(IMAGE_SIZE, IMAGE_SIZE, 3),
                weights='imagenet',
                include_top=False
            ),
            L.GlobalAveragePooling2D(),
            L.Dense(train_labels.shape[1], activation='softmax')
        ])
            
                 
        model.compile(
            optimizer='adam',
            loss = 'categorical_crossentropy',
            metrics=['categorical_accuracy']
        )
    #     model.summary()
    
    # save model
    ch_p_den = ModelCheckpoint(filepath="model_den.h5", monitor='val_loss', save_weights_only=True,
                                                     verbose=1)
    
    # train model
    history = model.fit(
        train_dataset, 
        epochs=EPOCHS, 
        callbacks=[lr_schedule, ch_p_den],
        # STEPS_PER_EPOCH_1 = train_labels.shape[0] // BATCH_SIZE
        steps_per_epoch=STEPS_PER_EPOCH,
        validation_data=valid_dataset
    )
    

    最后的训练结果(部分):

    展开全文
  • 什么是DenseNet? ... 我们知道,当靠近输入的层和靠近输出的层之间的连接越短,卷积神经网络就可以做得更深,精度更高且可以更加有效的训练。而DenseNet在此基础上将每一层与之前所有层相连接。传统的L层卷

    什么是DenseNet?

    DenseNet是由清华大学的Zhuang Liu、康奈尔大学的Gao Huang和Kilian Q.Weinberger,以及Facebook研究员Laurens van der Maaten在CVPR 2017所作,并且还获得了2017CVPR最佳论文!下面我们就来看看DenseNet是何方神圣吧。

    我们知道,当靠近输入的层和靠近输出的层之间的连接越短,卷积神经网络就可以做得更深,精度更高且可以更加有效的训练。而DenseNet在此基础上将每一层与之前所有层相连接。传统的L层卷积神经网络有L个连接——位于每一层和其后一层之间—,而我们的神经网络有L*(L+1)/2个直接链接。对于每一层,其输入的特征是之前所有的层,而它自己的特征图作为之后所有层的输入。

    下图展示了具体的密集连接方式:

    DenseNet有以下几个引人注目的优点:缓解梯度消失问题,加强特征传播,鼓励特征复用,极大的减少了参数量。DenseNets需要更少的计算来实现高性能

    ResNet

    训练深层的神经网络,会遇到梯度消失和梯度爆炸(vanishing/exploding gradients)的问题,影响了网络的收敛,但是这很大程度已经被标准初始化(normalized initialization)和BN(Batch Normalization)所处理

    当深层网络能够开始收敛,会引起网络退化(degradation problem)问题,即随着网络深度增加,准确率会饱和,甚至下降。这种退化不是由过拟合引起的,因为在适当的深度模型中增加更多的层反而会导致更高的训练误差
    ResNet就通过引入深度残差连接来解决网络退化的问题,建立前面层与后面层之间的短链接(shortcuts),从而解决深度CNN模型难训练的问题

    具体表达式如下:
    在这里插入图片描述
    在ResNet中前面层与后面层建立的短链接(shortcuts)方式是add相加操作,因此要求输入与输出的shape完全一样!这主要是由ResNet结构中的Identity Block来完成的,更大程度地去加深网络的深度,实现了深度残差网络。但是add操作可能会阻碍网络中的信息流。

    DenseNets和Resnet之间的主要区别,DenseNets通过特征重用来挖掘网络的潜力,产生易于训练且参数效率高的精简模型。将不同层学习到的特征映射进行堆叠操作,可以增加后续层的输入变化,并提高效率。

    DenseNet

    DenseNet的整体网络架构如下图所示:

    一个有三个Dense Block的DenseNet网络。每个Dense Block中含有多个conv blocks,conv blocks中特征图的高度和宽度不发生变化,进行的是通道数的变化。 两个相邻Dense Block之间的层称为Transition Layer过渡层,通过卷积和池化改变特征图的大小

    Dense connectivity 紧密连接

    为了进一步改善层与层之间的信息流,提出了一种不同的连接模式:引入从任何层到所有后续层的直接连接。正如上图所展示的那样,例如第l层接收前面所有层的特征映射,即x0,x1,…,xl-1作为输入:
    在这里插入图片描述
    H函数实现每层的非线性变换,主要由BN,Relu和3x3Conv组成,式中[x0,x1,…,xl-1]指的是第0,…,l-1层中生成的特征图进行串联。

    Bottleneck layers

    每一个Dense Block中的conv block经过H非线性输出k个特征图,但是它通常是输入特征图更多。因此在3x3卷积之前引入1x1卷积作为瓶颈层,以减少特征映射的数量,从而提高计算效率。

    Growth rate

    如果每个函数H生成k个特征映射,则第l层具有k0+k×(l-1)个输入特征映射,其中k0是输入的通道数。DenseNet与现有网络体系结构的一个重要区别是,DenseNet可以有非常窄的层,例如k=12。我们把超参数k称为网络的growth rate。相对较小的growth rate足以获得最新的结果。
    实现代码为:

    class Bottleneck(nn.Module):
        def __init__(self, nChannels, growthRate):
            super(Bottleneck, self).__init__()
            interChannels = 4*growthRate
            # 瓶颈结构1x1卷积减少输入的通道数
            self.bn1 = nn.BatchNorm2d(nChannels)
            self.conv1 = nn.Conv2d(nChannels, interChannels, kernel_size=1,bias=False)
            # H函数实现非线性输出BN+Relu+BN
            self.bn2 = nn.BatchNorm2d(interChannels)
            self.conv2 = nn.Conv2d(interChannels, growthRate, kernel_size=3,padding=1, bias=False)
    
        def forward(self, x):
            out = self.conv1(F.relu(self.bn1(x)))
            out = self.conv2(F.relu(self.bn2(out)))
            out = torch.cat((x, out), 1)
            return out
    

    Pooling layers 池化层

    当特征映射的大小发生变化时,上面式子中使用的连接操作是不可行的。然而,卷积网络的一个重要组成部分是向下采样层来改变特征映射的大小。因此在Dense Block之间添加Transition Layer来进行特征图大小的压缩,而Transition Layer主要由一个1x1卷积块以及步长为2的AveragePooling2D来进行特征图大小压缩。

    Compression 压缩

    为了进一步提高模型的紧凑性,在Transition Layer中减少特征映射的数量。如果一个Desne Block中包含m个特征映射,在Transition Layer中生成的特征图数量为θm,其中0<θ≤1被称为压缩因子。当θ=1时,Transition Layer的特征图数量保持不变,论文中将θ设置为0.5。
    Transition Layer实现代码如下:

    # reduction即为压缩因子
    nOutChannels = int(math.floor(nChannels*reduction))
    class Transition(nn.Module):
        def __init__(self, nChannels, nOutChannels):
            super(Transition, self).__init__()
            self.bn1 = nn.BatchNorm2d(nChannels)
            self.conv1 = nn.Conv2d(nChannels, nOutChannels, kernel_size=1,bias=False)
    
        def forward(self, x):
            out = self.conv1(F.relu(self.bn1(x)))
            out = F.avg_pool2d(out, 2)
            return out
    

    下图包含了具有四个Dense Block的DenseNet网络架构,根据每一个Dense Block中1x1conv 和3x3conv(即conv block)重复次数的不同,可以分为DenseNet-121,DenseNet-1169,DenseNet-201和DenseNet-264。所有网络的growth rate为32。
    输入图片在DenseNet网络的shape的具体变化如下:

    我们以上述DenseNet-121为例,来进行DenseNet网络的详解。我们将输入图片进行数据增强后,resize成224x224的shape作为DenseNet的输入input(224x224,3),经过一个kernel size为7且stride=2的卷积块(Conv+BN+Relu),此时conv1的shape为(112,112,64),再经过一次MaxPooling,poo1的shape变为(56,56,64);进入第一个Dense Block(1),此时的输入为poo1(56,56,64),Dense Block中首先是瓶颈层,即将pool1利用1x1卷积进行降维,降至4xgrowth rate,然后再进行3x3卷积特征提取,将输出通道固定为growth rate,将1x1conv和3
    x3conv称为Dense Block中的一个conv block。然后在进行Dense Block中特有的残差边短接,即将该输出(56,56,growth rate)与输入pool1进行通道数的堆叠,shape变为(56,56,64+growth rate);然后又将该特征层作为输入,继续重复瓶颈结构和残差边短接操作,在DenseNet-121的Dense Block(1)中,上述的conv block和残差边短接一共进行了6次,故输出dense1的shape变为(56,56,64+6growth rate)=(56,56,256),论文中是将growth rate设置为32。需要注意的是,上述Dense Block(1)中并没有发生特征图高度和宽度的改变,仅仅是进行了通道数的堆叠concatenate操作,即层与层之间的密集连接。接着是进入第一个Transition Layer(1),在Transition Layer(1)中首先利用1x1卷积进行通道数的压缩,压缩为一半的通道数,提高模型的紧凑性,shape此时变为(56,56,(64+6growth rate)/2)=(56,56,128)。然后再利用一个步长stride=2的平均池化AveragePooling2D来压缩特征层的高度和宽度,此时trans1的shape变为(28,28,(64+6growth rate)/2)=(56,56,128)。然后再将此特征层作为输入,进入第二个Dense Block(2),Dense Block(2)中进行的操作和Dense Block(1)一样,只是conv block和残差边短接重复的次数不一样而已,Dense Block(2)中一共进行了12次,此时dense2的shape为(28,28,(64+6growth rate)/2+12growth rate)=(28,28,512)。接着进入第二个Transition Layer(2),操作和Transition Layer(1)一样,先利用1x1卷积进行通道数压缩,再利用平均池化压缩特征层的高度和宽度,即trans2的shape为(14,14,((64+6growth rate)/2+12growth rate)/2)=(14,14,256)。再进入第三个Dense Block(3),conv block和残差边短接一共进行了24次,输出dense3的shape为(14,14,((64+6growth rate)/2+12growth rate)/2+24growth rate)=(14,14,1024),进入Transition Layer(3),输出trans3的shape为(7,7,512)。再进入第四个Dense Block(4),conv block和残差边短接一共进行了16次,输出dense4的shape为(7,7,1024)。然后进行一个全局平均池化,最后接一个全连接层将输出通道数固定为n_classes类别数量。

    DenseNet121的pytorch代码具体如下:

    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    from torch.autograd import Variable
    import torchvision.transforms as transforms
    import torchvision.models as models
    from torchsummary import summary
    
    import sys
    import math
    
    
    # 瓶颈结构,1x1卷积将输入通道数降低为4*growthRate,3x3卷积将通道数固定growthRate
    class Bottleneck(nn.Module):
        def __init__(self, nChannels, growthRate):
            super(Bottleneck, self).__init__()
            interChannels = 4 * growthRate
            self.bn1 = nn.BatchNorm2d(nChannels)
            self.conv1 = nn.Conv2d(nChannels, interChannels, kernel_size=1, bias=False)
            self.bn2 = nn.BatchNorm2d(interChannels)
            self.conv2 = nn.Conv2d(interChannels, growthRate, kernel_size=3, padding=1, bias=False)
    
        def forward(self, x):
            out = self.conv1(F.relu(self.bn1(x)))
            out = self.conv2(F.relu(self.bn2(out)))
            out = torch.cat((x, out), 1)
            return out
    
    class SingleLayer(nn.Module):
        def __init__(self, nChannels, growthRate):
            super(SingleLayer, self).__init__()
            self.bn1 = nn.BatchNorm2d(nChannels)
            self.conv1 = nn.Conv2d(nChannels, growthRate, kernel_size=3, padding=1, bias=False)
    
        def forward(self, x):
            out = self.conv1(F.relu(self.bn1(x)))
            out = torch.cat((x, out), 1)
            return out
    
    # Transition Layer将1x1卷积进行通道数压缩一半,然后再进行平均池化
    class Transition(nn.Module):
        def __init__(self, nChannels, nOutChannels):
            super(Transition, self).__init__()
            self.bn1 = nn.BatchNorm2d(nChannels)
            self.conv1 = nn.Conv2d(nChannels, nOutChannels, kernel_size=1, bias=False)
    
        def forward(self, x):
            out = self.conv1(F.relu(self.bn1(x)))
            out = F.avg_pool2d(out, 2)
            return out
    
    
    class DenseNet(nn.Module):
        def __init__(self, growthRate, nDenseBlocks, reduction, bottleneck, nClasses):
            super(DenseNet, self).__init__()
    
            # growthRate=32
            nChannels = 2 * growthRate
            self.conv1 = nn.Conv2d(3, nChannels, kernel_size=7, stride=2, padding=3, bias=False)
            self.bn1 = nn.BatchNorm2d(nChannels)
            self.relu = nn.ReLU(inplace=True)
            self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=0, ceil_mode=True)
    
            self.dense1 = self._make_dense(nChannels, growthRate, nDenseBlocks[0],bottleneck)
            nChannels += nDenseBlocks[0] * growthRate
            nOutChannels = int(math.floor(nChannels * reduction))
            self.trans1 = Transition(nChannels, nOutChannels)
    
            nChannels = nOutChannels
            self.dense2 = self._make_dense(nChannels, growthRate, nDenseBlocks[1],bottleneck)
            nChannels += nDenseBlocks[1] * growthRate
            nOutChannels = int(math.floor(nChannels * reduction))
            self.trans2 = Transition(nChannels, nOutChannels)
    
            nChannels = nOutChannels
            self.dense3 = self._make_dense(nChannels, growthRate, nDenseBlocks[2],bottleneck)
            nChannels += nDenseBlocks[2] * growthRate
            nOutChannels = int(math.floor(nChannels * reduction))
            self.trans3 = Transition(nChannels, nOutChannels)
    
            nChannels = nOutChannels
            self.dense4 = self._make_dense(nChannels, growthRate, nDenseBlocks[3],bottleneck)
            nChannels += nDenseBlocks[3] * growthRate
    
    
            self.bn2 = nn.BatchNorm2d(nChannels)
            self.fc = nn.Linear(nChannels, nClasses)
    
            for m in self.modules():
                if isinstance(m, nn.Conv2d):
                    n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
                    m.weight.data.normal_(0, math.sqrt(2. / n))
                elif isinstance(m, nn.BatchNorm2d):
                    m.weight.data.fill_(1)
                    m.bias.data.zero_()
                elif isinstance(m, nn.Linear):
                    m.bias.data.zero_()
    
        def _make_dense(self, nChannels, growthRate, nDenseBlocks, bottleneck):
            layers = []
            for i in range(int(nDenseBlocks)):
                if bottleneck:
                    layers.append(Bottleneck(nChannels, growthRate))
                else:
                    layers.append(SingleLayer(nChannels, growthRate))
                nChannels += growthRate
            return nn.Sequential(*layers)
    
        def forward(self, x):
            print(x.shape)
            out = self.conv1(x)
            print(out.shape)
            out = self.bn1(out)
            out = self.relu(out)
            out = self.maxpool(out)
            print(out.shape)
    
            out = self.trans1(self.dense1(out))
            print(out.shape)
            out = self.trans2(self.dense2(out))
            print(out.shape)
            out = self.trans3(self.dense3(out))
            print(out.shape)
            out = self.dense4(out)
            print(out.shape)
            out = torch.squeeze(F.avg_pool2d(F.relu(self.bn2(out)), 7))
            print(out.shape)
            out = F.log_softmax(self.fc(out))
            return out
    
    if __name__ == '__main__':
        DenseNet121= DenseNet(growthRate=32, nDenseBlocks=[6, 12, 24, 16], reduction=0.5, bottleneck=True,nClasses=1000)
        model = DenseNet121.train().cuda()
        summary(model,(3,224,224))
    

    在这里插入图片描述
    DenseNet的缺点:DneseNet在训练时十分消耗内存,这是由于算法实现不优带来的。当前的深度学习框架对 DenseNet 的密集连接没有很好的支持,所以只能借助于反复的拼接(Concatenation)操作,将之前层的输出与当前层的输出拼接在一起,然后传给下一层。对于大多数框架(如Torch和TensorFlow),每次拼接操作都会开辟新的内存来保存拼接后的特征。这样就导致一个 L 层的网络,要消耗相当于 L(L+1)/2 层网络的内存(第 l 层的输出在内存里被存了 (L-l+1) 份)

    展开全文
  • 近几年来,随着卷积神经网络(CNNs)的迅速发展,学术界涌现出一大批非常高效的模型,如 GoogleNet、VGGNet、ResNet 等,在各种计算机视觉任务上均崭露头角。但随着网络层数的加深,网络在训练过程中的前传信号和...
  • 卷积神经网络可能是这一巨大成功背后的关键组成模块。这次,我们将要使用卷积神经网络的思想来拓宽我们对神经网络工作原理的理解。简介过去我们接触到了密集连接的神经网络。那些神经网络中,所有的神经元被分成了...
  • 声音数据(比如波形):一维卷积神经网络(首选)或循环神经网络 文本数据:一维卷积神经网络(首选)或循环神经网络 时间序列数据:循环神经网络(首选)或一维卷积神经网络 其他类型的序列数据:循环神经网络或...
  • 在开集协议下设计了一种基于角度距离损失函数和密集连接卷积神经网络的人脸识别算法, 以实现深度人脸识别。所设计的网络结构使用基于角度距离的损失函数, 让人脸特征的区分度更高, 符合特征的理想分类标准。同时, 所...
  • 采用密集连接卷积网络(DenseNet)对编码后的信息进行译码。通过Skip-Connections实现编码和解码的信息流的集成,避免了层间信息传输的丢失。实验结果表明,与其他单目视觉深度估计方法相比,使用深度卷积神经网络...
  • 在计算机视觉领域,卷积神经网络(CNN)已经成为最主流的方法,比如最近的GoogLenet,VGG-19,Incepetion等模型。CNN史上的一个里程碑事件是ResNet模型的出现,ResNet可以训练出更深的CNN模型,从而实现更高的准确度...
  • 卷积神经网络中包含的都是卷积层,根据任务需要可以适当保留池化层,为了完成密集预测,卷积神经网络中的全连接层必须被卷积层替代,这也是全卷积神经网络最大的特点之一。
  • 但在此之前,我们先来看一个简单的卷积神经网络示例,即使用卷积神经网络对 MNIST 数字进行分类,这个任务我们在第 2 章用密集连接网络做过(当时的测试精度为 97.8%)。虽然本例中的卷积神经网络很简单,但其精度...
  • 下图中连线最密集的2个地方就是全连接层,这很明显的可以看出全连接层的参数的确很多。在前向计算过程,也就是一个线性的加权求和的过程,全连接层的每一个输出都可以看成前一层的每一个结点乘以一个权重系数W,最后...
  • 卷积神经网络,是计算机视觉领域使用最广泛的一种深度学习模型。可以对比,使用简单的卷积神经网络,即可达到比使用Dense层模型精确度更高的模型。 与密集连接层不同,卷积层学到的是图像的局部模式,而Dense层是从...
  • 1. 创新接收任意尺寸输入的全卷积网络使用反卷积的上采样融合深层粗糙特征和浅层精细特征的跳跃结构2.模型提出为什么可以将CNN转化为FCN?全连接层可以看作卷积层,其中,feature map 1x1,向量长度为通道数。为什么...
  • 针对传统计算机辅助检测系统中肺结节检测存在大量假阳性的问题,提出一种基于三维卷积神经网络的肺结节识别方法。首先,将传统二维卷积神经网络扩展为三维卷积神经网络,充分挖掘肺结节的三维特征,增强特征的表达能力;...
  • 图解:卷积神经网络数学原理解析

    千次阅读 2020-12-23 13:11:51
    密集连接神经网络结构 当我们根据一组有限的人工设计的特征来解决分类问题时,这种方法很有效。例如,我们根据足球运动员在比赛期间的统计数据来预测他的位置。然而,当处理照片时,情况变得更加复杂。当然,...
  • 在填充锯齿状空洞的卷积通路上构建并行三维卷积神经网络,提取多尺度图像块进行训练,捕获大范围空间信息。利用密集连接的恒等映射特性,将浅层特征叠加到网络末端,在MRI多模态图像中分割出水肿区、增强区、核心区和囊...
  • 2、卷积神经网络的两个有趣的性质。 【1】平移不变性 【2】卷积神经网络可以学到模式的空间层次结构。 3、特征图:对于包含两个空间轴(高度和宽度)和一个深度轴(也叫做通道轴)的3D张量,其卷积也叫做特征图。 4...
  • 卷积神经网络Densenet的分析与总结

    千次阅读 2018-06-28 21:58:24
    我们接受这一观察并且提出密集卷积神经网络,该网络以前馈方式将每层连接到每个其他层。具有L层的传统的卷积神经网络,其有L个连接,当前层只与下一层有一个连接;而我们提出的DenseNet,其具有L(L+1)/2个连接,当前...
  • 使用卷积神经网络之前还要了解一些卷积神经网络相关的基础知识,下面简单介绍一下再进行代码编写。 1、密集连接层(Dense层)和卷积层的区别: Dense层从输入特征空间中学到的是全局模式(涉及所有像素的模式),...
  • 基于卷积神经网络的图像分类

    万次阅读 2018-02-10 17:01:23
    《Convolutional Neural Networks for Large-Scale Remote-Sensing Image Classification》本文提出了一种全卷积神经网络来产生密集分类(逐像素分类),特点是:位置无关、输出是一系列卷积层的结果。首先将负责...
  • 提出了一种基于改进卷积神经网络的视网膜血管分割方法。首先, 将残差学习和密集连接网络(DenseNet)相结合, 更充分地利用每一层的特征;通过增加短连接的方式, 缩短了低层特征图到高层特征图之间的路径, 强化了特征的...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 124
精华内容 49
关键字:

密集连接卷积神经网络