DenseNet - 稠密神经网络(CNN卷积神经网络)

news/2024/5/3 7:29:49/文章来源:https://blog.csdn.net/weixin_43479947/article/details/127262445

文章目录

    • DenseNet - 稠密神经网络
      • 稠密块体
        • 稠密块中的卷积层
        • 稠密块
      • 过渡层
      • DenseNet模型
      • 训练模型
      • 小结

DenseNet - 稠密神经网络

ResNet极大地改变了如何参数化深层网络中函数的观点。 稠密连接网络(DenseNet) [Huang et al., 2017]在某种程度上是ResNet的逻辑扩展。

类似于ResNet神经网络的核心公式: f(x)=g(x)+xf(x) = g(x) + xf(x)=g(x)+x 累加方法突出特征 ,DenseNet神经网络使用的方式则是拼接的方法(cat):

x→[x,f1(x),f2([x,f1(x)]),f3([x,f1(x),f2([x,f1(x)])]),…].\mathbf{x} \to \left[ \mathbf{x}, f_1(\mathbf{x}), f_2([\mathbf{x}, f_1(\mathbf{x})]), f_3([\mathbf{x}, f_1(\mathbf{x}), f_2([\mathbf{x}, f_1(\mathbf{x})])]), \ldots\right].x[x,f1(x),f2([x,f1(x)]),f3([x,f1(x),f2([x,f1(x)])]),].

它们的关系如下图:

在这里插入图片描述

最后,将这些展开式结合到多层感知机中,再次减少特征的数量。

实现起来非常简单:我们不需要添加术语,而是将它们连接起来DenseNet这个名字由变量之间的 “稠密连接” 而得来,最后一层与之前的所有层紧密相连。 稠密连接如下图所示。

在这里插入图片描述

稠密网络主要由2部分构成:稠密块(dense block)和过渡层(transition layer)。 前者定义如何连接输入和输出,而后者则控制通道数量,使其不会太复杂。

稠密块体

引入依赖

import torch
from torch import nn
from d2l import torch as d2l

稠密块中的卷积层

DenseNet使用了ResNet改良版的“批量规范化、激活和卷积”架构。 我们首先实现一下这个架构。

#主要包含三个部分:批量规范化->ReLU激活函数->3*3卷积层,但不改变数据形状
def conv_clock(input_channels, num_channels):return nn.Sequential(nn.BatchNorm2d(input_channels), nn.ReLU(),nn.Conv2d(input_channels, num_channels, kernel_size=3, padding=1))

稠密块

一个稠密块由多个卷积块组成,每个卷积块使用相同数量的输出通道。 然而,在前向传播中,我们将每个卷积块的输入和输出在通道维上连结。

class DenseBlock(nn.Module):def __init__(self, num_convs, input_channels, num_channels):super(DenseBlock, self).__init__()layer = []for i in range(num_convs):layer.append(conv_clock(i * num_channels + input_channels,num_channels))self.net = nn.Sequential(*layer)def forward(self, X):for blk in self.net:Y = blk(X)#连接通道维度上每个块的输入和输出X = torch.cat((X, Y), dim=1)return X

卷积块的通道数控制了输出通道数相对于输入通道数的增长,因此也被称为增长率(growth rate)。

blk = DenseBlock(2, 3, 10)
X = torch.randn(4, 3, 8, 8)
Y = blk(X)
Y.shape
torch.Size([4, 23, 8, 8])

过渡层

由于每个稠密块都会带来通道数的增加,使用过多则会过于复杂化模型。 而过渡层可以用来控制模型复杂度。 它通过 1×11 \times 11×1 卷积层来减小通道数,并使用步幅为 2 的平均汇聚层减半高和宽,从而进一步降低模型复杂度。

def transition_block(input_channels, num_channels):return nn.Sequential(nn.BatchNorm2d(input_channels), nn.ReLU(),nn.Conv2d(input_channels, num_channels, kernel_size=1),nn.AvgPool2d(kernel_size=2, stride=2))                                  #执行平均池化层时,像素大小会减半。

对上一个例子中稠密块的输出使用通道数为10的过渡层。 此时输出的通道数减为10,高和宽均减半。

blk = transition_block(23, 10)
blk(Y).shape
torch.Size([4, 10, 4, 4])

DenseNet模型

我们来构造DenseNet模型。DenseNet首先使用同ResNet一样的单卷积层和最大汇聚层。

b1 = nn.Sequential(nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3),nn.MaxPool2d(kernel_size=3, stride=2, padding=1))

接下来,类似于ResNet使用的4个残差块,DenseNet使用的是4个稠密块。 与ResNet类似,我们可以设置每个稠密块使用多少个卷积层。 这里我们设成4,从而与ResNet-18保持一致。 稠密块里的卷积层通道数(即增长率)设为32,所以每个稠密块将增加128个通道。

在每个模块之间,ResNet通过步幅为2的残差块减小高和宽,DenseNet则使用过渡层来减半高和宽,并减半通道数。

