densenet121网络结构_resnet网络结构详解

densenet121网络结构_resnet网络结构详解论文:https://arxiv.org/pdf/1608.06993.pdf参考文献:https://blog.csdn.net/u014380165/article/details/75142664https://blog.csdn.net/qq_14845119/article/details/79272082与残差网络的区别:残差网络是加上跳转链接,非线性映射关…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

论文:https://arxiv.org/pdf/1608.06993.pdf 

参考文献:

DenseNet算法详解_AI之路-CSDN博客_densenet

DenseNet解读_年轻即出发,-CSDN博客_densenet

与残差网络的区别:

残差网络是加上跳转链接,非线性映射关系:

X(t)=H(X(t-1))+X(t-1)

An advantage of ResNets is that the gradient can flow directly through the identity function from later layers to the earlier layers. However, the identity function and the output of H are combined by summation, which may impede the information flow in the network.

ResNets的一个优点是,梯度可以直接通过恒等函数从后面的层流向前面的层。但是,恒等函数和H的输出是累加的,这可能会阻碍网络中的信息流。

为了改善不同层之间信息流的的问题,DenseNet采用直接将所有输入连接到输出层

与残差网络不同的是不用相加而是连接,输入直接传入到输出如图1,非线性映射关系:

X(t)=H([X0,X1,X2,…,X(t-1)])

网络模型:

稠密连接主要由两部分组成:dense block稠密块+transition layer 过渡块

稠密块:定义了输入输出之间的连接关系

过渡层:控制通道数

如图是生长率为4的5层稠密块,这张图对我吸引力也是相当大。主要思想是特征重复利用,又在通道数增多的问题上加入Bottleneck Layers和 transition Layers控制通道数量在4K

densenet121网络结构_resnet网络结构详解

生长率(Growth rate)为4表示每个稠密层输出feature map维度是4,第L层有k0+k(L-1)层输入feature-maps,其中k0是输入层通道数。在定义时一般是全局变量。

5层稠密块表示5个BN+ReLU+Conv(3*3)Layer

为了确保layers之间的最大信息流,将所有的layers直接连接起来。

为了保持前馈特性,每个层的输入是所有前面层映射输出,也将自己的特征映射结果作为后面层的输入。

稠密块后接着过渡层,过渡层就是1*1卷积核,通道数4k,k是生长率。

过渡层解决的问题

每一个DenseBlock模块的输出维度是很大的,假设一个L层的Dense Block模块,假设其中已经加入了Bottleneck 单元,那么输出的维度为,第1层的维度+第2层的维度+第3层的维度+******第L层的维度,加了Bottleneck单元后每层的输出维度为4K,那么最终Dense Block模块的输出维度为4K*L。随着层数L的增加,最终输出的feature map的维度也是一个很大的数。为了解决这个问题,在transition layer模块中加入了1*1卷积做降维。

池化层:

当特征大小改变时,连接操作不再适用。然而卷积层常在下采样提取特征时改变特征大小。池化层用在

解决使用稠密块后带来通道数剧增,使用过多稠密块模型过于复杂的问题。

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

densenet121网络结构_resnet网络结构详解

图2则是一个三个稠密块的稠密连接网络。每层之间有过渡层改变通道数大小,最后一层没有过渡层。

densenet121网络结构_resnet网络结构详解

表1是DenseNet网络结构

densenet121网络结构_resnet网络结构详解

 表2是在CIFAR和SVHN上的对比实验。k越大网络参数越大,效果越好。k较小时,在过渡层是存在信息丢失问题

文章同时提出了DenseNet,DenseNet-B,DenseNet-BC三种结构,具体区别如下:

DenseNet:

Dense Block模块:BN+Relu+Conv(3*3)+dropout

transition layer模块:BN+Relu+Conv(1*1)(filternum:m)+dropout+Pooling(2*2)

DenseNet-B:

Dense Block模块:BN+Relu+Conv(1*1)(filternum:4K)+dropout+BN+Relu+Conv(3*3)+dropout

transition layer模块:BN+Relu+Conv(1*1)(filternum:m)+dropout+Pooling(2*2)

DenseNet-BC:

Dense Block模块:BN+Relu+Conv(1*1)(filternum:4K)+dropout+BN+Relu+Conv(3*3)+dropout

