不考代码, 记得带计算器
考试题目很多,覆盖面很广,解答题每一小问分值很小,11-14章的内容基本只考选择题
还考了两道画图题,画LSTM与Transformer的结构图,务必记牢
解答题重点考察计算图,梯度传播计算,BN与LN,显存、感受野、参数量等计算,RNN的演化与架构,Transformer架构与关知识点等等
以下内容均为老师在复习课上提及的可能会考的重点内容。
02 线性分类器 #
1️⃣ 图像分类 #
图像分类是最核心的计算机视觉任务
语义鸿沟:人眼能看到猫的图像,但计算机看到的是由0-255的整数组成的矩阵
挑战:视角差异、光照变化、杂乱背景、遮挡、形变、类内差异、类间相似、语义干扰
图像分类器无法硬编码,会过拟合
数据驱动的图像分类任务:(1)收集图像和标签的数据集;(2)使用机器学习算法训练分类器;(3)使用分类器对新图像进行分类
2️⃣ K-NN 最近邻分类器 #
KNN 做法:记住所有数据和标签,将测试图像预测为与其最相似的训练图像的标签
距离度量
时间复杂度
1近邻产生的问题:离群点无法很好地分类
为什么有白色区域:白色区域内最近的k个点对应k个不同类
不要直接使用像素间的距离进行度量!像素间的距离度量的泛化性和稳定性都很差!
3️⃣ 线性分类器 #
线性分类器定义、公式、形状
一般挂载在神经网络之后,即模型的最后一层
如何理解线性分类器(代数视角(矩阵乘法),视觉视角(学到模板进行匹配),几何视角(超平面划分空间))
线性分类器难以处理的情况:线性不可分
低维不可分,高维可分,映射到高维空间,依然可以进行线性分类
非线性变换
SVM损失(hinge loss):
\[ L_i = \sum_{j \ne y_i} \max(0, s_j - s_{y_i} + 1) \]正确类别分数:\(s_{y_i}\)




损失函数的一些问题:
多类别 SVM loss 通过 margin 约束强制正确类别分数高于所有错误类别;
训练初期由于权重很小,所有样本 loss 近似为常数C-1;
hinge loss 线性惩罚违反 margin 的情况,而 squared hinge 对大错误惩罚更强;
求和时必须排除正确类别,否则只会引入无意义的常数项。
Softmax Loss:
\[ P(Y=k|X=x_i) = \frac{e^{s_k}}{\sum_j e^{s_j}} \]\[ L_i = -\log P(Y = y_i \mid X = x_i) \]Softmax 损失的最小值为 0,当模型以概率 1 预测正确类别;其最大值趋于正无穷,当正确类别概率趋于 0。在参数初始化时,由于各类别得分近似相等,Softmax 输出为均匀分布,此时单样本损失为 log C。由于 Softmax Loss 是连续可微函数,预测得分的微小扰动只会引起损失的平滑变化,从而提供稳定的梯度信号。
03 正则化与优化 #
1️⃣ 正则化 #
W不是独一无二的
为什么有正则化:避免模型过拟合训练数据
正则化公式:
\[ L(W) = \frac{1}{N} \sum_{i=1}^{N} L_i(f(x_i, W), y_i) + \lambda R(W) \]正则化特点:偏好简单的模型,降低模型对训练数据的过拟合,降低训练噪声对模型的影响
奥卡姆剃刀:如无必要,勿增实体
L2正则化:
\[ R(W)=\sum_{k,l} W_{k,l}^2 \]惩罚大的权重, 让权重整体变小,但很少精确变成 0
L1正则化:
\[ R(W)=\sum_{k,l} |W_{k,l}| \]鼓励很多权重 直接变成 0、 自动做“特征选择”
Elastic Net(L1 + L2):
\[ R(W)=\sum_{k,l} \big(\beta W_{k,l}^2 + |W_{k,l}|\big) \]为什么 Dropout / BN 也算正则化: 限制模型的有效容量
Dropout:训练时随机“删神经元”,防止神经元之间过度共适应,等价于训练大量子模型的 ensemble,强正则化
Batch Normalization:虽然主要是为了训练稳定,但mini-batch 统计量带噪声,实际上也起到了正则化作用,弱正则化 + 加速训练
Stochastic Depth / Fractional Pooling:本质是人为引入随机性, 让模型不能依赖某一条固定路径
在训练目标中引入正则化项可以限制模型参数规模,从而降低模型复杂度,防止过拟合。常见的 L2 正则化通过惩罚权重平方使模型更加平滑,而 L1 正则化则鼓励参数稀疏。正则化强度由超参数 λ 控制,需要通过验证集调节。此外,Dropout、Batch Normalization 等方法虽然未显式加入损失函数,但通过引入随机性或约束模型表达能力,也起到了正则化作用。
为什么正则化:表达对模型参数的偏好,使模型简单,使其适用于测试数据,改进模型优化
2️⃣ 模型优化 #
梯度方向:函数值最大增长的方向
梯度值:函数在这个方向上的增长率
梯度下降:对于每个维度,沿着该维度的梯度的相反方向更新模型参数,更新的幅度与梯度大小有关
\[ W \leftarrow W - \alpha \nabla L(W) \]数值法梯度计算:计算慢,近似,但易于实现
解析法:快速,准确,但实现较为复杂
梯度检查:使用解析法计算梯度,使用数值法检查梯度
随机梯度下降(Stochastic Gradient Descent, SGD):

考虑计算资源和成本,使用小批量样本计算
SGD 问题1: 如果损失在一个方向上变化很快,在另一个方向变化很慢怎么办?梯度下降法会怎样表现?
沿 w1 方向下降非常缓慢,沿 w2 方向抖动

