《Densely Connected Convolutional Networks》论文阅读笔记

DenseNet是一种创新的卷积神经网络结构,旨在解决传统CNN存在的梯度消失、特征重用和参数冗余问题。通过引入密集连接的概念,DenseNet实现了特征的高效传播和重用,减少了参数数量,同时具有较强的正则化效果,有效防止过拟合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文代码: https://github.com/liuzhuang13/DenseNet

pytorch实现 https://github.com/liuzhuang13/DenseNet/tree/master/models

论文动机:在CNN中靠近输入、输出的层之间如果包含更短的连接,则CNN训练时会更高效、更准确;

提出网络:Dense Convolutional Network(DenseNet);L层的传统卷积网络需要L次连接,而DenseNet需要\frac{L(L+1)}{2}次连接;

优点:减轻梯度消失问题;加强特征传播;支持特征重用(feature reuse);减少参数数量(因为不需要重新学习冗余的特征图,尽管这个网络结构是dense connectivity,参数反而大大减少);

Introduction

ResNets、Hightway Networks、FractalNets, they all share a key characteristic: they create short paths from early layers to later layers

下图时DenseNet结构,意义

To ensure maximum information flow between layers in the network, we connect all layers (with matching feature-map sizes) directly with each other. To preserve the feed-forward nature, each layer obtains additional inputs from all preceding layers and passes on its own feature-maps to all subsequent layers.

 

传统的前馈结构可以被看作是具有状态的算法,这个状态在层与层之间传播,每一层接收前面一层传递的状态然后写到下面一层,它改变了状态,但也传递了需要保存的信息。

本文提出的DenseNet结构可以准确区分增加到网络上的信息以及被保存下的信息;同时Dense connections有正则化作用,会在小训练集的任务上减少过拟合的影响;

DenseNets

l{\color{Red} }: 层的索引;

H_{l}(.): 非线性转换,是一个复合操作,比如BN、ReLU、Poolingu哦这Conv;

X_{l}l_{th}层的输出;

------------------------------------

先回忆ResNets:

X_{l}=H_{l}(X_{l-1})+X_{l-1}

优点:梯度可以从后面的层通过恒等函数到达前面的层;

缺点:因为采用加和的方式将恒等函数和H_{l}结合,可能阻碍信息在网络中的传播;   

------------------------------------

Dense connectivity:

X_{l}=H_{l}([X_{0},X_{1},...,X_{l-1}]])

------------------------------------

考虑到特征图尺寸可能由下采样引起的变化,我们将网络分成多个dense blocks,如下图;

transition layers: 是block和block之间的,卷积和池化操作;

Growth rate

每个函数H_{l}产生k个特征图,则l_{th}层有k_{0}+k*(l-1)个输入特征图,k_{0}是输入层的通道数;k就是网络的Growth rate;

------------------------------------

Bottleneck layers:

1X1的卷积在3X3的卷积前作为一个bottleneck layer,可以提高计算效率;

------------------------------------

Compression:

为了进一步提高模型的compactness,我们可以减少过渡层的特征图的数量。

 

相关参考 https://blog.youkuaiyun.com/u012938704/article/details/53468483

https://blog.youkuaiyun.com/u011974639/article/details/78290448

 

### Densely Connected Convolutional Networks (DenseNet) 的架构与实现 #### 架构解释 DenseNet 是一种密集连接的卷积神经网络,其核心思想在于通过层间的密集连接来增强特征重用并减少冗余参数。在传统卷积网络中,每一层仅与其相邻的一层相连;而在 DenseNet 中,每层不仅接受前一层的输入,还接受之前所有层的输出作为额外输入[^3]。 这种设计使得 DenseNet 能够显著降低模型复杂度和计算成本,因为各层无需重复学习相同的特征图。具体而言,DenseNet 将每一层的输出视为全局状态的一部分,并允许后续层访问这些状态。因此,最终分类器能够利用整个网络中的所有特征图进行预测[^5]。 #### 实现方法 以下是 DenseNet 的基本构建单元及其 Python 实现: 1. **Dense Block**: 密集块由多个卷积层组成,其中每一层都将自身的输出与其他层的输出拼接在一起。 2. **Transition Layer**: 这些层用于控制特征图的数量以及缩小图像尺寸,通常包括批量归一化(Batch Normalization)、ReLU 和平均池化操作。 下面是基于 PyTorch 的简单实现示例: ```python import torch.nn as nn import torch class Bottleneck(nn.Module): """Bottleneck 层""" def __init__(self, in_channels, growth_rate): super(Bottleneck, self).__init__() inter_channel = 4 * growth_rate self.bn1 = nn.BatchNorm2d(in_channels) self.conv1 = nn.Conv2d(in_channels, inter_channel, kernel_size=1, bias=False) self.relu = nn.ReLU(inplace=True) self.bn2 = nn.BatchNorm2d(inter_channel) self.conv2 = nn.Conv2d(inter_channel, growth_rate, kernel_size=3, padding=1, bias=False) def forward(self, x): out = self.conv1(self.relu(self.bn1(x))) out = self.conv2(self.relu(self.bn2(out))) out = torch.cat((x, out), dim=1) # 特征图拼接 return out class Transition(nn.Module): """过渡层""" def __init__(self, in_channels, out_channels): super(Transition, self).__init__() self.bn = nn.BatchNorm2d(in_channels) self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=1, bias=False) self.avg_pool = nn.AvgPool2d(kernel_size=2, stride=2) def forward(self, x): out = self.conv(self.bn(x)) out = self.avg_pool(out) return out class DenseNet(nn.Module): """DenseNet 主体结构""" def __init__(self, num_init_features, growth_rate, block_config, num_classes=1000): super(DenseNet, self).__init__() self.features = nn.Sequential( nn.Conv2d(3, num_init_features, kernel_size=7, stride=2, padding=3, bias=False), nn.BatchNorm2d(num_init_features), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=3, stride=2, padding=1) ) num_features = num_init_features for i, num_layers in enumerate(block_config): dense_block = self._make_dense_block(growth_rate, num_layers, num_features) self.features.add_module(f"denseblock{i + 1}", dense_block) num_features += num_layers * growth_rate if i != len(block_config) - 1: trans_layer = Transition(num_features, num_features // 2) self.features.add_module(f"transition{i + 1}", trans_layer) num_features //= 2 self.classifier = nn.Linear(num_features, num_classes) def _make_dense_block(self, growth_rate, n_layers, input_channels): layers = [] for _ in range(n_layers): layers.append(Bottleneck(input_channels, growth_rate)) input_channels += growth_rate return nn.Sequential(*layers) def forward(self, x): features = self.features(x) out = nn.functional.adaptive_avg_pool2d(features, (1, 1)) out = torch.flatten(out, 1) out = self.classifier(out) return out ``` 上述代码定义了一个基础版本的 DenseNet 模型,其中包括瓶颈层(`Bottleneck`)和过渡层(`Transition`)。通过调整 `growth_rate` 和 `block_config` 参数,可以灵活配置不同的 DenseNet 变种。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值