transition layer模块:BN+Relu+Conv(1*1)(filternum:θm,其中0<θ<1,文章取θ=0.5) +dropout +Pooling(2*2)

其中,DenseNet-B在原始DenseNet的基础上,加入Bottleneck layers, 主要是在Dense Block模块中加入了1*1卷积,使得将每一个layer输入的feature map都降为到4k的维度,大大的减少了计算量。

解决在Dense Block模块中每一层layer输入的feature maps随着层数增加而增大,则需要加入Bottleneck 模块,降维feature maps到4k维

DenseNet-BC在DenseNet-B的基础上,在transitionlayer模块中加入了压缩率θ参数,论文中将θ设置为0.5,这样通过1*1卷积,将上一个Dense Block模块的输出feature map维度减少一半。

优缺点:

解决梯度消失的问题

以下是介绍梯度消失、梯度弥散问题的博客:

详解机器学习中的梯度消失、爆炸原因及其解决方法_Double_V的博客-CSDN博客

机器学习总结(二):梯度消失和梯度爆炸_以梦为马,不负韶华-CSDN博客

神经网络训练中的梯度消失与梯度爆炸 – 知乎

解决方案是:尽量缩短前层和后层之间的连接。 (they contain shorter connections between layers close to the input and those close to the output)

(梯度消失经常出现,一是在深层网络中,二是采用了不合适的损失函数,比如sigmoid

梯度爆炸一般出现在深层网络和权值初始化值太大的情况下

解决方案:

残差网络Highway Networks通过旁路信息将上一层信息直接传递给下一层。

随机深度网络,随机dropping layers

分型网络,多条短路径相连接)

我认为梯度消失问题是网络太深,梯度值在网络传递过程中会越来越小或越来越大,传递至输入时损失梯度变化过大,所以反馈信息有误。当每个损失计算都直接与输入相连时则不会出现损失梯度在传递过程中信息值变化过大。

加强特征传播

每一层都可以直接从损失函数和原始输入信号中获取梯度,从而实现隐含的深度监控

鼓励特征重用

前向传递中每经过一层传递信息都将改变,ResNet利用相加保留了这部分信息。随着近几年研究表明许多层贡献很小,可以在训练中随机删去某些层。这使得ResNet有些像RNN,但是ResNet的参数很大,因为每层都需要自己的权重。

DenseNet明确区分了添加到网络中的信息(改变的信息)和被保护的信息(重用的信息)。

DenseNet层是非常窄的(例如,每层12个过滤器),只在网络的集合知识中添加一小部分feature-maps,并保持其余的feature-maps不变,最终的分类器根据网络中的所有feature-maps做出决策。

大幅度减少参数数量

网络比较窄,参数少,其feature maps=4k,k是生长率,一般比较小。

不需要学习冗余的特征映射。

有正则化,可以在小数据集上减少过拟合,文中解释为参数减少的原因。

Bottleneck Layers:

BN+Relu+Conv(1*1)(filternum:4K)+dropout(代码中无)+BN+Relu+Conv(3*3)+dropout(代码中无)

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

普通Dense Block  :

BN+Relu+Conv(3*3)+dropout(代码中无)

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

Dense Net,3块Dense Block,如图2

class DenseNet(nn.Module):
    def __init__(self, growthRate, depth, reduction, nClasses, bottleneck):
        super(DenseNet, self).__init__()

        nDenseBlocks = (depth-4) // 3
        if bottleneck:
            nDenseBlocks //= 2

        nChannels = 2*growthRate
        self.conv1 = nn.Conv2d(3, nChannels, kernel_size=3, padding=1,
                               bias=False)
        self.dense1 = self._make_dense(nChannels, growthRate, nDenseBlocks, bottleneck)
        nChannels += nDenseBlocks*growthRate
        nOutChannels = int(math.floor(nChannels*reduction))
        self.trans1 = Transition(nChannels, nOutChannels)

        nChannels = nOutChannels
        self.dense2 = self._make_dense(nChannels, growthRate, nDenseBlocks, bottleneck)
        nChannels += nDenseBlocks*growthRate
        nOutChannels = int(math.floor(nChannels*reduction))
        self.trans2 = Transition(nChannels, nOutChannels)

        nChannels = nOutChannels
        self.dense3 = self._make_dense(nChannels, growthRate, nDenseBlocks, bottleneck)
        nChannels += nDenseBlocks*growthRate

        self.bn1 = 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):
        out = self.conv1(x)
        out = self.trans1(self.dense1(out))
        out = self.trans2(self.dense2(out))
        out = self.dense3(out)
        out = torch.squeeze(F.avg_pool2d(F.relu(self.bn1(out)), 8))
        out = F.log_softmax(self.fc(out))
        return out