我们并不总是朝着全局最优点进行优化,当前的最陡方向并不总是最优的方向
SGD 问题 2:局部最优 vs 鞍点
局部最优值:
此处梯度为 0,理论上可怕(非凸损失函数),实际上,随着网络参数量的增加,这个问题的影响会很小,因为对于大型网络,局部最优值通常与全局最优值很接近
Hessian矩阵的特征值全部大于0
鞍点:
鞍点处的梯度很小(或为 0 ),跳出鞍点需要很长时间
神经网络的 loss landscape 中的大多数关键点都是鞍点
Hessian矩阵的特征值有正也有负
SGD + Momentum:将连续梯度平均在一起似乎会产生更好的方向!
\[ \begin{aligned}v_{t+1} &= \rho v_t + \nabla f(x_t) \\x_{t+1} &= x_t - \alpha v_{t+1}\end{aligned} \]rho 一般为 0.9 或 0.99
Momentum 通过累积历史梯度方向,
抑制震荡、加速一致方向更新,
从而更快通过鞍点、在窄谷中高效下降。
RMSProp (Root Mean Squared Propagation):对每个维度的梯度大小进行“归一化”
\[ G_{t,i} = \rho G_{t-1,i} + (1-\rho)\,(\nabla_i L_t)^2 \]\[ x_{t+1,i}=x_{t,i}-\frac{\alpha}{\sqrt{G_{t,i}} + \epsilon}\;\nabla_i L_t \]RMSProp 通过对每个参数维度维护梯度平方的指数滑动平均,对梯度进行归一化缩放,从而在陡峭方向减小步长、在平缓方向增大步长,显著改善 SGD 在病态曲率下的收敛速度与稳定性。
AdaGrad (Adaptive Gradient Algorithm)
\[ G_t = \sum_{\tau=1}^t g_\tau^2 \]\[ x_{t+1} = x_t - \frac{\alpha}{\sqrt{G_t} + \epsilon} g_t \]AdaGrad 使用所有历史梯度平方累积来缩放学习率,
导致学习率单调下降,适合凸优化与稀疏特征;
RMSProp 使用指数衰减的梯度平方平均,避免学习率过早衰减,
更适合深度学习中的非凸优化。
提示
关于AdaGrad为什么适用于稀疏特征:
AdaGrad 在每个维度有一个“历史记账本”,稀疏特征的\(G_t\)几乎不涨,所以当它终于出现时,更新步子会很大
Adam
\[ m_t = \beta_1 m_{t-1} + (1-\beta_1) g_t \]\[ v_t = \beta_2 v_{t-1} + (1-\beta_2) g_t^2 \]\[ \hat m_t = \frac{m_t}{1-\beta_1^t}, \quad\hat v_t = \frac{v_t}{1-\beta_2^t} \]\[ x_{t+1}=x_t-\alpha\frac{\hat m_t}{\sqrt{\hat v_t} + \epsilon} \]beta1 = 0.9;beta2 = 0.999;epsilon = 1e-8
提示
关于为什么要做Bias Correction #
初始化时\(m_0 = 0\),\(v_0 = 0\)
如果没有偏置修正,第一步时\(m_1 ≈ 0.1 g\),\(v_1 ≈ 0.001 g^2\)
此时第一步的更新大小,几乎和梯度大小无关了!导致“数值失真”问题
做了偏置修正后,第一步的\(m̂₁ ≈ g\),\(v̂₁ ≈ g²\),变为正常的梯度更新
因此Bias Correction 不是为了“提高精度”,而是为了“防止前几步更新完全不对”。
提示
关于为什么AdamW要在最后加上Weight Decay #
先看标准Adam,其在loss上加入了L2正则,实际上就是想起一个weight decay的作用。
但是由于L2正则加在损失函数上,\(\lambda w\)(L2正则的梯度)被Adam一起进行了缩放,正则强度变成“因参数而异、随时间变化”。
而AdamW将Weight Decay放到了Adam的自适应变化外面,使正则化强度统一,训练更稳定,并且有更好的泛化效果。
x -= lr * first_unbias / (sqrt(second_unbias) + eps) # Adam步
x -= lr * weight_decay * x # 衰减步学习率:训练前期 lr 大 → 后期逐渐变小
- Step Learning Rate:训练固定的 epoch 之后,降低学习率,常乘以0.1
- Cosine Learning Rate:\(\alpha_t = \frac{1}{2}\alpha_0 \left(1 + \cos\left(\frac{t\pi}{T}\right)\right)\),最常用
- Linear Learning Rate:\(\alpha_t = \alpha_0 \left(1 - \frac{t}{T}\right)\)
- Inverse Learning Rate(反比衰减):\(\alpha_t = \frac{\alpha_0}{\sqrt{t}}\)
Warmup: 高初始学习率会使损失激增。前5000 次迭代中,从 0 开始线性增加学习率可以防止这种情况
经验法则: 如果将批处理大小增加N,则初始学习率也按N缩放(因为梯度估计更稳定,可以走更大的步子而不震荡,batch size × N → lr 也 × N)
04 神经网络与反向传播 #
1️⃣ 神经网络 #
为什么我们需要非线性?
多层神经网络若不包含非线性激活函数,其整体仍等价于单一线性变换,无法提升模型表达能力;激活函数通过引入非线性,使网络能够学习复杂的非线性决策边界。
激活函数:
Sigmiod:
\[ \sigma(x)=\frac{1}{1+e^{-x}} \]\[ \frac{\partial \sigma(x)}{\partial x} = \sigma(x) \left(1 - \sigma(x)\right) \]有梯度消失和非零中心的问题,现在常用于二分类输出层

Tanh:
\[ \tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} \]具有零中心但是两端仍然存在梯度消失问题,现在深层网络基本不用,但有时在RNN/门控结构里还能见到

ReLU:
\[ \text{ReLU}(x)=\max(0,x) \]不会饱和,计算便宜且产生稀疏激活,但是输出不以0为中心,且存在Dying ReLU的问题,现在是CNN / MLP 隐藏层默认首选

Leaky ReLU:
\[ \max(0.1x,\;x) \]解决了Dying ReLU,但表达略复杂,GAN中比较常见

PReLU:
\[ f(x)=\max(\alpha x,x) \]α 是可学习参数(这么多激活函数中只有这一个是可学习参数),比 Leaky ReLU 更灵活,但是多一个参数
ELU:
\[ \text{ELU}(x)=\begin{cases}x,& x\ge0 \\\alpha(e^x-1),& x\lt 0\end{cases} \]具备ReLU的所有优点,但计算开销较高

SELU:
\[ f(x)= \begin{cases} \lambda x, & x\gt 0 \\ \lambda\alpha(e^x-1), & x\le 0 \end{cases} \]ELU 的扩展版本,更适合深度网络,具有“自我规范”属性,可以在没有BN的情况下训练深度网络
α,λ 是精心计算的常数,不是随便取的
SELU 不是随便就能用的,必须满足:LeCun Normal 初始化,不能随便加 BN,Dropout 要用 AlphaDropout

