跳转至

第5讲 深度学习(二)

一、深度学习中的优化方法

深度学习的优化不仅取决于梯度公式,还取决于参数怎样初始化、选择什么优化器,以及网络结构、学习率、小批量大小和正则化系数等超参数怎样设置。

模型参数初始化

若多层网络的所有权值都初始化为同一个固定值,同层神经元会产生相同输出并得到相同梯度,训练后仍保持相同,无法学出不同特征。偏置不承担这种打破对称性的任务,一般可统一初始化为 0。采用 ReLU 时,也可把偏置设成 \(0.01\) 之类的小正数,使神经元在训练初期更容易激活并得到反向梯度。

最常见的随机初始化来自正态分布 \(N(\mu,\sigma^2)\) 或均匀分布。随机变量在 \([a,b]\) 上均匀分布时,方差为

\[ \operatorname{Var}(x)=\frac{(b-a)^2}{12}. \]

因此在 \([-r,r]\) 上均匀分布时,

\[ \operatorname{Var}(x)=\frac{r^2}{3}. \]

初始化尺度不能随意选。对

\[ y=\sum_{i=1}^{d}w_ix_i+b, \]

若各变量独立、均值为 0 且 \(b=0\),则

\[ \sigma_y^2=d\sigma_w^2\sigma_x^2. \]

若希望前向传播前后方差保持不变,应令 \(d\sigma_w^2=1\),即

\[ \sigma_w^2=\frac{1}{d}. \]

相应地,权值可初始化为

\[ w\sim N\left(0,\frac{1}{d}\right) \]

\[ w\sim U\left(-\sqrt{\frac{3}{d}},\sqrt{\frac{3}{d}}\right). \]

Xavier 初始化适合关于原点对称的激活函数,如 tanh。第 \(l-1\) 层和第 \(l\) 层的节点数分别为 \(d_{l-1}\)\(d_l\) 时,前向方差守恒希望 \(\sigma_w^2=1/d_{l-1}\),反向梯度方差守恒希望 \(\sigma_w^2=1/d_l\),折中取

\[ \sigma_w^2=\frac{2}{d_{l-1}+d_l}. \]

于是可用

\[ w\sim N\left(0,\frac{2}{d_{l-1}+d_l}\right) \]

\[ w\sim U\left(-\sqrt{\frac{6}{d_{l-1}+d_l}},\sqrt{\frac{6}{d_{l-1}+d_l}}\right). \]

He 初始化适合 ReLU。由于约有一半神经元不被激活,输出方差近似为

\[ \sigma_y^2=\frac{d}{2}\sigma_w^2\sigma_x^2, \]

故应取

\[ \sigma_w^2=\frac{2}{d}. \]

权值可初始化为

\[ w\sim N\left(0,\frac{2}{d}\right) \]

\[ w\sim U\left(-\sqrt{\frac{6}{d}},\sqrt{\frac{6}{d}}\right). \]

预训练初始化有两种思路。早期做法是把大模型拆成小网络,分别预训练后再组合;现在更常见的是直接用大规模数据训练好的模型参数初始化当前任务。

随机梯度下降与学习率

随机梯度下降 SGD 的参数更新为

\[ \theta_t=\theta_{t-1}-\eta\nabla_\theta L_t(\theta). \]

\(g_t=\nabla_\theta L_t(\theta)\),则

\[ \Delta\theta_t=\theta_t-\theta_{t-1}=-\eta g_t. \]

学习率决定每一步走多远。课件用一层隐藏层、32 个节点、ReLU 的网络比较 SGD:训练 1000 轮时,学习率 \(0.3\) 的损失为 \(0.158\),学习率 \(0.05\) 的损失为 \(0.258\)。固定学习率 \(0.01\) 时,1000 轮损失为 \(0.281\),增加到 5000 轮后降至 \(0.166\)。学习率和训练轮数需要配合,过小的学习率可能只是收敛得更慢。

动量法

动量法利用上一次参数调整量,使更新方向更稳定:

\[ \Delta\theta_t=\rho\Delta\theta_{t-1}-\eta g_t. \]

展开后可看作历次负梯度的指数加权和:

\[ \Delta\theta_t=-\eta\sum_{\tau=1}^{t}\rho^{t-\tau}g_\tau. \]