# num_channels 为当前的通道数
num_channels, growth_rate = 64, 32
num_convs_in_dense_block = [4, 4, 4, 4]blks = []for i, num_convs in enumerate(num_convs_in_dense_block):blks.append(DenseBlock(num_convs, num_channels, growth_rate))#上一个稠密块的输出通道数num_channels += num_convs * growth_rate#在稠密块之间添加一个转换层, 使通道数减半if i != len(num_convs_in_dense_block) - 1:blks.append(transition_block(num_channels, num_channels // 2))num_channels = num_channels // 2

定义模型

net = nn.Sequential(b1, *blks, nn.BatchNorm2d(num_channels), nn.ReLU(),nn.AdaptiveAvgPool2d((1,1)), nn.Flatten(),nn.Linear(num_channels, 10))

测试模型的输出形状

X = torch.rand((1, 1, 96, 96))for layer in net:X = layer(X)print(layer.__class__.__name__, 'output shape:\t', X.shape)
Sequential output shape:	 torch.Size([1, 64, 24, 24])
DenseBlock output shape:	 torch.Size([1, 192, 24, 24])
Sequential output shape:	 torch.Size([1, 96, 12, 12])
DenseBlock output shape:	 torch.Size([1, 224, 12, 12])
Sequential output shape:	 torch.Size([1, 112, 6, 6])
DenseBlock output shape:	 torch.Size([1, 240, 6, 6])
Sequential output shape:	 torch.Size([1, 120, 3, 3])
DenseBlock output shape:	 torch.Size([1, 248, 3, 3])
BatchNorm2d output shape:	 torch.Size([1, 248, 3, 3])
ReLU output shape:	 torch.Size([1, 248, 3, 3])
AdaptiveAvgPool2d output shape:	 torch.Size([1, 248, 1, 1])
Flatten output shape:	 torch.Size([1, 248])
Linear output shape:	 torch.Size([1, 10])

训练模型

lr, num_epochs, batch_size = 0.1, 10, 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=96)
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-czsBv42r-1665468421015)(attachment:QQ%E6%88%AA%E5%9B%BE20221009192050.png)]

可以看到,DenseNet神经网络在Fashion-MNIST数据集上迭代10次时较不稳定,训练集准确度为0.948, 测试集准确度为0.765。

迭代次数为20次的训练结果,如下

在这里插入图片描述

可见,训练集准确度为0.978,测试集准确度为0.907。

小结

1.在跨层连接上,不同于ResNet中将输入与输出相加,稠密连接网络(DenseNet)在通道维上连结输入与输出

2.DenseNet的主要构建模块是稠密块和过渡层

3.在构建DenseNet时,我们需要通过添加过渡层来控制网络的维数,从而再次减少通道的数量。

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里巴巴面试题- - -多线程并发篇(四十一)

前言:七月末八月初的时候,秋招正式打响,公司会放出大量的全职和实习岗位。为了帮助秋招的小伙伴们,学长这里整理了一系列的秋招面试题给大家,所以小伙伴们不用太过焦虑,相信你们一定能超常发挥,收到心仪公司的Offer~~ 内容涵盖:Java、MyBatis、ZooKeeper、Dubbo、Elast…

SptingBoot基于Echarts生成折线图,柱状图。看完必会,超详细~~

SptingBoot基于Echarts生成折线图,柱状图前言用到的技术与开源代码1.PhantomJS2.Echartsconvert 开源项目2.SpringBoot实现统计图生成1.pom.xml重要依赖2.图片数据模板3.JAVA代码结尾前言 近期产品团伙给了一个生成PDF数据报的需求,PDF中需要生成折线图…

MySQL死锁排查步骤

系列文章目录 第一章:sql_mode模式 第二章:optimize table、analyze table、alter table、gh-ost 第三章:InnoDB MVCC原理 第四章:sql语句执行过程 第五章:Percona Toolkit工具简介 第六章:MySQL索引 第七…

TRC丨艾美捷TRC 波普瑞韦代谢物 M4说明书