MaxOut:
\[ \text{MaxOut}(x)=\max(w_1^Tx+b_1,\;w_2^Tx+b_2) \]非线性,具有Leaky ReLU的优点,不会饱和,梯度不会为0,但是参数数量翻倍
GELU:
\[ \text{GELU}(x)=x\cdot \Phi(x) \]\[ \phi(x) = \frac{1}{\sqrt{2\pi}} e^{-x^2/2} \]\[ \Phi(x) = \int_{-\infty}^{x} \phi(t)\,dt \]从负无穷到 x,正态分布曲线下面的面积

在 0 附近连续可导, 梯度更平滑,非常适合 Transformer,但计算更复杂,较大的负值处梯度为 0
激活函数输出以 0 为中心,可以让反向传播时梯度在各维度正负均衡,减少参数更新的 zig-zag 现象,使优化路径更直接,从而加快模型收敛。

更多的神经元带来更大的模型容量,更大的神经网络使用更强的正则化进行约束
2️⃣ 反向传播 ⭐️ #

提示
计算图和反向传播推导示例: #
梯度流中的基本计算模式:

向量的导数:
- Scalar → Scalar:
- Vector → Scalar:
- Vector → Vector:
dL/dx 的形状永远和 x 一样
不要显式计算雅可比矩阵,因为其太稀疏、太大,逐元素乘法等价,使用隐式计算即可
推导出的矩阵乘法层在反向传播时的梯度:
\[ \boxed{\begin{aligned}y &= xW \\\frac{\partial L}{\partial x} &= \frac{\partial L}{\partial y}\, W^\top \\\frac{\partial L}{\partial W} &= x^\top \frac{\partial L}{\partial y}\end{aligned}} \]05 卷积神经网络 #
全连接层:参数量大,没有空间信息

卷积层:
3x32x32图像:保持图像的空间结构









卷积神经网络由一系列卷积层组成:

线性分类器学到了什么:每个类别学到的是一张“模板图像”
第 k 类对应一行 \(W_k\),把 \(W_k\) reshape 成图像,就得到:“如果输入长得像这张图 → 分数就高”

全连接神经网络学到了什么:每个隐层神经元 = 一张“原型模板”

卷积神经网络(CNN)学到了什么:
| 层数 | 学到的东西 |
|---|---|
| Layer 1 | 边缘、颜色 |
| Layer 2 | 角点、简单纹理 |
| Layer 3 | 局部部件(眼睛、轮子) |
| Layer 4 | 物体局部组合 |
| Layer 5 | 高级语义(狗脸、车头) |

卷积的计算:
\[ \boxed{\text{输出尺寸}= \frac{N + 2P - K}{S} + 1} \]\[ H_{\text{out}} = \left\lfloor \frac{H_{\text{in}} + 2P - K}{S} \right\rfloor + 1 \]\[ W_{\text{out}} = \left\lfloor \frac{W_{\text{in}} + 2P - K}{S} \right\rfloor + 1 \]N:输入尺寸
S:步长
K:滤波器大小
P:padding 大小(每边)
为了保持空间尺寸不变:
步长:
S = 1Padding:
常见情况:
\[ \boxed{P = \frac{F - 1}{2}} \]| 滤波器 F | Padding P |
|---|---|
| 3×3 | 1 |
| 5×5 | 2 |
| 7×7 | 3 |
多输入通道卷积:


一个卷积核的参数量 = F × F × 输入通道数 + 1(bias)
提示
感受野很重要,怎么计算,要计算不同步长下的,审题要注意是在前一层上的感受野,还是在输入图上的感受野
对于核大小为K的卷积,输出中的每个元素都取决于输入中的K x K感受野:




感受野的计算公式:
\[ l_k \;=\; l_{k-1} + (f_k - 1)\cdot \prod_{i=1}^{k-1} s_i \]| 符号 | 含义 |
|---|---|
| \(l_k\) | 第 k 层在输入图像上的感受野大小 |
| \(f_k\) | 第 k 层的 kernel size |
| \(s_i\) | 第 i 层的 stride |
| \(\prod s_i\) | 前面所有 stride 的累计放大效应 |
卷积层通过逐层叠加扩大感受野,下采样通过 stride 放大感受野增长速度,二者配合让高层特征既“看得远”,又“算得动”。
提示
卷积层总结:
全连接层: 每个神经元都“看”整个输入,但是有参数爆炸、不利用图像的局部性的问题
卷积层:从局部开始,用共享权重逐层扩大感受野,这是“更像视觉皮层”的建模方式
池化层:使特征更小,更易于处理,独立操作每个激活图
最大池化(Max Pooling):