\(\rho\) 是动量因子,通常取 \(0.9\)。它会削弱相互抵消的摆动方向,并在梯度方向持续一致时积累速度。

RMSProp

RMSProp 用指数衰减累计梯度平方,并据此自适应调整各参数的有效学习率:

\[ h_t\leftarrow\alpha h_{t-1}+(1-\alpha)g_t\odot g_t, \]
\[ W_t\leftarrow W_{t-1}-\eta\frac{g_t}{\sqrt{h_t}}. \]

梯度较小时,\(1/\sqrt{h_t}\) 较大,可适当放大更新;梯度较大时,该因子较小,可约束更新幅度。

Adam

Adam 把动量和自适应学习率结合起来。它先估计梯度的一阶矩和二阶矩:

\[ m_t=\beta_1m_{t-1}+(1-\beta_1)g_t, \]
\[ v_t=\beta_2v_{t-1}+(1-\beta_2)g_t^2, \]

其中 \(m_0=v_0=0\)。为修正初始阶段向 0 偏移的问题,作偏差校正:

\[ \hat{m}_t=\frac{m_t}{1-\beta_1^t}, \qquad \hat{v}_t=\frac{v_t}{1-\beta_2^t}. \]

参数更新为

\[ \theta_t=\theta_{t-1}-\eta\frac{\hat{m}_t}{\sqrt{\hat{v}_t}+\varepsilon}. \]

常用默认值是 \(\eta=0.001\)\(\beta_1=0.9\)\(\beta_2=0.999\)\(\varepsilon=10^{-8}\),其中 \(\varepsilon\) 防止分母为 0。

课件第 16 页把更新式排成 \(\sqrt{\hat v_t+\varepsilon}\),即把 \(\varepsilon\) 放在根号内;标准 Adam 公式如上,把它放在根号外。两者数值上都用于稳定分母,但实现时应以所用优化器的定义为准。

在同一个一层 32 节点 ReLU 网络上,分段调整 SGD 学习率:第 1 至 500 轮取 \(0.3\),第 501 至 900 轮取 \(0.05\),第 901 至 1000 轮取 \(0.01\),最终损失为 \(0.053\);Adam 以学习率 \(0.03\) 训练 1000 轮,损失为 \(0.000\)。这说明优化器和学习率共同决定训练轨迹,不能脱离具体任务简单比较。

超参数与学习率调整

常见超参数分三类:网络结构参数,包括连接关系、层数、每层节点数和激活函数;优化参数,包括优化方法、学习率和 batch size;正则化参数,包括各类正则化系数。

