一、网络中的网络 (NiN: Network in Network)
参考:Network In Network——卷积神经网络的革新 - 殷大侠 - 博客园
深度学习(二十六)Network In Network学习笔记-CSDN博客
- ① MLPconv 层
参考:深度学习基础模型NIN(Network in Network)+Pytorch
- ② 全局平均池化层(Global Average Pooling, GAP)
参考:通俗易懂理解全局平均池化(GAP)-CSDN博客
二、含并行连接的网络 (GoogLeNet)
参考:深入理解GoogLeNet结构(原创)
- ① Inception块(Inception block)
GoogLeNet 中的 Inception 块由四条并行路径组成。前 3 条路径分别采用 1×1、3×3 和 5×5 的卷积核,从不同的空间尺度提取特征。中间的 2 条路径在主卷积操作前引入 1×1 卷积,用于降低通道数,从而减少计算量和模型复杂度。第 4 条路径先进行 3×3 最大池化,再通过 1×1 卷积调整通道数。所有路径均采用适当的填充策略,以保持输入与输出在空间尺寸上的一致。最终,将四条路径的输出在通道维度上进行拼接,形成 Inception 块的输出。
Inception 块中通常需要调节的超参数是各分支中卷积层的输出通道数。
总结:
-
Inception 块本质上是一个包含四条并行路径的子网络,通过不同尺寸的卷积核和最大池化操作并行提取不同尺度的特征。路径中引入的 1×1 卷积用于在像素级别上压缩通道维度,从而有效降低模型的计算复杂度。
-
GoogLeNet 通过将多个结构精巧的 Inception 块与卷积层、全连接层串联构建深层网络结构。其中,各分支通道数的分配比例是在 ImageNet 数据集上经过大量实验调优得到的,以实现计算效率与模型性能之间的良好平衡。
-
GoogLeNet 及其后续版本曾是 ImageNet 挑战中最具竞争力的模型之一,在显著降低计算成本的同时仍保持了接近甚至优于同类模型的分类精度。
三、批量归一化 (bn: Batch Normalization)
参考:神经网络中的 BN(Batch Normalization)层意义何在
Batch Normalization详解以及pytorch实验_pytorch batch normalization-CSDN博客
下图展示了一个batch size为2(两张图片)的Batch Normalization的计算过程:
BN 示例代码:
其中 滑动平均值参考 BN/Batch Norm中的滑动平均/移动平均/Moving Average
def batch_norm(X, gamma, beta, moving_mean, moving_var, eps, momentum):"""实现批量归一化(Batch Normalization)。在训练模式下,使用当前 mini-batch 的均值和方差对输入进行归一化,并更新全局的移动平均均值和方差;在预测模式下,使用训练阶段保存的全局均值和方差。Parameters----------X : torch.Tensor输入张量,形状为 (batch_size, features)(用于全连接层)或(batch_size, channels, height, width)(用于卷积层)。gamma : torch.Tensor缩放参数,形状与特征维度或通道数匹配。beta : torch.Tensor平移参数,形状与特征维度或通道数匹配。moving_mean : torch.Tensor当前的移动平均均值,用于预测阶段。moving_var : torch.Tensor当前的移动平均方差,用于预测阶段。eps : float用于数值稳定性的微小常数,防止除以零。momentum : float用于更新移动平均的动量参数,常取值 0.9 或 0.99。Returns-------Y : torch.Tensor批量归一化后的输出张量,与输入形状相同。updated_moving_mean : torch.Tensor更新后的移动平均均值,脱离计算图。updated_moving_var : torch.Tensor更新后的移动平均方差,脱离计算图。"""if not torch.is_grad_enabled():# 预测模式:使用移动平均统计量X_hat = (X - moving_mean) / torch.sqrt(moving_var + eps)else:assert len(X.shape) in (2, 4)if len(X.shape) == 2:# 全连接层:在特征维上计算均值和方差mean = X.mean(dim=0)var = ((X - mean) ** 2).mean(dim=0)else:# 卷积层:在通道维上计算均值和方差mean = X.mean(dim=(0, 2, 3), keepdim=True)var = ((X - mean) ** 2).mean(dim=(0, 2, 3), keepdim=True)# 使用当前 batch 的统计量进行标准化X_hat = (X - mean) / torch.sqrt(var + eps)# 更新全局移动平均统计量moving_mean = momentum * moving_mean + (1.0 - momentum) * meanmoving_var = momentum * moving_var + (1.0 - momentum) * var# 应用缩放和平移Y = gamma * X_hat + betareturn Y, moving_mean.data, moving_var.data
PyTorch 中的 BN :
- 全连接层
class BatchNorm1d(_BatchNorm):r"""对小批量 1D 输入应用批量归一化(Batch Normalization)。适用于输入维度为 (N, C) 或 (N, C, L) 的张量,常用于全连接层或 1D 卷积后的输出。在训练过程中,该层会根据当前批次计算均值和方差;在评估(推理)模式下,使用累计的移动平均均值与方差。数学表达式如下:y = (x - E[x]) / sqrt(Var[x] + eps) * gamma + beta其中:- E[x] 为均值- Var[x] 为方差- gamma 和 beta 是可学习参数,用于缩放和平移参数:num_features (int): 输入特征的维度 C。eps (float): 为了数值稳定性添加到分母中的值,默认 1e-5。momentum (float): 用于更新运行均值和方差的动量,默认 0.1。affine (bool): 若为 True,则该模块包含可学习的缩放参数 gamma 和偏移参数 beta,默认 True。track_running_stats (bool): 若为 True,将跟踪运行时的均值和方差;否则仅使用当前批次统计量,默认 True。输入:- shape: (N, C) 或 (N, C, L)输出:- shape: (N, C) 或 (N, C, L)(与输入相同)示例::>>> bn = nn.BatchNorm1d(128)>>> x = torch.randn(32, 128)>>> y = bn(x)"""
- 卷积层
class BatchNorm2d(_BatchNorm):r"""对小批量 4D 输入应用批量归一化(Batch Normalization)。适用于输入维度为 (N, C, H, W) 的张量,常用于 2D 卷积层之后的特征图归一化。数学表达式如下:y = (x - E[x]) / sqrt(Var[x] + eps) * gamma + beta在训练时计算每个通道的均值和方差,并进行标准化;在评估模式下使用移动平均的均值与方差。参数:num_features (int): 输入特征图的通道数 C。eps (float): 为了数值稳定性添加到分母中的值,默认 1e-5。momentum (float): 用于更新运行均值和方差的动量,默认 0.1。affine (bool): 若为 True,该模块包含可学习参数 gamma 和 beta,默认 True。track_running_stats (bool): 若为 True,将记录并使用运行均值和方差,默认 True。输入:- shape: (N, C, H, W)输出:- shape: (N, C, H, W)示例::>>> bn = nn.BatchNorm2d(64)>>> x = torch.randn(8, 64, 32, 32)>>> y = bn(x)"""
四、残差网络 (RessNet)
参考:ResNet及其变种的结构梳理、有效性分析与代码解读
ResNet网络结构详解与模型的搭建_resnet模型结构-CSDN博客
ResNet18 网络结构
残差网络的核心思想是:每个附加层都应该更容易地包含原始函数作为其元素之一。源于嵌套函数( nested function )的思路。
-
我们希望神经网络中的某些层至少能做到什么都不改变(即恒等映射
);
-
但传统结构中,神经网络并不容易学会这种恒等映射,因为层层变换和激活函数会“扭曲”输入;
-
而残差结构通过引入跳跃连接(skip connection),天然地包含了恒等映射作为可能的输出形式;
-
如果需要改变输入,它可以通过残差函数
做微调;如果不需要改变输入,它只要让
即可。
也就是说,残差结构为网络增加了一个“保守的选择”:最坏的情况它可以什么都不做。
ResNet 设计要求:
①要求2个卷积层的输出与输入形状一样,从而使它们可以相加。
②如果想改变输出的通道数和分辨率(H*W),就需要引入一个额外的1×1卷积层来将输入变换成需要的形状后再做相加运算。
五、稠密连接网络 (DenseNet)
参考:DenseNet:比ResNet更优的CNN模型
稠密网络主要由2部分构成:稠密块(dense block)和过渡层(transition layer)。 前者定义如何连接输入和输出,而后者则控制通道数量,使网络不会太复杂。
- 一个稠密块由多个卷积块组成,每个卷积块使用相同数量的输出通道。 在前向传播中,我们将每个卷积块的输入和输出在通道维度上连接。
- 由于每个稠密块都会带来通道数的增加,使用过多则会过于复杂化模型。 而过渡层可以用来控制模型复杂度。 它通过1×1卷积层来减小通道数,并使用步幅为2的平均池化层减半高度和宽度,从而进一步降低模型复杂度。
注意这里的操作:Sum(相加)操作 和 Concat(拼接)操作
✅ 1. Sum(相加)操作
全称:element-wise sum,中文:逐元素相加。
作用:将两个形状完全相同的特征图,按元素相加。
举例:
假设有两个张量:
-
A
的 shape 是[N, C, H, W]
-
B
的 shape 是[N, C, H, W]
使用 sum
操作后:
C = A + B # 逐元素相加
C.shape = [N, C, H, W]
使用场景:
-
ResNet 中的残差连接(residual connection)
-
模型融合时的加权
-
参数少、计算量小
✅ 2. Concat(拼接)操作
全称:concatenation,中文:拼接。
作用:将两个特征图在通道维度(channel)上进行拼接。
举例:
假设有两个张量:
-
A
的 shape 是[N, C1, H, W]
-
B
的 shape 是[N, C2, H, W]
使用 concat
操作后:
C = concat(A, B, dim=1) # 在通道维度上拼接
C.shape = [N, C1 + C2, H, W]
使用场景:
- DenseNet 中跨层特征堆叠
- U-Net 中 encoder 和 decoder 特征图的拼接
-
提高表达能力(保留两个输入的全部信息)