深度学习训练营之Densenet网络

news2024/9/29 11:36:21

深度学习训练营

  • 原文链接
  • 环境介绍
  • 前言
  • 设计理念
  • 网络结构
  • 实验结果和讨论
  • pytorch实现DenseNet
  • 附录

原文链接

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍦 参考文章:365天深度学习训练营-第J3周:Densenet网络学习
  • 🍖 原作者:K同学啊|接辅导、项目定制

环境介绍

  • 语言环境:Python3.9.13
  • 编译器:jupyter notebook
  • 深度学习环境:TensorFlow2

前言

在计算机视觉领域当中,卷积神经网络(CNN)已经成为最主流的方法.CNN当中十分重要的就在于ResNet的出现,ResNet可以训练出更深的CNN模型,实现较高的准确度,有助于训练过程当中梯度的反向传播,从而训练出更深的CNN网络,
DenseNet(Densely connected convolutional networks),其基本思路和ResNet一致,重要的在于其将前面所有层与后面层的密集连接.
其一大特色在于通过特征在channel上实现特征重用(feature reuse)

设计理念

相较于ResNet,DenseNet提出了更加激进的密集连接机制,简单的来说,就是当前层是会接受前面所有的层作为额外的输入,也正是因为如此表现的更加紧密
对于一个 L L L 层的网络,DenseNet共包含 L ( L + 1 ) 2 \frac{L(L+1)}{2} 2L(L+1)个连接,这相较于ResNet,这是一种密集连接。而且DenseNet是直接concat来自不同层的特征图,这可以实现特征重用,提升效率,这一特点也是DenseNet与ResNet最主要的区别。
标准神经网络:
传统的网络在 l l l层的输出为 x l = H l ( x l − 1 ) x_l=H_l (x_{l-1}) xl=Hl(xl1)
在这里插入图片描述
ResNet:
对于ResNet来说,增加了来自上一层的输入的 i d e n t i t y identity identity函数: x l = H l ( x l − 1 ) + x l − 1 x_l=H_l(x _{l−1})+x_{l−1} xl=Hl(xl1)+xl1
在这里插入图片描述

DenseNet:
在DenseNet当中会连接到所有的层作为输入: x l = H l ( [ x 0 , x 1 , ⋅ , x l − 1 ] ) x_l=H_l([x_0,x_1,\cdot,x_{l-1}]) xl=Hl([x0,x1,,xl1])
在这里插入图片描述
需要注意到的是 H l ( ⋅ ) H_l(⋅) Hl()表示非线性转化函数( n o n − l i n e a r t r a n s f o r m a t i o n non-linear \\ transformation nonlineartransformation)
,这当中是包括像 B N BN BN, R e L U ReLU ReLU等格式各样的卷积层的组合操
DenseNet的密集连接方式要求了其需要保证特征图的一致,为解决这样的问题,使用到 D e n s B l o c k + T r a n s i t i o n DensBlock+Transition DensBlock+Transition的结构,其中 D e n s e B l o c k DenseBlock DenseBlock包含多个层的模块,保证每一层的特征图一样,可以实现层与层之间的密集连接
请添加图片描述

网络结构