学习率可采用衰减、预热或周期性调整。逐渐预热设预热迭代数为 \(T'\)、目标初始学习率为 \(\eta_0\),在预热阶段取

\[ \eta_t=\frac{t}{T'}\eta_0, \qquad 1\leq t\leq T'. \]

预热结束后再选一种衰减方法逐渐降低学习率;周期性策略则让学习率在给定范围内往复变化。

二、深度学习中的正则化方法

过拟合时,模型把训练样本的偶然细节也拟合进去,训练误差很小但泛化较差。正则化的两条主线是控制模型复杂度和改进数据利用方式。前者包括 \(L_1/L_2\) 范数约束、权值衰减和 Dropout;后者包括提前停止和数据增强。

范数约束

以多项式

\[ f(x)=w_0+w_1x+w_2x^2+\cdots+w_nx^n \]

为例,若高次项系数 \(w_3,w_4,w_5\) 等都很小,高次模型就近似退化为低次模型。因此限制参数大小能够降低有效复杂度。加入正则项后的目标函数为

\[ \operatorname{Loss}'(\theta)=\operatorname{Loss}(\theta)+\lambda L'(\theta), \]

其中 \(\lambda\) 是正则化系数,\(L'(\theta)\) 可取 \(L_2\) 范数平方或 \(L_1\) 范数。

\(n\) 维向量 \(x\)\(p\) 范数定义为

\[ \lVert x\rVert_p=\left(\sum_{i=1}^{n}|x_i|^p\right)^{1/p}. \]

几个常用特例是

\[ \lVert x\rVert_1=\sum_{i=1}^{n}|x_i|, \qquad \lVert x\rVert_2=\sqrt{\sum_{i=1}^{n}x_i^2}, \]
\[ \lVert x\rVert_\infty=\max_i|x_i|, \qquad \lVert x\rVert_0=\#\{i:x_i\neq0\}. \]

\(L_2\) 等值线平滑,倾向于让参数整体变小;\(L_1\) 约束域有尖角,目标函数等高线与它相切时更容易落在坐标轴上,因此会使部分参数恰好为 0。

课件仍用一层隐藏层、32 个 ReLU 节点、Adam 学习率 \(0.03\)、训练 1000 轮比较 \(L_2\) 系数。系数为 0 时损失为 \(0.000\)\(10^{-4}\) 时为 \(0.012\)\(10^{-3}\) 时为 \(0.107\)\(5\times10^{-3}\) 时为 \(0.276\)。约束过强会限制模型对训练数据的拟合。

权值衰减

权值衰减在每次更新时直接缩小旧参数:

\[ \theta_t=(1-\lambda)\theta_{t-1}-\eta g_t. \]

它也可写成

\[ \theta_t=\theta_{t-1}-\left(\eta g_t+\lambda\theta_{t-1}\right). \]

在标准 SGD 中,适当对应系数后,权值衰减与 \(L_2\) 约束效果相同;在 Adam 等更复杂的自适应优化器中,两者并不等价。

Dropout

Dropout 在训练的每次迭代中,以给定概率把各层节点的激活值随机置 0。不同子网络轮流参与训练,能减弱神经元之间的过度依赖。

在相同的一层 32 节点 ReLU 网络上,Dropout 概率为 0 时损失为 \(0.000\);概率为 \(0.1\) 时为 \(0.028\);概率为 \(0.5\) 时为 \(0.210\);概率为 \(0.9\) 时为 \(0.602\)。丢弃概率太大时,可用的网络容量明显不足。

提前停止

提前停止在训练过程中持续用验证集检查模型。如果验证错误或验证损失不再下降,就停止迭代并保留验证性能最好的参数。

场景英文字符识别例使用一层 32 节点隐藏层、ReLU、Adam 学习率 \(0.03\),原计划训练 1000 轮,并在“字符”和“背景”两类中各加入两幅验证图像。不使用提前停止时,训练 1000 轮后训练损失为 \(0.000\),验证损失却为 \(1.420\),且发生分类错误;验证损失在第 194 轮达到最小。若在第 194 轮停止,训练损失为 \(0.259\),验证损失只有 \(0.040\)。训练集上的拟合不再继续改善,却换来了更好的泛化。

数据增强

图像数据增强通过变换已有图像增加数据多样性,包括随机旋转、水平或竖直翻转、放大或缩小、水平或竖直平移,以及加入随机噪声。增强方式应保留任务标签所代表的语义。

三、典型卷积神经网络架构

架构演进

卷积网络的发展延续了视觉系统的层级处理思想。Fukushima 在 1980 年提出 Neocognitron,依据 Hubel 和 Wiesel 对视觉皮层功能的划分设计简单、复杂和超复杂神经元,用多层结构学习特征。LeCun 等人在 1989 至 1998 年间提出 LeNet,用深度卷积网络识别手写数字。2012 年 AlexNet 结合 GPU、ImageNet 百万量级数据和深层网络,带来图像分类突破。2014 年 VGGNet 用连续 \(3\times3\) 卷积代替 \(5\times5\)\(7\times7\) 大卷积核。2015 年 GoogLeNet 引入 Inception 并用 \(1\times1\) 卷积降维。2016 年 ResNet 用残差连接缓解深层网络的信息传递问题,获 CVPR 最佳论文。2017 年 DenseNet 让前层输出在后续层中重用,也获 CVPR 最佳论文。

后续网络进一步引入注意力和自适应结构。SENet 在 2018 年引入通道注意力;SKNet 在 2019 年通过类似通道选择的机制,自适应调节每层感受野;Non-local Network 在 2018 年、GCNet 在 2019 年用自注意力方式聚合远距离或全局上下文。

LeNet

课件中的经典 LeNet 结构为:C1 使用 \(5\times5\) 卷积,输出 \(6\times28\times28\);S2 下采样到 \(6\times14\times14\);C3 采用局部组合,输出 \(16\times10\times10\);S4 下采样得到 16 个 \(5\times5\) 特征图;C5 用 120 个 \(5\times5\) 卷积核把 \(16\times5\times5\) 映射为 \(120\times1\times1\);F6 为全连接层。课件第 42 页把 C5 标成“\(1\times1\) 卷积”,这是把输出空间尺寸误当成了核尺寸。输出层由径向基函数 RBF 单元组成,每个单元计算输入向量与自身参数向量的欧氏距离,距离越大,RBF 单元的输出越大。

AlexNet

AlexNet 有五个卷积层和三个全连接层,采用 ReLU、局部响应归一化、数据增强和 Dropout,并以双 GPU 并行训练 ImageNet 百万量级数据。输入 RGB 图像归一化为 \(227\times227\times3\),简化后的逐层结构是:

输出尺寸 配置
Conv1 \(55\times55\times96\) 96 个 \(11\times11\) 核,步幅 4,填充 0
Pool1 \(27\times27\times96\) \(3\times3\) 最大池化,步幅 2
Norm1 \(27\times27\times96\) 局部响应归一化
Conv2 \(27\times27\times256\) 256 个 \(5\times5\) 核,步幅 1,填充 2
Pool2 \(13\times13\times256\) \(3\times3\) 最大池化,步幅 2
Norm2 \(13\times13\times256\) 局部响应归一化
Conv3 \(13\times13\times384\) 384 个 \(3\times3\) 核,步幅 1,填充 1
Conv4 \(13\times13\times384\) 384 个 \(3\times3\) 核,步幅 1,填充 1
Conv5 \(13\times13\times256\) 256 个 \(3\times3\) 核,步幅 1,填充 1
Pool3 \(6\times6\times256\) \(3\times3\) 最大池化,步幅 2
FC6、FC7、FC8 \(4096,4096,1000\) 前两层用 ReLU,最后输出 1000 类

第一层输出边长的计算为

\[ \frac{227-11}{4}+1=55, \]

其权值参数量为

\[ (11\times11\times3)\times96\approx35\text{K}. \]

第一个池化层的输出边长为

\[ \frac{55-3}{2}+1=27. \]

原始双 GPU 设计把第二层写成 \(256=128\times2\)\(5\times5\times48\) 核,第三层为 \(384=192\times2\)\(3\times3\times256\) 核,第四层为 \(384=192\times2\)\(3\times3\times192\) 核,第五层为 \(256=128\times2\)\(3\times3\times192\) 核。第三、四、五个卷积层之间不再插入局部归一化和池化层。

各层量级也说明了计算和存储分别集中在哪里。五个卷积层参数量约为 \(35\)K、\(307\)K、\(884\)K、\(1.3\)M、\(442\)K,对应计算量约为 \(105\)M、\(223\)M、\(149\)M、\(112\)M、\(74\)M FLOPs;三个全连接层参数量约为 \(37\)M、\(16\)M、\(4\)M。卷积层计算量大,全连接层则占去大量参数。课件还可视化了第一层卷积核系数和第四层部分特征图,说明学习到的滤波器与中间响应都可以直接观察;PyTorch 的 torchvision 也提供了 AlexNet 模型定义。

这里还存在分组口径差异。按原始双 GPU 的 Conv4,每个 GPU 有 192 个 \(3\times3\times192\) 核,总参数量约为

\[ 2\times192\times3\times3\times192\approx664\text{K}. \]

课件汇总表中的约 \(1.3\)M 则相当于不分组、让 384 个输出通道都连接 384 个输入通道,即 \(384\times3\times3\times384\)。两项不能在同一口径下同时成立,应把它们分别理解为分组版与非分组版。

VGGNet

VGGNet 把卷积核固定为 \(3\times3\),通过连续堆叠模拟大感受野。两个 \(3\times3\) 卷积等效感受野为 \(5\times5\),三个则为 \(7\times7\)。若输入、输出通道均为 \(C\),三个 \(3\times3\) 卷积需要 \(27C^2\) 个权值,小于一个 \(7\times7\) 卷积的 \(49C^2\),而且多了两次非线性变换。

典型版本是 VGG16 和 VGG19。两者都用卷积块逐步增加通道数,并在块间最大池化,末端都有三层全连接。VGG16 的主要尺寸与参数为:

阶段 输出尺寸 单层权值参数量
输入 \(224\times224\times3\) 0
Conv3-64,2 层 \(224\times224\times64\) 1728;36864
Pool2 \(112\times112\times64\) 0
Conv3-128,2 层 \(112\times112\times128\) 73728;147456
Pool2 \(56\times56\times128\) 0
Conv3-256,3 层 \(56\times56\times256\) 294912;589824;589824
Pool2 \(28\times28\times256\) 0
Conv3-512,3 层 \(28\times28\times512\) 1179648;2359296;2359296
Pool2 \(14\times14\times512\) 0
Conv3-512,3 层 \(14\times14\times512\) 每层 2359296
Pool2 \(7\times7\times512\) 0
FC-4096 4096 102760448
FC-4096 4096 16777216
FC-1000 1000 4096000

全网约有 \(138\)M 参数。首层输入含约 \(150\)K 个数据,首个 64 通道特征图已有约 \(3.2\)M 个数据;随着池化继续,空间数据量下降,而后部全连接层成为参数主体。

GoogLeNet 与 Inception

Inception 模块并行使用 \(1\times1\)\(3\times3\)\(5\times5\) 卷积和 \(3\times3\) 池化,再沿通道维合并各分支输出。它同时观察多个尺度,拓宽了网络并提高尺度适应性。

若输入为 \(28\times28\times256\),四条直接分支分别输出 128、192、96 和 256 个通道,合并后为

\[ 28\times28\times(128+192+96+256)=28\times28\times672. \]

不计池化分支,三个卷积分支的乘法量为

\[ \begin{aligned} N_{1\times1}&=28\times28\times128\times1\times1\times256,\\ N_{3\times3}&=28\times28\times192\times3\times3\times256,\\ N_{5\times5}&=28\times28\times96\times5\times5\times256, \end{aligned} \]

合计 \(854{,}196{,}224\approx854\text{M}\)。为降低计算量,可在 \(3\times3\)\(5\times5\) 卷积前增加 \(1\times1\) 降维卷积,并在最大池化后增加 \(1\times1\) 卷积。课件示例中,两条大核分支先各降到 64 通道,直接 \(1\times1\) 分支输出 128 通道,池化投影输出 64 通道,最终合并为

\[ 28\times28\times(128+192+96+64)=28\times28\times480, \]

课件列出的六项运算量为

\[ \begin{aligned} &28\times28\times64\times1\times1\times256\quad(\text{两次}),\\ &28\times28\times128\times1\times1\times256,\\ &28\times28\times192\times3\times3\times64,\\ &28\times28\times96\times5\times5\times64,\\ &28\times28\times64\times1\times1\times256. \end{aligned} \]

课件页末标为 \(358\)M,但把上面六项实际相加得到 \(271{,}351{,}808\approx271\)M;这是课件数值的不一致。无论采用哪一数值,都能看出 \(1\times1\) 卷积显著降低了大核卷积的计算量,它既可降维,也可升维。

Inception-V2 加入 BN,并用两个 \(3\times3\) 卷积代替 \(5\times5\) 卷积以减少参数;Inception-V3 通过卷积分解增加非线性;Inception-V4 融合残差网络的设计思想。GoogLeNet 还使用辅助损失层,帮助中间层得到训练信号,缓解梯度消失。

ResNet

普通网络加深后可能出现信息传递受阻。ResNet 加入快捷连接,把输入作为参照,只让权值层学习残差:

\[ H(x)=F(x)+x. \]

残差函数通常比直接学习完整映射更容易优化,因此网络可以加得更深。跨越多层时,课件写作

\[ x_L=x_l+\sum_{i=l}^{L-1}F(x_i). \]

相应梯度为

\[ \frac{\partial E}{\partial x_l}=\frac{\partial E}{\partial x_L}\left(1+\frac{\partial}{\partial x_l}\sum_{i=l}^{L-1}F(x_i)\right). \]

其中恒等通路贡献的 1 让梯度可以直接向浅层传播。典型网络有 ResNet-34、ResNet-50、ResNet-101 和 ResNet-152。

DenseNet

DenseNet 让每一层接收前面所有层的输出。若网络有 \(L\) 层,连接总数为

\[ \frac{L(L+1)}{2}. \]

稠密连接尽量缩短前层与后层之间的信息路径,最大化信息流动,缓解梯度消失,强化特征传播和特征重用,并可减少参数量。

轻量网络与架构搜索

MobileNet 的基本单元是深度可分离卷积:先用 depthwise convolution 对不同输入通道分别卷积,再用 pointwise convolution,也就是 \(1\times1\) 卷积,汇聚通道信息。

ShuffleNet 使用分组卷积降低计算,但普通分组会使某些输出通道只依赖固定的一组输入通道。channel shuffle 在组间重排通道,让信息跨组流动,改善全局信息不畅和表达能力不足的问题。

神经网络架构搜索 NAS 自动寻找网络结构。课件中的 NASNet 用强化学习搜索可迁移的 Normal Cell 和 Reduction Cell,再把搜索到的单元扩展到大规模图像识别网络。

四、卷积神经网络的应用

媒体内容分析任务

计算机视觉任务可按“物体是什么”和“物体在哪里”来区分。图像分类给出整幅图像的类别,没有空间位置信息;语义分割给每个像素分类,但不区分同类物体的不同实例;图像生成依据指定类别或条件产生图像;目标检测同时给出多个物体的类别和位置框;实例分割还要为每个物体实例给出像素级区域。自动驾驶场景理解往往同时需要图像分割、目标检测、识别和跟踪。

图像分类的挑战与流程

开放环境中的图像分类面对光照、视角、尺度和前景变化,以及背景干扰、遮挡等问题,需要学习对这些变化较稳定的不变特征。机器学习通常假设训练集与测试集来自相同统计分布,但实际环境可能偏离这一假设,因此还要提升模型的泛化能力。

改进图像分类有三条路径:网络结构上使用更深的 ResNet,或更复杂的 Spatial Transformer Network、SENet;目标函数上使用对比学习,如 Triplet Loss;训练策略上采用数据增强和迁移学习。

CIFAR-10 编程例的十类是 plane、car、bird、cat、deer、dog、frog、horse、ship、truck。PyTorch 实现分五步:

  1. 准备训练集和测试集。
  2. 设计由卷积层、池化层、全连接层和激活函数组成的 CNN。
  3. 确定损失函数和优化方法。
  4. 在训练集上作 mini-batch 训练,学习网络参数。
  5. 在测试集上推断并统计准确率。

课件使用的关键配置如下,训练集随机打乱,测试集不打乱:

transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
])
trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4, shuffle=True, num_workers=2)
testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=4, shuffle=False, num_workers=2)

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 16 * 5 * 5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        return self.fc3(x)