提示
池化层总结:
卷积神经网络总结:
- 卷积层+池化层+全连层+激活函数
- 趋向于更小的滤波器和更深的层
- 趋向于舍弃池化层和全连接层
- 以往常见的卷积网络架构:[(Conv-ReLU)*N-Pooling]*M-(FC-ReLU)*K-Softmax
N一般为
5,M较大,K一般在02 - 新型卷积网络(ResNet,GoogLeNet)提出了新的架构
\(1 \times 1\) 卷积主要作用:特征图通道的变化,增加非线性,计算量和参数量最低,对每个像素位置做一次全连接
3D卷积、转置卷积、空洞卷积、分组卷积、可分离、可变性卷积
| 卷积类型 | 核心解决的问题 | 一句话理解 |
|---|---|---|
| 1×1 卷积 | 通道变换 / 非线性 | 只在“通道维度”上做计算 |
| 3D 卷积 | 时序 / 体数据 | 在“空间 + 时间”一起卷 |
| 转置卷积 | 上采样 | 学出来的上采样 |
| 空洞卷积(Dilated) | 扩大感受野不降分辨率 | 卷积核“插空” |
| 分组卷积(Group) | 降计算量 | 通道分组,各算各的 |
| 深度可分离卷积 | 极致降计算 | 空间卷 + 通道卷分开 |
| 可变形卷积 | 形变建模 | 卷积位置是“学出来的” |
06 卷积神经网络架构 #
1️⃣ 归一化层 #
提示
Batch Normalization(批归一化层)
输入不以零为中心(有较大的偏置)、输入的每个元素具有不同的缩放比例会导致网络难以优化,解决方案是对输入进行缩放(归一化)
训练阶段:
\[ x \in \mathbb{R}^{N \times D} \]\[ \mu_j^{(B)}=\frac{1}{N}\sum_{i=1}^{N}x_{i,j} \]\[ (\sigma_j^{2})^{(B)}=\frac{1}{N}\sum_{i=1}^{N}(x_{i,j}-\mu_j^{(B)})^2 \]\[ \hat{x}_{i,j}=\frac{x_{i,j}-\mu_j^{(B)}}{\sqrt{(\sigma_j^{2})^{(B)}+\varepsilon}} \]上标 (B) 表示Batch(当前 mini-batch)统计量。
问题:归一化后的输入丢失了大量数据信息(均值、方差)
因此引入可学习参数:
\[ \gamma,\ \beta \in \mathbb{R}^D \]并做仿射变换:
\[ y_{i,j} = \gamma_j \hat{x}_{i,j} + \beta_j \]BN 不是“强制把数据变成标准正态”,
而是“先标准化,再让网络自己决定要不要变回去”
BN 不会限制模型表达能力
训练时BN还会维护:
- running mean:\(\mu^{(R)}\)
- running var:\((\sigma^2)^{(R)}\)
用指数滑动平均(EMA)更新(PyTorch 中 momentum 默认 0.1):
\[ \mu^{(R)} \leftarrow (1-m)\mu^{(R)} + m\mu^{(B)} \]\[ (\sigma^2)^{(R)} \leftarrow (1-m)(\sigma^2)^{(R)} + m(\sigma^2)^{(B)} \]把很多 batch 的统计量“平均”起来,得到更稳定的全局估计
测试阶段:
\[ \hat{x}_{i,j}=\frac{x_{i,j}-\mu_j^{(R)}}{\sqrt{(\sigma_j^{2})^{(R)}+\varepsilon}} \]\[ y_{i,j}=\gamma_j\hat{x}_{i,j}+\beta_j \]BN的好处:使深度网络更容易训练,改善梯度流允许更高的学习率,更快的收敛,网络对初始化变得更加稳健,在训练过程中起到正则化的作用
2️⃣ 经典卷积网络结构 #
Alex

ZFNet

VGGNet

为什么只使用3x3 Conv:多个 3x3 Conv 相对一个 7x7 Conv,相同的感受野、更少的参数量与更深、更多非线性变换

卷积核参数:(根据题目要求决定是否计算bias)
\[ \text{params} = K_h \times K_w \times C_{in} \times C_{out} \]FC 参数公式:
\[ \text{params} = N_{in} \times N_{out} \]Feature Map 显存计算公式:
\[ \text{memory} = H \times W \times C \times \text{bytes} \]VGG 的主要问题不是卷积,而是浅层高分辨率特征导致显存开销巨大,以及末端全连接层导致参数量爆炸,这直接推动了后续网络在结构压缩和下采样策略上的演进。
float32(最常默认):1 个参数 4 bytes
FP16:2 bytes。
GoogLeNet

Inception 模块:


GoogLeNet 只在分类器中使用的 FC 层
ResNet

训练深层卷积网络存在问题:深层网络的性能比浅层的更差,但不是由过拟合造成的
深层网络比浅层网络具有更强的表达能力(更多参数)
猜想1:优化问题,深度网络更难优化
关键问题:让深层网络的能力至少与浅层网络一样好(恒等映射)

使用 Bottleneck 提升计算效率: Bottleneck 是一种通过 1×1 卷积在通道维度上压缩特征,再在低维空间进行昂贵卷积计算、最后恢复通道数的结构设计,用以显著降低计算量与参数量,同时配合残差连接保持模型表达能力。

经典卷积网络总结
- AlexNet:CNN可以用于计算机视觉任务
- VGG:网络深度的重要性
- GoogLeNet:网络宽度的重要性
- ResNet:训练极深卷积网络,CNN 的表现优于人类!
迁移学习
将在分类任务上训练好的网络迁移到其他任务
- 分类任务数据量大,标注难度低,标注成本低
- 其他任务数据量小,标注难度高,标注成本高
- 直接在小数据上训练网络,性能很差

后续的研究发现预训练并不是必须的,更长的训练时长+tricks可以达到相同的性能
但是,使用合适的预训练模型一定不会得到更差的结果,注意一定要是合适的预训练模型
07 训练神经网络 #
1️⃣ 权重初始化 #
小随机数初始化:
W = 0.01 * np.random.randn(Din, Dout)直觉上这样做可以随机打破对称性,同时数值小可以避免网络一开始就爆炸
但是深层网络的输出会趋向于0,梯度很小,网络难以训练

若把权重加大一些:
W = 0.05 * np.random.randn(Din, Dout)所有输出都在±1,这是tanh饱和区,梯度很小,依然无法训练

Xavier初始化:(给 tanh / sigmoid 用的)
目标: 前向传播时激活的方差不随层数变化,反向传播时梯度的方差不随层数变化
\[ \mathrm{Var}(x_{l+1}) \approx \mathrm{Var}(x_l)\rightarrow \mathrm{Var}(W) = \frac{1}{D_{in}} \]W = np.random.randn(Din, Dout) / np.sqrt(Din)
各层 std 缓慢下降,但不再崩溃
对卷积层来说,\(D_{in} = \text{filter\_size}^2 \times \text{input\_channels}\)
Kaiming 初始化:
若将 tanh 变为 ReLU,不满足Xavier对于激活函数输出均值为0的假设,Xavier 会低估 ReLU 的能量损失。
\[ \mathrm{Var}(W) = \frac{2}{D_{in}} \]W = np.random.randn(Din, Dout) * np.sqrt(2 / Din)
这是 ResNet、CNN、Transformer 中 ReLU 系列的默认选择
2️⃣ 正则化 #
更好的优化算法将有助于降低训练损失,但我们更希望降低测试泛化损失,减少gap
往往我们当val上的准确性降低时停止训练模型,或者一直训练,但始终存储在val上效果最好的模型快照