过渡层:

BN+Relu+Conv(1*1)(filternum:m)+dropout(无)+Pooling(2*2)

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

代码:

https://github.com/liuzhuang13/DenseNet

GitHub – titu1994/DenseNet: DenseNet implementation in Keras

https://github.com/YixuanLi/densenet-tensorflow

参考文献:

5.12. 稠密连接网络(DenseNet) — 《动手学深度学习》 文档

DenseNet模型_毛财胜的专栏-CSDN博客_densenet201

DenseNet算法详解_AI之路-CSDN博客_densenet

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/187797.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • java 判断对象是否为空的工具类_如何判断java对象是否为空「建议收藏」

    java 判断对象是否为空的工具类_如何判断java对象是否为空「建议收藏」首先来看一下工具StringUtils的判断方法:一种是org.apache.commons.lang3包下的;另一种是org.springframework.util包下的。这两种StringUtils工具类判断对象是否为空是有差距的:StringUtils.isEmpty(CharSequencecs);//org.apache.commons.lang3包下的StringUtils类,判…

  • java PrepareStatement[通俗易懂]

    java PrepareStatement[通俗易懂]PrepareStatementStatement对同一个sql语句charrette不同值需要重新发送一条sql语句sql注入selectusername,passwordfromempwhereusername=’admin’andpassword=’123’or1=1;insertintoempvalues(?,?,?);接口PrepareStatement表示预编译的SQL语句的对象。SQL语句被预编译并存储在Prepare…

  • AD PCBlayout 总结[通俗易懂]

    AD PCBlayout 总结[通俗易懂]PCBlayout总结1、关于规则注:多个规则存在时需要设置规则的优先级,如:(1)poly和keepout之间的clearance规则定义2、关于走线拐角PCB走线中不能出现锐角和直角,而且走线也不能和IC的PIN脚垂直首先不光是天线的布线不走锐角,在布线中最好都不走锐角,只是天线的布线尤为重要。1、对于高频电流来说,当导线的拐弯处呈现直角甚至锐角时,在靠近弯角的部位,磁通密度及电场强度都比较高,会辐射较强的电磁波,而且…

    2022年10月28日
  • caffe中常用层: BatchNorm层详解

    caffe中常用层: BatchNorm层详解Batchnorm原理详解前言:Batchnorm是深度网络中经常用到的加速神经网络训练,加速收敛速度及稳定性的算法,可以说是目前深度网络必不可少的一部分。 本文旨在用通俗易懂的语言,对深度学习的常用算法–batchnorm的原理及其代码实现做一个详细的解读。本文主要包括以下几个部分。Batchnorm主要解决的问题Batchnorm原理解读Batchnorm的优点Batchnorm的源码解读第一…

  • matlab plot函数详解_matlab floor函数用法

    matlab plot函数详解_matlab floor函数用法plot是绘制二维图形的最基本函数,它是针对向量或矩阵的列来绘制曲线的。也就是说,使用plot函数之前,必须首先定义好曲线上每一点的x及y坐标。1.plot(x)当x为一向量时,以x元素的值为纵坐标,x的序号为横坐标值绘制曲线。当x为一实矩阵时,则以其序号为横坐标,按列绘制每列元素值相对于其序号的曲线。2.plot(x,y)以x元素为横坐标值,y元素为纵坐标值绘制曲线3….

  • arping详解

    arping详解最近检测内网机器的ip占用问题,用到了arping,总结一下。版本arping主要干的活就是查看ip的MAC地址及IP占用的问题。arping有两个版本,一个版本是ThomasHabets这个人写的,这个版本有个好处是可以arping<MAC地址>,也就是说我们可以通过MAC地址得到IP。还有一个版本是Linuxiputilssui…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号