net = Net()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

训练两轮,每批依次执行 zero_grad、前向计算、交叉熵、backwardstep,每 2000 个 mini-batch 打印一次平均损失。课件记录的第 1 轮损失为 \(2.191,1.863,1.664,1.581,1.520,1.493\),第 2 轮为 \(1.433,1.406,1.373,1.340,1.308,1.314\),分别对应 2000 至 12000 批。测试示例的四个预测依次是 catshipshipship;教程入口是 https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html

ResNet 的不同配置

ResNet-18 和 ResNet-34 使用 Basic Block,每个块含两个 \(3\times3\) 卷积;ResNet-50、101、152 使用 Bottleneck Block,以 \(1\times1\) 降维、\(3\times3\) 处理、\(1\times1\) 升维。各配置先经过 \(7\times7\)、64 通道、步幅 2 的卷积,输出 \(112\times112\),再经 \(3\times3\)、步幅 2 的最大池化。随后结构为:

阶段与输出尺寸 ResNet-18 ResNet-34 ResNet-50 ResNet-101 ResNet-152
conv2_x,\(56\times56\) \([3\times3,64;3\times3,64]\times2\) 同左 \(\times3\) \([1\times1,64;3\times3,64;1\times1,256]\times3\) 同左 \(\times3\) 同左 \(\times3\)
conv3_x,\(28\times28\) \([3\times3,128;3\times3,128]\times2\) 同左 \(\times4\) \([1\times1,128;3\times3,128;1\times1,512]\times4\) 同左 \(\times4\) 同左 \(\times8\)
conv4_x,\(14\times14\) \([3\times3,256;3\times3,256]\times2\) 同左 \(\times6\) \([1\times1,256;3\times3,256;1\times1,1024]\times6\) 同左 \(\times23\) 同左 \(\times36\)
conv5_x,\(7\times7\) \([3\times3,512;3\times3,512]\times2\) 同左 \(\times3\) \([1\times1,512;3\times3,512;1\times1,2048]\times3\) 同左 \(\times3\) 同左 \(\times3\)

最后使用全局平均池化、1000 类全连接层和 Softmax。五种网络的计算量约为 \(1.8\)\(3.6\)\(3.8\)\(7.6\)\(11.3\) billion FLOPs。

通道注意力 SENet

SENet 为每个特征通道学习一个权系数。SE Block 先通过全局平均池化把每个通道压缩为一个数,即 squeeze;再经两层全连接、中间 ReLU 和末端 Sigmoid 得到通道权值,即 excitation;最后把权值乘回原特征图。把 SE Block 嵌入残差块即可得到 SE-ResNet Block。

Triplet Loss

三元组由锚点样本 \(x_i^a\)、同类正样本 \(x_i^p\) 和异类负样本 \(x_i^n\) 组成。目标是让锚点与正样本的距离比锚点与负样本的距离至少小一个间隔 \(\alpha\)

\[ \left\lVert f(x_i^a)-f(x_i^p)\right\rVert_2^2+\alpha<\left\lVert f(x_i^a)-f(x_i^n)\right\rVert_2^2. \]

对应损失为

\[ L=\sum_i\left[\left\lVert f(x_i^a)-f(x_i^p)\right\rVert_2^2-\left\lVert f(x_i^a)-f(x_i^n)\right\rVert_2^2+\alpha\right]_+. \]

它直接约束嵌入空间中的相对距离,可用于人脸识别与聚类等对比学习任务。

迁移学习

迁移学习先在标记样本充足的源域预训练,再把模型迁移到标记样本较少的目标域。预训练模型可以从随机初始化开始,在 ImageNet 等大数据集上从头训练。迁移到目标任务时,用预训练参数初始化网络,并按目标类别数重设最后一个全连接层。训练有两种方式:对整个卷积网络作 fine-tune;或把卷积层当作固定特征提取器,只训练新全连接层。

课件的两类分类代码以预训练 ResNet-18 为例:把原网络全部参数的 requires_grad 设为 False,冻结卷积层;将最后一层替换为两输出的线性层;使用交叉熵,只把新全连接层参数交给 SGD,学习率 \(0.001\)、动量 \(0.9\);学习率调度器每 7 轮乘 \(0.1\)

图像语义分割与全卷积网络

传统图像分割依据颜色、纹理等把图像划成同质区域;语义分割则依据语义单元,为人、车等类别产生像素级区域。全卷积网络 FCN 用卷积替代固定尺寸的全连接层,先下采样提取高层特征,再逐步上采样恢复到输入分辨率。课件图中,\(3\times H\times W\) 输入经编码器得到 \(D_1\times H/2\times W/2\)\(D_2\times H/4\times W/4\)\(D_3\times H/8\times W/8\) 特征,再在解码过程中恢复并融合相应尺度信息,最终输出 \(H\times W\) 的预测。

U-Net 采用对称的编码器—解码器:左侧卷积与下采样提取语义,右侧上采样恢复空间尺寸,并通过跳跃连接把编码端同尺度的高分辨率特征送到解码端。这样可同时利用定位细节和深层语义,最初用于生物医学图像分割。

上采样与转置卷积

增大卷积步幅或增加池化层可以下采样。恢复空间尺寸有几种方法:最近邻上采样直接重复元素,例如把 \(2\times2\) 复制为 \(4\times4\);“bed of nails”把原元素放到稀疏位置,其余位置补 0;最大反池化保存前向最大池化时每个最大值的位置,上采样时把数值放回这些位置,其他位置置 0。

\(A=\begin{bmatrix}1&2\\3&4\end{bmatrix}\),前两种固定上采样分别得到

\[ A_{\mathrm{nn}}=\begin{bmatrix}1&1&2&2\\1&1&2&2\\3&3&4&4\\3&3&4&4\end{bmatrix},\qquad A_{\mathrm{bon}}=\begin{bmatrix}1&0&2&0\\0&0&0&0\\3&0&4&0\\0&0&0&0\end{bmatrix}. \]

最大反池化例中,输入

\[ \begin{bmatrix}1&2&6&3\\3&5&2&1\\1&2&2&1\\7&3&4&8\end{bmatrix} \]

\(2\times2\) 最大池化得到

\[ \begin{bmatrix}5&6\\7&8\end{bmatrix}, \]

保存最大值位置后,反池化恢复为

\[ \begin{bmatrix}0&0&6&0\\0&5&0&0\\0&0&0&0\\7&0&0&8\end{bmatrix}. \]

这些固定方法没有可学习参数。转置卷积则能学习上采样核。若普通卷积展开成矩阵乘法

\[ w*x=Wx, \]

转置卷积使用同一连接关系的转置矩阵:

\[ w^T*x=W^Tx. \]

转置卷积不是普通卷积的数值逆运算,而是普通卷积对应线性变换的转置,也与反向传播中对卷积输入求梯度的运算相同。卷积矩阵中会重复利用卷积核系数;若换一种展开方式,也可看见图像数据在滑动窗口中被重复利用。

一维卷积的矩阵形式为

\[ \begin{bmatrix}w_1&w_2&w_3&0&0&0\\0&0&w_1&w_2&w_3&0\end{bmatrix}\begin{bmatrix}0\\x_1\\x_2\\x_3\\x_4\\0\end{bmatrix}=\begin{bmatrix}w_2x_1+w_3x_2\\w_1x_2+w_2x_3+w_3x_4\end{bmatrix}. \]

相应的转置线性变换为

\[ \begin{bmatrix}w_1&0\\w_2&0\\w_3&w_1\\0&w_2\\0&w_3\\0&0\end{bmatrix}\begin{bmatrix}x_1\\x_2\end{bmatrix}=\begin{bmatrix}w_1x_1\\w_2x_1\\w_3x_1+w_1x_2\\w_2x_2\\w_3x_2\\0\end{bmatrix}. \]

二维例中,\(4\times4\) 输入与 \(2\times2\) 卷积核作步幅为 2 的卷积,输出 \(2\times2\)。展开后普通卷积矩阵大小为 \(4\times16\),而转置卷积使用 \(16\times4\) 的转置矩阵,把四个输入位置的贡献分配回 16 个输出位置。计算步幅大于 1 的转置卷积时,可在输入相邻行、列间插入 \(S-1\) 个 0,再用步幅 1 卷积。

\(2\times2\) 核写成 \(\begin{bmatrix}w_1&w_2\\w_3&w_4\end{bmatrix}\),按行展开输入时,步幅 2 的普通卷积矩阵为

\[ W_c=\begin{bmatrix}w_1&w_2&0&0&w_3&w_4&0&0&0&0&0&0&0&0&0&0\\0&0&w_1&w_2&0&0&w_3&w_4&0&0&0&0&0&0&0&0\\0&0&0&0&0&0&0&0&w_1&w_2&0&0&w_3&w_4&0&0\\0&0&0&0&0&0&0&0&0&0&w_1&w_2&0&0&w_3&w_4\end{bmatrix}_{4\times16}. \]

普通卷积是 \(z=W_cx\),转置卷积则用 \(x'=W_c^Tz\)。等价的图像操作是:在 \(2\times2\)\(Z\) 周围及相邻元素间补零形成 \(5\times5\),把核旋转 \(180^\circ\),把步幅改成 1 后再卷积。

转置卷积的输出高度为

\[ H_{\mathrm{out}}=(H_{\mathrm{in}}-1)S-2P+D(K-1)+\operatorname{output\_padding}+1. \]

课件的二维数值流程使用 \(3\times3\) 输入、\(3\times3\) 核、步幅 2、填充 1。先在相邻行列间各插入一个 0,边长由 3 变为

\[ 3+(3-1)(2-1)=5. \]

按转置卷积的边界补齐后,计算图边长为 7;再以步幅 1 做 \(3\times3\) 卷积,输出边长为

\[ \frac{7-3}{1}+1=5. \]

因此转置卷积实现了参数可学习的特征图上采样。

思考与探究

  1. 编程比较 Dropout 和权值衰减。如果同时使用,两者的收益会简单累加、减弱,还是彼此抵消?
  2. 如果把 Dropout 施加在隐藏层节点的权值参数上,而不是节点激活值上,会发生什么?
  3. 不同深度 ResNet 的部分结构含 \(1\times1\) 卷积,这一设计的主要目的是什么?
  4. 按课件所示把卷积展开成完整矩阵乘法,是否是高效实现?为什么?

评论