当前位置: 首页 > news >正文

卷积神经网络CNN-part9-DenseNet

卷积神经网络CNN-part8-ResNet-CSDN博客

摘要:本文介绍了DenseNet(稠密连接网络)的核心结构和实现方法。DenseNet通过"稠密连接"机制让每层都与前面所有层直接相连,其核心组件包括:1)稠密块(DenseBlock)实现特征重用和特征传播;2)过渡层(transition_block)使用1x1卷积和平均池化控制模型复杂度。文章详细给出了PyTorch实现代码,包括卷积块、稠密块和过渡层的构建方法,并展示了完整的DenseNet模型架构。最后通过Fashion-MNIST数据集验证了模型性能,使用0.05学习率训练10个epoch达到不错效果。相比于ResNet,DenseNet通过特征复用显著提升了参数效率。【AI】

0. 前言

        稠密连接网络(Dense Convolutional Network,简称 DenseNet)是 2017 年由 Huang 等人提出的一种深层卷积神经网络,其核心创新是“稠密连接(Dense Connection)”:网络中的每个层都会与前面所有层直接连接,即第l层的输入是前l-1层的输出的拼接(而非简单相加)。【网络】

        DenseNet在某种程度上师ResNet的逻辑扩展。

1.DenseNet

1.1稠密块(DenseBlock)

         DenseNet使用了ResNet改良版的“批量规范层、激活层和卷积层”架构

import torch
from torch import nn
from d2l import torch as d2l#稠密块体
def conv_block(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_block(num_channels*i+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.2 过渡层

        由于每个稠密块都会带来通道数的增加,因此使用过多会复杂化模型,用过渡层控制模型复杂度。过渡层通过1x1卷积层来减小通道数,并使用步幅为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))

        我们查看过渡层的作用。

blk=transition_block(23,10)
blk(y).shape

        结果:torch.Size([4, 10, 4, 4])

1.3 DenseNet模型

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

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

        DenseNet使用了4个稠密块,每个模块之间,DenseNet使用过渡层来减半高度和宽度,并减半通道。

#num_channels为当前的通道数
num_channels,growth_rate=64,32
num_conv_in_dense_blocks=[4,4,4,4]
blks=[]
for i,num_convs in enumerate(num_conv_in_dense_blocks):blks.append(DenseBlock(num_convs,num_channels,growth_rate))#上一个稠密块的输出通道数num_channels+=num_convs*growth_rate#在稠密块之间添加一个过渡层,使通道数减半if i!=len(num_conv_in_dense_blocks)-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))

2. 训练

#训练模型
lr,num_epochs,batch_size=0.05,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())

http://www.dtcms.com/a/392921.html

相关文章:

  • 深入浅出密码学第一章课后题(持续更新)
  • Mysql 入门概览
  • 大模型中权重共享的作用?
  • 【精品资料鉴赏】55页可编辑PPT详解 数字化高校智慧后勤解决方案
  • LLM大模型 - 实战篇 - AI Agents的开发应用
  • 【分布式技术】RedisShake相关功能详细介绍
  • qsv:一款高性能的CSV数据处理工具
  • `html` 将视频作为背景
  • 口播提词器怎么选?手机提词器实测指南与参数推荐
  • 解剖线性表
  • 计算数学研究方向有哪些细分领域?
  • [xboard]08-Makefile逐行分析2
  • Clash 中 REJECT 的技术原理与解决方案 —— 以哔哩哔哩延迟问题为例
  • 庖丁解牛与专家思维:道家的“心手合一”训练法
  • matlab通过GUI实现点云的读取、自定义显示和保存
  • 工业现场实战:如何利用智能网关实现西门子PLC与库卡机器人的无缝连接
  • 【开题答辩全过程】以 Java程序设计课程作业数据分析为例,包含答辩的问题和答案
  • ubuntu配置cuda与torch
  • C语言:输出水仙花数
  • 进程的创建
  • 如何用Anaconda Navigator和命令行管理Python库?
  • 28 种 LLM 越狱攻击全景拆解(2025.9 版)从“AIM”到“Generation Exploitation”,一张防御地图看懂所有套路
  • 第14章 智能床位
  • 总结一下MySQL数据库服务器性能优化的几个维度
  • IP 打造财富新机遇
  • linux系统如何查看文件位置在数据盘还是系统盘
  • C#关键字 unchecked与checked
  • EasyClick JavaScript 字符串进阶
  • 小明打砖块-算法
  • 【Open3D】在Conda环境下安装Open3D | Anaconda | VSCode