模型集成往往能带来可观的性能提升,但若想提升单个模型性能,就不得不提到正则化
L1、L2正则以及Elastic Net不过多赘述
Dropout:
为了不让模型太依赖某几个神经元 / 某几条连接 / 某一条计算路径
让网络学习冗余表示,防止特征的协同适应
在模型训练的每次前向传播中,将一些神经元随机设置为 0
为了在测试时得到自网络的平均效果,工程上常用的实现是:
U1 = (np.random.rand(*H1.shape) < p) / p
H1 *= U1dropout可以看作模型集成,dropout训练了大量参数共享的模型,每次的随机掩码都对应了一个模型
Dropconnect:
连线被剪,计算复杂使用较少
Stochastic Depth:
把 dropout 的思想,从“神经元”提升到“层”
训练时随机跳过某些层,测试时使用所有层,适合放在ResNet中
3️⃣ 超参数选择 #
检查初始损失(关闭权重衰减)
C 个类别,softmax loss 初始值应为 log(C)
这一步是在确认“模型+数据+loss”是正常的
过拟合少量样本
这一步在验证模型是否“有能力”拟合数据
选择合适的LR
1e-1, 1e-2, 1e-3, 1e-4, ...让损失在 100 iterations 内显著下降
粗调(1–5 epochs)
快速筛选方案
精调(10–20 epochs)
选择最优模型
看 loss & accuracy 曲线
情况 1:Train ↑,Val ↑(还在上升)
“如果准确率持续上升,需要训练更多轮次”

情况 2:Train ↑↑,Val ↓(巨大 gap)
“巨大的 train–val gap 意味着过拟合”

情况 3:Train ≈ Val,但都不高
“train–val gap 很小 = 欠拟合”

- 如果第六步出现问题则回到第五步
“随机参数搜索(Random Search)”常常比“网格参数搜索(Grid Search)”更好。
08 循环神经网络 #

| 类型 | 输入形式 | 输出形式 | 时间维度关系 | 典型任务 | 直观理解 |
|---|---|---|---|---|---|
| One → One | 单个输入 | 单个输出 | 无时间展开 | Image Classification | 一张图 → 一个类别 |
| One → Many | 单个输入 | 序列输出 | 输出有时间序列 | Image Captioning | 一张图 → 一句话 |
| Many → One | 序列输入 | 单个输出 | 输入有时间序列 | Action Prediction | 一段视频 → 一个动作 |
| Many → Many(对齐) | 序列输入 | 序列输出 | 输入输出一一对齐 | Video Classification(逐帧) | 每一帧 → 一个标签 |
| Many → Many(不对齐) | 序列输入 | 序列输出 | 长度可不同 | Video Captioning / 翻译 | 一段视频 → 一句话 |
隐藏状态 \(h_t\) = RNN 在时刻 t 的“记忆”
\[ \boxed{h_t = f_W(h_{t-1}, x_t)} \]| 符号 | 含义 |
|---|---|
| \(h_t\) | 当前时刻的隐藏状态(new state) |
| \(h_{t-1}\) | 上一时刻的隐藏状态(old state) |
| \(x_t\) | 当前输入 |
| \(f_W\) | 带参数 W 的同一个函数 |
所有时间步,共享同一组参数 W
\[ \boxed{ h_t = \tanh\left( W_{hh} h_{t-1} + W_{xh} x_t \right) } \]RNN 在每个时间步:把“过去状态 + 当前输入”融合成新的状态
\[ \boxed{y_t = W_{hy} h_t} \]
例子:预测字符
字符表:{h, e, l, o}
测试采样:每次预测一个结果,并将预测结果送入模型

RNN 的总损失 = 所有时间步输出的损失之和,但反向传播不一定从最后一步一路传回最早,而是“分时间块截断地反传”。

RNN的优势:
- 可以处理任何长度的输入
- 步骤 t 的计算(理论上)可以使用之前许多步骤的信息
- 序列越长,计算和存储成本越高,但参数不随时间增长
- 每个时间步都使用相同的权重
RNN缺点:
- 循环计算速度慢(不并行)
- 实践中,很难从很多步之前获取信息(遗忘)