D e n s e N e t DenseNet DenseNet的网络结构主要利用 D e n s e B l o c k DenseBlock DenseBlock T r a n s i t i o n Transition Transition组成
请添加图片描述
D e n s e B l o c k DenseBlock DenseBlock当中,每一个层的特征图大小一致,可以在 c h a n n e l channel channel维度上链接, D e n s e B l o c k DenseBlock DenseBlock的非线性组合函数 H ( ⋅ ) H(⋅) H()采用 B N + R e L U + 3 ∗ 3 C o n v BN+ReLU+3*3Conv BN+ReLU+33Conv的结构,
注意所有的 D e n s e B l o c k DenseBlock DenseBlock中各个层卷积之后会输出 k k k个特征图,即得到的特征图的 c h a n n e l channel channel数为 k k k,由于本身 D e n s e B l o c k DenseBlock DenseBlock随着深度的不断增加,其输入会不断增多,这样 k k k在不需要设置过高的情况下就可以得到很好的训练效果
请添加图片描述
为了减少计算量, D e n s e B l o c k DenseBlock DenseBlock内部采用bottleneck层减少计算量,即 B N + R e L U + 1 ∗ 1 C o n v + B N + R e L U + 3 ∗ 3 C o n v BN+ReLU+1*1 Conv+BN+ReLU+3*3Conv BN+ReLU+11Conv+BN+ReLU+33Conv,称为 D e n s e N e t − B DenseNet-B DenseNetB结构 ,其中 1 ∗ 1 C o n v 1*1Conv 11Conv可以得到 4 k 4k 4k个特征图,做到了降低特征数量,缩短了计算所需时间
请添加图片描述
对于Transition层,使用两个相邻的DenseBlock,从而降低特征图大小,结构为 B N + R e L U + 1 x 1 C o n v + 2 x 2 A v g P o o l i n g BN+ReLU+1x1 Conv+2x2 AvgPooling BN+ReLU+1x1Conv+2x2AvgPooling,另外,Transition层起到了压缩模型的作用,假定Transition上接 D e n s e B l o c k DenseBlock DenseBlock得到的特征图 c h a n n e l channel channel数为 m m m,使用Transition层产生 θ m \theta m θm个特征(经过卷积层, θ ∈ ( 0 , 1 ] \theta \in(0,1] θ(0,1]是压缩系数,只要 θ < 1 \theta <1 θ<1就相当于对特征个数经过Transition层发生了变化),文章中 θ = 0.5 \theta=0.5 θ=0.5,对于bottleneck层的DenseBlock结构和压缩系数小于1的Transition结构称为DenseNet-BC
论文当中ImageNet数据集所采用的网络配置如下图所示:请添加图片描述

实验结果和讨论

给出了DenseNet在CIFAR-100和ImagetNet数据集上与ResNet的对比结果,如下图,可以看得出来DenseNet的网络性能成功在更小的参数下超越了 ResNet-1001
在这里插入图片描述
在ImageNet数据集上ResNet和DenseNet之间的比较
请添加图片描述
综合来看,DenseNet的优势如下;

  • 由于密集连接方式,DenseNet提升了梯度的反向传播,使得模型更加容易训练,由于每层可以直接到达最后的误差信号,实现了隐式的"deep supervision"
  • 参数更小且计算更高效,这有点违反直觉,由于DenseNet是通过concat特征来实现短路连接,实现了特征重用,并且采用较小的growth rate,每个层所独有的特征图是比较小的
  • 由于特征复用,最后的分类器使用了低级特征

pytorch实现DenseNet

B N + R e L U + 1 x 1 C o n v + B N + R e L U + 3 x 3 C o n v BN+ReLU+1x1 Conv+BN+ReLU+3x3 Conv BN+ReLU+1x1Conv+BN+ReLU+3x3Conv结构

class _DenseLayer(nn.Sequential):
    """Basic unit of DenseBlock (using bottleneck layer) """
    def __init__(self, num_input_features, growth_rate, bn_size, drop_rate):
        super(_DenseLayer, self).__init__()
        self.add_module("norm1", nn.BatchNorm2d(num_input_features))
        self.add_module("relu1", nn.ReLU(inplace=True))
        self.add_module("conv1", nn.Conv2d(num_input_features, bn_size*growth_rate,
                                           kernel_size=1, stride=1, bias=False))
        self.add_module("norm2", nn.BatchNorm2d(bn_size*growth_rate))
        self.add_module("relu2", nn.ReLU(inplace=True))
        self.add_module("conv2", nn.Conv2d(bn_size*growth_rate, growth_rate,
                                           kernel_size=3, stride=1, padding=1, bias=False))
        self.drop_rate = drop_rate

    def forward(self, x):
        new_features = super(_DenseLayer, self).forward(x)
        if self.drop_rate > 0:
            new_features = F.dropout(new_features, p=self.drop_rate, training=self.training)
        return torch.cat([x, new_features], 1)

实现DenseBlock模块,内部是密集连接方式:

class _DenseBlock(nn.Sequential):
    """DenseBlock"""
    def __init__(self, num_layers, num_input_features, bn_size, growth_rate, drop_rate):
        super(_DenseBlock, self).__init__()
        for i in range(num_layers):
            layer = _DenseLayer(num_input_features+i*growth_rate, growth_rate, bn_size,
                                drop_rate)
            self.add_module("denselayer%d" % (i+1,), layer)

Transition层

class _Transition(nn.Sequential):
    """Transition layer between two adjacent DenseBlock"""
    def __init__(self, num_input_feature, num_output_features):
        super(_Transition, self).__init__()
        self.add_module("norm", nn.BatchNorm2d(num_input_feature))
        self.add_module("relu", nn.ReLU(inplace=True))
        self.add_module("conv", nn.Conv2d(num_input_feature, num_output_features,
                                          kernel_size=1, stride=1, bias=False))
        self.add_module("pool", nn.AvgPool2d(2, stride=2))

最后是实现DenseNet网络

class DenseNet(nn.Module):
    "DenseNet-BC model"
    def __init__(self, growth_rate=32, block_config=(6, 12, 24, 16), num_init_features=64,
                 bn_size=4, compression_rate=0.5, drop_rate=0, num_classes=1000):
        """
        :param growth_rate: (int) number of filters used in DenseLayer, `k` in the paper
        :param block_config: (list of 4 ints) number of layers in each DenseBlock
        :param num_init_features: (int) number of filters in the first Conv2d
        :param bn_size: (int) the factor using in the bottleneck layer
        :param compression_rate: (float) the compression rate used in Transition Layer
        :param drop_rate: (float) the drop rate after each DenseLayer
        :param num_classes: (int) number of classes for classification
        """
        super(DenseNet, self).__init__()
        # first Conv2d
        self.features = nn.Sequential(OrderedDict([
            ("conv0", nn.Conv2d(3, num_init_features, kernel_size=7, stride=2, padding=3, bias=False)),
            ("norm0", nn.BatchNorm2d(num_init_features)),
            ("relu0", nn.ReLU(inplace=True)),
            ("pool0", nn.MaxPool2d(3, stride=2, padding=1))
        ]))

        # DenseBlock
        num_features = num_init_features
        for i, num_layers in enumerate(block_config):
            block = _DenseBlock(num_layers, num_features, bn_size, growth_rate, drop_rate)
            self.features.add_module("denseblock%d" % (i + 1), block)
            num_features += num_layers*growth_rate
            if i != len(block_config) - 1:
                transition = _Transition(num_features, int(num_features*compression_rate))
                self.features.add_module("transition%d" % (i + 1), transition)
                num_features = int(num_features * compression_rate)

        # final bn+ReLU
        self.features.add_module("norm5", nn.BatchNorm2d(num_features))
        self.features.add_module("relu5", nn.ReLU(inplace=True))

        # classification layer
        self.classifier = nn.Linear(num_features, num_classes)

        # params initialization
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight)
            elif isinstance(m, nn.BatchNorm2d):
                nn.init.constant_(m.bias, 0)
                nn.init.constant_(m.weight, 1)
            elif isinstance(m, nn.Linear):
                nn.init.constant_(m.bias, 0)

    def forward(self, x):
        features = self.features(x)
        out = F.avg_pool2d(features, 7, stride=1).view(features.size(0), -1)
        out = self.classifier(out)
        return out

选择不同的网络参数可以实现不同深度的DenseNet

def densenet121(pretrained=False, **kwargs):
    """DenseNet121"""
    model = DenseNet(num_init_features=64, growth_rate=32, block_config=(6, 12, 24, 16),
                     **kwargs)

    if pretrained:
        # '.'s are no longer allowed in module names, but pervious _DenseLayer
        # has keys 'norm.1', 'relu.1', 'conv.1', 'norm.2', 'relu.2', 'conv.2'.
        # They are also in the checkpoints in model_urls. This pattern is used
        # to find such keys.
        pattern = re.compile(
            r'^(.*denselayer\d+\.(?:norm|relu|conv))\.((?:[12])\.(?:weight|bias|running_mean|running_var))$')
        state_dict = model_zoo.load_url(model_urls['densenet121'])
        for key in list(state_dict.keys()):
            res = pattern.match(key)
            if res:
                new_key = res.group(1) + res.group(2)
                state_dict[new_key] = state_dict[key]
                del state_dict[key]
        model.load_state_dict(state_dict)
    return model

附录

参考内容连接:
详解DenseNet(密集连接的卷积网络)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/545788.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第一代AIGC硬件悄然爆发

文 | 智能相对论 作者 | 叶远风 看起来&#xff0c;这可能是一副正常的黑框眼镜&#xff0c;你戴上去彬彬有礼、斯斯文文&#xff1b; 实际上&#xff0c;它里边还装了一个“小伙伴”&#xff0c;你随时可以与它交流&#xff0c;谈天说地或者提出各种问题接受它的帮助&#x…

深度学习之构建MPL神经网络——泰坦尼克号乘客的生存分析

大家好&#xff0c;我是带我去滑雪&#xff01; 本期使用泰坦尼克号数据集&#xff0c;该数据集的响应变量为乘客是生存还是死亡&#xff08;survived&#xff0c;其中1表示生存&#xff0c;0表示死亡&#xff09;&#xff0c;特征变量有乘客舱位等级&#xff08;pclass&#x…

广告投放的关键成功因素:广告归因与广告效果监测

在当今竞争激烈的市场环境中&#xff0c;广告归因和广告效果监测成为了广告投放中至关重要的环节。通过深入了解广告归因和广告效果监测的方法&#xff0c;企业可以更好地评估广告投放的成效&#xff0c;并做出精确的决策&#xff0c;以提高广告效果和最大化投资回报。 本文将带…

昆仑万维“勇闯”百模大战:一个“无懈可击”的商业故事话本?

文丨智能相对论 作者丨沈浪 新能源火了做新能源&#xff0c;元宇宙火了做元宇宙。 如果一个热点领域没有昆仑万维的身影&#xff0c;那一定是这个领域还不够“热”&#xff0c;爆不了。 但凡是热到爆的领域&#xff0c;昆仑万维虽迟但到。 不过&#xff0c;这样说可能有些…

【计算机网络基础】章节测试3 数据链路层

文章目录 判断题选择题辨析题应用题 判断题 相对于广域网而言&#xff0c;局域网的误码率较低。√ 交换机是依据IP地址来转发数据包的。 局域网使用集线器作为网络连接设备时&#xff0c;逻辑上是星型结构。 PPP协议应首先满足的需求是简单&#xff0c;以使得协议在实现的时…

Go语言的学习【2】基础语法

目录 代码组成部分字符串格式化字符数据类型变量遇到的问题及解决办法1 代码组成部分 Go 程序可以由多个标记组成&#xff0c;可以是关键字&#xff0c;标识符&#xff0c;常量&#xff0c;字符串&#xff0c;符号。 在 Go 程序中&#xff0c;一行代表一个语句结束。 如果你…

【linux】图文并茂,让你轻松掌握Linux基本指令

目录 一&#xff0c;前提 二&#xff0c; 在root身份下&#xff0c;管理用户 1. 判断身份 2. 创建用户 3. 销毁用户 三&#xff0c;文件增&#xff0c;删&#xff0c;移动指令 1. pwd——查看路径 2. ps ——打开文件目录 3. touch——创建文件 4. nano——打开文件 5.…

【大数据】Presto(Trino)REST API 与执行计划介绍

文章目录 一、概述二、环境准备三、常用 REST API1&#xff09;worker 节点优雅退出2&#xff09;提交SQL查询请求3&#xff09;获取查询状态4&#xff09;获取查询结果5&#xff09;取消查询请求6&#xff09;获取Presto 节点信息7&#xff09;获取Presto服务器使用统计信息8&…

功率放大器电路中的三极管和MOS管,究竟有什么区别?

学习模拟电子技术基础&#xff0c;和电子技术相关领域的朋友&#xff0c;在学习构建功率放大器电路时最常见的电子元器件就是三极管和场效应管&#xff08;MOS管&#xff09;了。那么三极管和MOS管有哪些联系和区别呢&#xff1f;在构建功率放大器电路时我们要怎么选择呢&#…

干货 | 利用SPSS进行高级统计分析第一期

Hello&#xff0c;大家好&#xff01; 这里是壹脑云科研圈&#xff0c;我是喵君姐姐&#xff5e; 你是否还在为分析实验数据而感到头疼&#xff1f;你是否还在苦于自己不知道如何选择合适的模型来分析数据&#xff1f; 本期我们就来为大家带来了利用SPSS软件进行高级统计分析…

【学习日记】在不可联网电脑上安装Python和深度学习环境

测试环境 Hyer-V上开了个虚拟机&#xff0c;win7-64位企业版&#xff0c;全新未安装任何环境的最基本的操作系统。 因为不联网安装&#xff0c;而且是win7这种古老的操作系统&#xff0c;确实会遇到很多问题。做个记录。 安装Python 打开python-3.7.8.exe 安装程序 此时可能…

离岗识别 yolov5模型

离岗识别通过yolov5网络模型技术&#xff0c;离岗识别可以自动识别现场画面中人员离岗脱岗睡岗等行为&#xff0c;发现违规行为立即抓拍告警。YOLOv5在YOLOv4算法的基础上做了进一步的改进&#xff0c;检测性能得到进一步的提升。虽然YOLOv5算法并没有与YOLOv4算法进行性能比较…

Unity3d 开发Pico4程序闪退弹窗【版权保护】检测的解决方法

前言 最近在进行基于Pico4的应用开发&#xff0c;然后在部分设备上程序是无法正常进入的&#xff0c;而且总是弹出这个版权保护的窗口&#xff1a; 按理说正常的自己开发的测试的程序不应该有这种限制&#xff0c;查询后发现是 PICO 内置了版权保护机制。应用上架后&#xff0…

研发工程师玩转Kubernetes——通过文件创建Service

在《研发工程师玩转Kubernetes——部署应用》一文中&#xff0c;我们使用kubectl expose创建了一个Service&#xff0c;暴露了一个Pod上的nginx服务。这篇文章我们将使用文件的形式创建Service。 为了增加有趣性&#xff0c;我们采用《研发工程师玩转Kubernetes——构建、推送自…

与众不同的夜间开关交互效果

这个夜间模式切换开关效果是不是很炫酷&#xff0c;在短视频曾刷到过是一个国外的设计师看似是为了难为我们前端开发设计了一个元素超多且动画复杂的开关切换效果。 结果在逛 codepen 的时候发现真的被一个大佬给做出来了&#xff0c;效果真的很不错&#xff0c;而且还在原来的…

矩池云教程|体验 OpenAI 最近推出的 3D 生成模型 Shap-E!

Shap-E 是由 OpenAI 最近推出的3D生成模型&#xff0c;使用者可以通过简单的文字或图像进行三维模型的生成&#xff0c;OpenAI 认为相比于点云的生成模型Point-E&#xff0c;Shap-E的收敛更快。本文将展示如何在矩池云上体验3D模型生成。 Shap-E&#xff1a;https://github.co…

自动生成测试用例_接口测试用例自动生成工具

前言 写用例之前&#xff0c;我们应该熟悉API的详细信息。建议使用抓包工具Charles或AnyProxy进行抓包。 har2case 我们先来了解一下另一个项目har2case 他的工作原理就是将当前主流的抓包工具和浏览器都支持将抓取得到的数据包导出为标准通用的 HAR 格式&#xff08;HTTP A…

软件测试需要学会写代码吗?

无论是刚入测试行业的萌新&#xff0c;还是已经在测试行业闯荡了两三年的小司机们&#xff0c;都会琢磨一个问题&#xff1a;如果要持续发展下去&#xff0c;我要不要懂代码&#xff1f; 在软件测试初级阶段&#xff0c;不需要编程能力。但是任何一个职业&#xff0c;都会追求…

【网络协议详解】——IPv6协议(学习笔记)

&#x1f4d6; 前言&#xff1a;IPv6 协议是未来互联网的发展方向&#xff0c;它的推出为网络通信和互联带来了更大的便利性和更广阔的发展空间。相比于 IPv4&#xff0c;IPv6 支持更多的地址空间、更高效的路由和唯一的全球性地址等特点&#xff0c;可以更好地满足未来数字化时…

Mac电脑 Vscode : Flutter 开发环境搭建(最细节教程)

参考链接&#xff1a; MacVSCode安装flutter环境_mac vscode配置flutter_GalenWu的博客-CSDN博客 mac搭建Flutter环境以及初始化项目 - 简书 注意&#xff1a; *下载xcode 就包含git了, *苹果芯片和intel 芯片需要的环境不同&#xff0c;苹果芯片需要安装&#xff1a; Im…