艾美捷TRC 波普瑞韦代谢物 M4—丙型肝炎病毒 NS3 丝氨酸蛋白酶抑制剂 Boceprevir (B675500) 的代谢物。 艾美捷TRC 波普瑞韦代谢物 M4化学性质: 目录号B674520 化学名称波普瑞韦代谢物 M4 同义词(1R,2S,5S)-3-[(2S)-2-[[[[1,1-二甲基乙基]氨基]羰基]氨基]-3,3-二…

【C++笔试强训】第四天

🎇C笔试强训 博客主页:一起去看日落吗分享博主的C刷题日常,大家一起学习博主的能力有限,出现错误希望大家不吝赐教分享给大家一句我很喜欢的话:夜色难免微凉,前方必有曙光 🌞。 💦&a…

【Day28】力扣算法(超详细思路+注释) [1790. 仅执行一次字符串交换能否使两个字符串相等 ] [328. 奇偶链表 ][148. 排序链表]

刷题打卡,第 二十八 天题目一、1790. 仅执行一次字符串交换能否使两个字符串相等题目二、328. 奇偶链表题目三、148. 排序链表题目一、1790. 仅执行一次字符串交换能否使两个字符串相等 原题链接:1790. 仅执行一次字符串交换能否使两个字符串相等 题目…

消息队列的一些思考

前言 像我们Feign进行服务远程调用就会出现上述情况,服务调用是同步的,需要保证整个链路成功执行完才能成功下单,需要考虑网络抖动等影响,还有雪崩的现象——>同步通信会产生不稳定的影响导致用户体验较差 (41条消息) Dubbo_…

【前端笔试之输入输出问题汇总】系列1

1、题目1:涉及到new Array()以及map方面的一些特性 const array new Array(5).map((item) > {return item {name: 1} }) console.log(array)//[empty*5]一般我们认为会输出[name,name,name,name,name]。但是输出的却是empty。 因为new Array(5)生成的数组在每…

CAD导入Revit缺少东西原因-Revit中如何批量导出CAD图纸

一、CAD导入Revit缺少东西原因汇总 在Revit中导入CAD进行模型搭建是建模过程中常用的方法,但是有时会遇到导入的CAD缺少东西的情况,下面介绍几种导致这种问题的原因 1.CAD导入的时候,不是设置为全部可见。 CAD导入Revit中时,“图层…

护眼灯色温多少对眼睛好?推荐色温4000K暖白光的护眼灯

色温就是指温度的颜色,通常人眼所见的光线,由7中色光的光谱所组成,而护眼灯的光源越接近自然光就越好,一般要求色温在4000K左右比较合适,灯光为暖黄光,既温馨有符合相应的亮度,可以起到很好保护…

ROS2在ROS1 的基础的改进点

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录系列文章目录前言一、为什么要推出ROS2【重构ROS1】二、ROS1存在的问题三、ROS1与ROS2架构对比四、ROS2新概念例举五、ROS安装版本(…

【SpringCloud学习笔记】Feign

Feign 的使用 什么是Feign Feign是声明性的web服务客户端。它使编写web服务客户端更加容易,它封装类Ribbon和RestTemplate Feign vs OpenFeign 1、Feign是Netflix公司写的,是SpringCloud组件中的一个轻量级RESTful的HTTP服务客户端,是Spring…

C/C++里危险的宏(Macro)

#define SQUARE(x) x*x 上述宏定义SQUARE(x)用于求“参数”x的平方,这个宏很容易被使用者误认为是函数。宏是由预处理器处理的,它有着函数的形式却没有函数调用的代价。我们不建议初学者使用宏,因为使用宏的收益远不足以抵消其带给初学者的风…

基于本地存储LVM新建虚机方案

文章目录基于本地存储LVM新建虚机方案date: 2021/12/22auth: mmwei3一、环境信息如下:二、需求方案:1、虚机(卷启动)系统盘数据盘 三者在同一计算节点。2、虚机可以挂本计算节点的数据盘也可以挂载其他计算节点的数据盘。3、虚机可以使用本节点上的HDD做…

大数据必学Java基础(七十六):创建线程的三种方式

文章目录 创建线程的三种方式 一、继承Thread类 二、实现Runnable接口 三、实现Callable接口 创建线程的三种方式 一、继承Thread类 在学习多线程之前,以前的代码是单线程的吗? 不是,以前也是有三个线程同时执行的。 现在我想自己制造…

《单元测试》Junit5入门教程——非常详细,入门即精通

本文为在霍格沃兹测试开发学社中学习到的一些技术,写出来分享给大家,希望有志同道合的小伙伴可以一起交流技术,一起进步~ 单元测试-Junit5入门教程一、添加Junit5依赖二、Junit5 常用注解2.1、Test2.2、BeforeAll2.3、AfterAll2.4、BeforeEac…

JavaWeb学习5:Maven

Maven的学习为什么要学习这个技术?在javaweb开发中,需要使用大量的jar包,这种jar包需要手动的导入 如何让一个东西自动导入和配置jar包 所以Maven诞生了maven就是一个架构管理工具 1、Maven项目架构管理工具 Maven的核心思想:约定大于配置,有约束,不要去违反。 Maven会规…

做过的题

菜就多练 主要记录的是 dp 题(因为大部分都不会),还有一些思维题,还有一些 tricks,还有一些模板类的题。 CF533B Work Group 简要题意: 给定一棵树,要求选定一些点加入点集,使得这些点的权值和最大,且对于点集中的任意一个点,其子树中恰有奇数个点(可能包括它本身)…

(附源码)计算机毕业设计SSM基于java的云顶博客系统

(附源码)计算机毕业设计SSM基于java的云顶博客系统 项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技…

easyrecovery数据恢复软件15版本功能介绍

easyrecovery恢复文件介绍 easyrecovery是一款功能非常强大的数据恢复软件,不仅能够恢复手机等终端被删除的文件,还可以恢复从硬盘上删除的文件,而且操作非常简单,下面就跟着小编一起来看一下吧。 easyrecovery可以恢复任何被从…