RNN的梯度计算:
\[ h_t=\tanh(W_{hh}h_{t-1}+W_{xh}x_t) \quad (\text{也可加 bias}) \]进行记号上的合并可以得到:
\[ h_t=\tanh\!\left(W\begin{pmatrix}h_{t-1}\\ x_t\end{pmatrix}\right) \]\[ \frac{\partial h_t}{\partial h_{t-1}}=\tanh'(W_{hh}h_{t-1}+W_{xh}x_t)\,W_{hh} \]其中:\(\tanh'(z)=1-\tanh^2(z)\),取值范围是 \((0,1]\),很多时候会因为饱和接近 0
\[ \boxed{ \frac{\partial L}{\partial W}=\sum_{t=1}^{T}\frac{\partial L_t}{\partial W} } \]
但是存在梯度的消失的问题:
中间那串乘积可以看作 \(\prod_{t=2}^T\Big(\operatorname{diag}(\tanh'(a_t))\, W_{hh}\Big)\),每一项总是小于 1,导致梯度消失
假如去除了非线性 tanh,变成线性RNN:
\[ \frac{\partial h_t}{\partial h_{t-1}} = W_{hh} \]\[ \prod_{t=2}^{T} W_{hh} = W_{hh}^{T-1} \]- 若最大奇异值大于1,会导致梯度爆炸,需要进行梯度裁剪
- 若最大奇异值小于1,会导致梯度消失,这时候就需要改进RNN结构
LSTM(Long Short Term Memory):
让“重要信息 + 梯度”能在时间上稳定地流动,不要被一步步乘没了。
| 符号 | 名字 | 作用 |
|---|---|---|
| \(C_t\) | Cell state(长期记忆) | 真正“跨时间传递”的通道 |
| \(h_t\) | Hidden state(短期输出) | 当前时刻对外的表示 |

- 遗忘门——要不要保留旧记忆
- 输入门 + 候选记忆 ——要写入什么新信息
Cell State更新:
\[
\boxed{C_t = f_t \odot C_{t-1} + i_t \odot \tilde{C}_t}
\]这里是「加法」,不是嵌套非线性!\(\frac{\partial C_t}{\partial C_{t-1}} = f_t\)
如果模型学会让 \(f_t \approx 1\),那么信息、梯度都可以**几乎无损地跨很多时间步传递**
- 输出门:从长期记忆中“读什么出来”
RNN 的梯度问题来自“时间上的非线性连乘”,
LSTM 通过引入 Cell state 和门控加法通道,使梯度可以在时间维度上稳定传播。



从 \(c_t\) 到 \(c_{t-1}\) 的反向传播只与 f 有点乘的关系,与 W 无关
提示
LSTM 到底有没有“解决”梯度消失?
没有彻底解决,但在机制上大幅缓解了,而且让“保留长程信息”变得可控、可学。
- LSTM 架构使 RNN 更容易在多个时间步长内保存信息(更新公式使用加法路径非乘法路径)
- 例如,如果 f = 1 且 i = 0,则该单元的信息将无限期保留。
- 相比之下,vanilla RNN 更难学习循环权重矩阵 \(W_h\) 以保存信息
- LSTM 不能保证没有消失/爆炸梯度,但它确实为学习长距离依赖提供了更简单的方法
总结:
- RNN在架构设计中提供了很大的灵活性
- Vanilla RNN很简单,但效果不太好, RNN 中梯度的反向流动可能会爆炸或消失
- 常用 LSTM 或 GRU:它们改善了梯度流
09 注意力机制与 Transformer #
https://icnbqxskffeq.feishu.cn/wiki/NHc2wNyJHiVJL2kGMpScednfnxc?from=from_copylink
1️⃣ 注意力机制 #
让每一个空间位置(像素)都能“看见”并选择性地融合其他位置的信息,而不只是靠卷积的局部感受野。

Step 1:计算注意力分布 α
\[ \alpha_n = \text{softmax}(s(x_n, q)) \]| 符号 | 含义 |
|---|---|
| \(x_n\) | 第 n 个输入(token / 像素 / 时间步) |
| \(q\) | Query(我要找什么) |
| \((s(\cdot))\) | 相似度函数(dot / cosine / MLP) |
| \(\alpha_n\) | 注意力权重 |
Step 2:加权求和(注意力输出)
\[ \text{att}(X, q) = \sum_{n=1}^N \alpha_n x_n \]注意力类型:
Channel Attention(注意“是什么”)
作用在 通道维 C
Spatial Attention(注意“在哪里”)
作用在 H×W
Channel + Spatial
先选“什么特征”,再选“什么位置”
Temporal Attention(注意“什么时候”)
用于序列 / 视频 / NLP
Spatial + Temporal
视频理解、动作识别
Branch Attention(注意“选哪条路”)
多分支结构(Inception / SKNet)

自注意力的Q-K-V:

多头注意力:

2️⃣ Transformer #
Text Embedding:

| 符号 | 含义 |
|---|---|
| pos | 这是第几个 token(位置) |
| i | 向量的第 i 个维度 |
| d_model | embedding 总维度 |
Encoder:全局语义建模
\[ \text{Attention}(Q,K,V)=\text{softmax}\left(\frac{QK^\top}{\sqrt{d_k}}\right)V \]

时间复杂度:O(T² · d)
空间复杂度:O(T²)
Multi-Head Attention




Feed Forward(FFN):
Self-Attention 负责“不同 token 之间的信息交换”,
Feed Forward 负责“对每个 token 自己做非线性变换”。
对每个 token 独立,参数在所有 token 间共享
\[ \text{FFN}(x) = W_2 \,\sigma(W_1 x + b_1) + b_2 \]Add & Norm:
\[ y = x + f(x) \]防止梯度消失,让模型只学增量
使用Layer Norm

Decoder:
- 训练阶段:一次性并行算完所有位置(靠 mask 防作弊)
- 测试阶段:一步一步往前生成(靠上一步的预测)


最后的Linear + Softmax:
| 模块 | 时间复杂度 | 空间复杂度 |
|---|---|---|
| Linear | \(O(T_d \cdot d_{model} \cdot V)\) | \(O(T_d \cdot V)\) |
| Softmax | \(O(T_d \cdot V)\) | \(O(T_d \cdot V)\) |
| 总计 | \(O(T_d \cdot d_{model} \cdot V)\) | \(O(T_d \cdot V)\) |
其中:
| 符号 | 含义 |
|---|---|
| \(T_d\) | decoder 序列长度(生成到第几个词) |
| \(d_{model}\) | 模型隐藏维度(如 512 / 768) |
| \(V\) | 词表大小(如 30k / 50k) |
ViT及其他变种Transformer:


Multiscale Vision Transformers

10 目标检测与图像分割 #
1️⃣ 语义分割 #
语义分割 = 对图像中「每一个像素」做分类,不区分物体,只进行分割
滑窗分类(Sliding Window):
以某个像素为中心,裁一个小 patch,用 CNN 分类这个 patch,并把分类结果赋给中心像素
但是相邻像素的 patch 高度重叠, 同一块区域被 CNN 反复算几十次 / 上百次
——于是全卷积网络(FCN) 诞生了

把“分类网络”改造成“像素级预测网络”
去掉全连接层,全部使用卷积,输出变成:\(C \times H \times W\)
但是这样虽然能实现高分辨率像素级预测,卷积操作的显存/计算量太大了
——于是Encoder–Decoder(下采样 + 上采样) 架构诞生了

先下采样降低计算量,再上采样恢复分辨率
常见架构:
U-Net:Skip Connection 把 Encoder 里的高分辨率特征 直接拼到 Decoder 对应层

DeepLab(Encoder-only):不靠 Decoder 恢复分辨率,而是在 Encoder 阶段“少下采样(ASPP) + 空洞卷积(Atrous Convolution)”
PSPNet : Pyramid Pooling Module(PPM)
2️⃣ 目标检测 #
起点:单个物体 = 分类 + 定位
用同一个 CNN backbone,接两个 head:一个做分类,一个做框回归,这就是最早的 multi-task learning 思想。
但是问题出现了:真实世界不是单个物体的,就不能直接“一个 FC 输出所有框”
——于是可以想到将问题拆分成多个“单物体问题“:先找一些“可能有物体的区域” 对每个区域:判别是不是物体,如果是,分类 + 回归框。这一步叫Region Proposals(候选区域)
假如用滑窗方法穷举:计算量会爆炸
——于是诞生了第一次工程化方案:Selective Search
从像素 / 超像素 开始,根据:颜色相似、纹理相似、空间邻近来不断合并区域 得到 ~2000 个候选框
R-CNN:

每一个 RoI 都是完整走一遍 CNN,效率低,非常慢,同一块区域会被反复计算
Fast R-CNN:
Fast R-CNN 的本质改进:CNN 不再对每个 RoI 单独跑一遍,而是只对整张图跑一次 CNN,所有 RoI 共享特征。

这里依然要进行Selective Search,但这里只是2000 次很轻量的 RoI 裁剪 + FC,所以速度要快于R-CNN
RoI Pooling / RoI Align:
把「大小各不相同的候选框(proposal)」变成大小固定的一块特征(比如 512×7×7),这样后面的分类 / 回归网络才能统一处理。

先在在特征图上裁出 RoI 区域, 再把把这块区域均匀分成 K×K 个 bin(切分时要把浮点坐标取整, bin 的边界会被粗暴地对齐到网格),再每个 bin 做 Max Pooling
但是RoI 提取的特征与原始 proposal中的特征存在差异

不做任何取整,全部用浮点坐标 + 插值
Faster R-CNN:
用 CNN 自己学会“提候选框”(proposal),而不是用人工算法(Selective Search)

Region Proposal Network:
先在特征图的每个位置放k个不同大小的Anchor,接下来预测每个锚框内是否存在物体,并对于存在物体的锚框进行位置的调整,最终选择得分最高的300个锚框作为proposal

3️⃣ 实例分割 #
实例分割 = 目标检测 + 像素级分割(而且是“每个实例一张 mask”)
Mask R-CNN:
基于Faster R-CNN,Mask R-CNN在每一个 RoI(检测到的实例)上,再预测这个实例的像素形状(mask)

网络会为 每个类别都预测一个 mask, 最终只取 分类结果对应的那一张
11 视频理解 #
Video = 2D + Time:
\[ T \times 3 \times H \times W \]动作 ≠ 单帧能看出来的东西,需要观察多帧之间的变化模式,但是原始视频的数据量太大了
——在视频切片(clip)上进行训练:
\[ \text{clip} \in \mathbb{R}^{T \times 3 \times H \times W} \]
单帧 CNN: 最朴素但非常强的 baseline
每一帧单独送进 2D CNN, 得到每一帧的分类结果,最后投票 / 平均
Late Fusion(FC版): 先看帧,再想时间

- 参数量爆炸,对时间顺序不敏感,只是“拼接”,没有“运动建模”
Late Fusion(Pooling 版):

Early Fusion:在最开始就看时间
\[ T \times 3 \times H \times W \;\;\Rightarrow\;\; (3T) \times H \times W \]
- 只在第一层用到了时间信息,时间信息用的太浅
于是引入3D卷积,让卷积核不仅在空间滑动, 还在时间维度滑动

具有时间平移不变性!
| 方法 | 时间维发生了什么 | 本质 |
|---|---|---|
| Late Fusion | 时间维一直保留,但 CNN 不看时间 | 帧级处理,最后再平均 |
| Early Fusion | 时间维被并进通道,一开始就消失 | 把整段视频当“一张厚图” |
| 3D CNN | 时间维参与卷积并逐层建模 | 真正学习“运动模式” |
衡量运动(Motion):光流(Optical Flow)

Two-Stream Network:把“外观”和“运动”分开学
| Stream | 输入 | 学什么 |
|---|---|---|
| Spatial Stream | 单帧 RGB | 人长什么样、场景 |
| Temporal Stream | 多帧光流 | 怎么动、动得多快 |
CNN+RNN:

CNN 负责“看清每一刻”,RNN 负责“记住过去”
用 ImageNet / Kinetics 预训练 CNN,冻结 CNN, 只训练 RNN
Recurrent Convolutional Network(RCNN)= 用“卷积”来实现 RNN 的状态更新
普通 RNN(向量):
\[ h_t = \tanh(W_h h_{t-1} + W_x x_t) \]Recurrent Conv(特征图):
\[ \boxed{H_t = \tanh(\underbrace{W_h * H_{t-1}}_{\text{时间递归(卷积)}}+\underbrace{W_x * X_t}_{\text{当前输入(卷积)}})} \]Spatio-Temporal Self-Attention(Non-local Block):

Inflating 2D Networks to 3D(I3D):
把 2D 卷积核,复制成 3D 卷积核
W_3D[:, t, :, :] = W_2D / Kt
Video Transformer:
把视频切成“时空 token”,然后用 Transformer 的自注意力在整个时空范围内建模。

Embed to tokens:
3D Conv (kernel = t × p × p, stride = t × p × p) N = T × H × W 个 token 每个 token ∈ R^D加上 Position + CLS token:
[CLS] 0 1 2 3 ... NPool_Q / Pool_K / Pool_V:
这是视频 Transformer 特有的工程优化,降token数降显存,近似全局注意力
12 可视化 #
Attention 可视化:
在视觉模型中,每个位置都有一个 attention weight,把这些权重画成热力图(heatmap)
其中白色/亮色线条或区域,表示:模型在预测时重点关注的区域
越深、越强的模型,Attention 越集中、越语义化
最近邻可视化:
把一张图的特征向量取出来,在特征空间中找最近的图
CNN 学到的是 语义距离,而不是像素距离
特征降维可视化:
把 4096 维 → 2 维,常用PCA和t-SNE,其中的“簇”代表同一类别自动聚在一起
激活值可视化:
例如conv5 输出:128 × 13 × 13 ,让每个通道 → 一张灰度图,意味着哪些通道被激活,激活位置在哪里
判断哪些图最容易激活某个神经元:固定某一层、某一通道,并在大量图像中找激活最大的 patch,会发现某些神经元专门响应特定的特征如:圆形、眼睛、轮子、纹理模式
显著性可视化(Saliency):
遮挡法(Occlusion):
先遮住图像的一块,再看预测概率变化,如果遮住 A → 概率大降则说明 A 很重要
梯度法 Saliency Map:
首先进行前向传播,然后计算每个类预测值相对于图像像素的梯度,在 RGB 通道上取绝对值的最大值
卷积特征可视化:
中间层梯度可视化(Guided Backprop):
- 普通反向传播:正负梯度都传
- Guided BP:只传正梯度 + ReLU
可视化 CNN 特征:梯度上升
(引导)反向传播:找到神经元被图像激活的部分
梯度上升:生成最大程度激活神经元的合成图像

- 在图像优化期间,高斯模糊图像、将值较小的像素剪裁为0、将梯度较小的像素剪裁为0可以取得更好的正则化效果
对抗样本:
对图像加人类几乎看不见的扰动, 却能让模型分类错误
- 选择任意一张图
- 选择任意一个类
- 修改图像以最大化这个类
- 重复,直到网络分类错误
DeepDream:
DeepDream用于放大特征,选择一张图像和一个 CNN 层,重复步骤1-2
- 前向:将所选层的梯度设置为其激活值
- 反向:计算图像的梯度,更新图像
风格迁移:

α 大:更像内容图
β 大:更像风格图
风格图越大,纹理尺度更丰富;越小,纹理更“细碎/重复”。
提示
Gram Matrix(对位置不敏感,用于表示纹理和风格)
F \in \mathbb{R}^{C\times (HW)}
G = FF^\top \in \mathbb{R}^{C\times C}
G_{ij} = \sum_{k=1}^{HW} F_{i,k}F_{j,k}
但是速度非常慢,因此有了Fast版本:
- 训练一个前馈网络 \(g_\theta\),输入内容图 \(c\),直接输出 \(x=g_\theta(c)\)
- 训练时仍用同样的 VGG losses(内容/风格)监督
- 推理时只需一次 forward
13 自监督学习 #
没有大规模人工标注,但又想学到“对下游任务有用的特征”,该怎么办?
这就引出了自监督学习:用数据本身,自动构造“监督信号”,先学一个好特征提取器

Pretext Task:
无标签数据
↓
Encoder(特征提取器)
↓
Decoder / Classifier / Regressor
↓
自动生成的标签 / 目标典型 Pretext Task 示例:

旋转预测角度,预测图像块位置,预测图像拼图,预测缺失的像素,图像着色
提示
- Pretext Task 侧重于“视觉常识”,例如预测旋转、修复、重新排列和着色
- 模型需要学习自然图像的良好特征,例如对象类别的语义表示,以解决 Pretext Task
- 我们通常不关心这些 Pretext Task 的性能,而是关心学习到的特征对 Downstream Task(分类、检测、分割)的效果**(这里只是为了学一个Encoder)**
Downstream Task(你真正想解决的问题):
(预训练好的)Encoder
↓
FC / Linear Classifier
↓
人工标注的输出(使用人工标注好的小数据集)如何评价一个自监督学习方法:
- 特征质量:线性分类效果、聚类、t-SNE 可视化
- 鲁棒性和泛化性:不同数据集和不同变化
- 计算效率:训练时间和训练所需资源
- 迁移学习和 Downstream Task 性能
对比学习:
对比学习 = 在一堆候选样本中,让模型选出“和我最像的那个”
reference / anchor(锚点)—— x
positive sample(正样本)—— x⁺
negative sample(负样本)—— x⁻
score( f(x), f(x⁺) ) >> score( f(x), f(x⁻) )N 路 softmax 分类器的交叉熵损失
SimCLR:
SimCLR 通过对同一图像的两种随机增强构成正样本对,在 mini-batch 内构造大量负样本,利用余弦相似度和 InfoNCE 损失最大化正样本一致性、最小化与负样本的相似度。SimCLR 引入投影头将对比目标与下游表示解耦,并通过大 batch 提供充足负样本,从而学习到高质量、可迁移的特征表示。


MoCo:
MoCo 通过引入动量编码器和负样本队列,将负样本数量与 batch 大小解耦,从而在较小 batch 下实现大规模对比学习。MoCo v2 进一步结合 SimCLR 的非线性投影头和强数据增强策略,在保持低显存消耗的同时显著提升表示学习性能,其在小 batch 场景下优于 SimCLR。
SimCLR:
通过大 batch 构造大量负样本,使用 InfoNCE 学习增强不变表示。
MoCo:
通过动量编码器和负样本队列,将负样本数量与 batch size 解耦。
DINO:
基于自蒸馏的无负样本方法,通过 teacher–student 一致性学习语义表示。
14 视觉-语言模型 #
1️⃣ 视觉(-语言)基础模型预训练 #
模型预训练方式:
- 全监督学习:用人工标注的标签 训练模型
- 缺点:人工标注很昂贵,标签也可能有限
- 图像对比学习:不需要标签
- 语言–图像对比学习:输入是 (图像, 文本) 对
- 掩蔽自编码器:遮住输入的一部分, 让模型去重建被遮住的内容
现代深度学习预训练已从依赖人工标注的全监督学习,发展为以对比学习和掩蔽建模为代表的自监督范式。其中,图像对比学习强调判别性表示,语言–图像对比学习实现跨模态语义对齐,而掩蔽自编码器侧重结构建模与生成能力。
Clip:

从海量的图像文本对中学习,是一种简单的对比学习训练方式,但是数据海量
CLIP 通过语言–图像对比学习,在海量图文对的监督下学习统一的跨模态表示。语言作为一种比封闭标签更强的监督信号,使得模型能够获得良好的 zero-shot 泛化能力。实验表明,CLIP 遵循清晰的 scaling laws,其性能随着数据规模、模型容量和算力的提升而稳定增长。因此,CLIP 的成功不仅来自对比学习本身,更源于“简单模型 + 海量数据”的可扩展设计范式。
| 方法 | 改进维度 | 核心做法 | 是否改变 CLIP Loss | 主要收益 |
|---|---|---|---|---|
| CLIP | 基线 | 图文双编码器 + 对比学习 | ✅ 原始 | Zero-shot、多模态对齐 |
| FLIP | 图像端(效率) | 随机 mask patch,只编码可见区域 | ❌ 不变 | 训练速度 ↑↑ |
| FILIP | 对齐粒度 | Patch–Token 细粒度相似度 | ❌ 不变 | 小目标、局部语义更强 |
| K-Lite | 文本端(知识) | 引入字典/知识增强文本 | ❌ 不变 | 长尾概念 ↑ |
| ImageBind | 模态扩展 | 冻结 CLIP,对齐其他模态 | ❌ 不变 | 多模态统一空间 |
| CoCa | 目标函数 | 加 Captioning Loss(生成) | ➕ 新增 | 表征 + 生成能力 |
2️⃣ 通用视觉(-语言)模型 #
视觉任务在输入模态、时间尺度、任务粒度与输出形式上高度异构,给统一建模带来根本挑战。
不同类型标注的数据量差异极大
| 标注类型 | 数据规模 | 语义 | 成本 |
|---|---|---|---|
| Image-level(ImageNet / LAION) | 极大 | 粗 | 低 |
| Box-level(COCO / Objects365) | 中 | 中 | 中 |
| Mask-level(COCO / LVIS) | 小 | 细 | 高 |
通用视觉模型的尝试:













