跳转至

cv导论

CNN : Sparse Connectivity,相比 FC(全连接)的优势在于更加轻量,对图片的小平移和小角度旋转具有鲁棒性(不会导致 FC 中图片像素平移一格导致 output 完全不一致的问题)

多层 pooling + convolution,小平移和小角度旋转不会改变输出,这是天然不用学习的。

convolution 运算的 平移等变性 决定了上面的性质。

视觉中的 classification task 是满足 平移等变性(translation invariance)的,故 CNN 具有天然的优势。

CNN 的 Inductive bias 很强,transformer 则没那么强(有益于多模态)

补充:Inductive Bias(归纳偏置)详解

Inductive bias 指的是学习算法对问题做出的先验假设——模型在看到数据之前,就"默认"相信某种规律是对的。这些假设不是从数据中学来的,而是被硬编码进模型结构里的。

CNN 的两大归纳偏置

CNN 的结构内置了两个强假设:

  1. Locality(局部性):卷积核局部滑动处理图片,认为某个位置的像素只和附近像素有关。这是视觉信息的**强先验**,现实中大部分视觉特征确实是局部的(边缘、纹理、局部形状),但也存在需要全局上下文才能判断的模式。

  2. Translation Equivalence(平移等变性):卷积 + pooling 天然具有平移等变性——输入平移,输出也跟着平移但特征表达不变。这对视觉分类任务来说是**天然适配** 的假设。

为什么说 CNN "归纳偏置很强"

CNN 的每一步(局部卷积 → 池化降采样 → 再局部卷积 → 再池化)都在告诉模型:"你相信局部特征,相信平移不变性,相信层级化的特征提取。"

  • 优点:数据量小时,归纳偏置能弥补数据不足,训练效率高
  • 缺点:当数据量非常大时,强先验反而限制了模型上限——模型被结构框死了,无法学到结构之外的知识

Transformer 的弱归纳偏置

Transformer(以 Vision Transformer 为例)几乎**不做这些假设**:

  • 输入被切成 patch,不假设局部相邻关系
  • 通过全局 self-attention 让任意两个位置直接交互
  • 结构上更"通用",更依赖数据来学习几何规律

有益于多模态

Transformer 的弱归纳偏置让它成为多模态的统一骨架:

模态 CNN Transformer
图像(2D grid) 天然适合 需 ViT 改造
文本(1D 序列) 不适合 天然适合
音频(1D 时序) 不适合 天然适合
视频(时空序列) 勉强 天然适合

CNN 的局部卷积假设了"2D 局部邻域关系",直接套到文本上效果很差。Transformer 的 self-attention 对输入结构**不做任何假设**,只关心 token 和 token 之间的关系——无论输入是句子、图像块还是音频频谱,都可以统一用 attention 建模。

总结

CNN Transformer
归纳偏置 强(局部 + 平移不变) 弱(几乎不假设)
数据依赖 依赖数据少 依赖数据多
上限 受限于先验假设 更高(数据足够时)
下限 高(数据少时也好用) 低(需要大量数据)

这就是为什么:

  • 数据少时 CNN 吊打 ViT(ViT 没有足够数据弥补弱先验)
  • 数据多时 ViT 超越 CNN(Transformer 有更大的学习空间)
  • **多模态任务**首选 Transformer(结构通用,不被单一模态的结构假设束缚)

Data Preprocess

数据预处理,归一化之类的

为什么需要归一化

  • 像素值范围通常在 \([0, 255]\),如果直接输入,梯度下降速度会非常不一致
  • 特征尺度差异大时,loss landscape 呈椭圆形,梯度下降走很多弯路
  • 归一化后,loss landscape 更接近球形,优化路径更直接

常见方法:

方法 公式 适用场景
Min-Max 归一化 \(x' = \frac{x - x_{\min}}{x_{\max} - x_{\min}}\) 像素值 \([0, 255]\)
Z-Score 标准化 \(x' = \frac{x - \mu}{\sigma}\) 特征分布未知
逐通道归一化 对 RGB 三通道分别计算 \(\mu, \sigma\) 图像(ImageNet)

图像预处理的实际做法

# 常见做法:减均值、除标准差
# ImageNet 均值:[0.485, 0.456, 0.406]
# ImageNet 标准差:[0.229, 0.224, 0.225]
img = (img - mean) / std

Weight Initialization

gaussian with zero mean and 1e-2 standard deviation

W = 0.01 * np.random.randn(Din, Dout)

这个初始化的问题

\(D_{in}\) 很大时(如 FC 层 \(D_{in} = 784\)),初始权重太小会导致信号在前向传播中指数衰减 当 \(D_{in}\) 很小时,初始权重可能导致信号爆炸

Xavier Initialization

目标是让前向传播时各层激活的方差不要随深度剧烈放大或缩小,从而缓解梯度消失 / 梯度爆炸,让深层网络更容易训练。(比较好优化)

W = 0.01 * np.random.randn(Din, Dout) / np.sqrt(Din)

Xavier Initialization 的推导

假设权重独立同分布 \(W \sim \mathcal{N}(0, \sigma^2)\),输入 \(x\) 与权重独立

前向传播:\(y = W x + b\)

为使 \(\text{Var}(y) = \text{Var}(x)\),需要 \(\sigma^2 = \frac{1}{D_{in}}\)

反向传播同理,需 \(\sigma^2 = \frac{1}{D_{out}}\)

折中取 \(\sigma^2 = \frac{2}{D_{in} + D_{out}}\),即:

\[W \sim \mathcal{N}\left(0, \frac{2}{D_{in} + D_{out}}\right)\]

ReLU correction:

std = sqrt(2 / Din)

因为 ReLU 会导致 \(< 0\) 的信号全部丢失。

Kaiming Initialization(He Initialization)

针对 ReLU/Leaky ReLU 的改进:

\[W \sim \mathcal{N}\left(0, \frac{2}{D_{in}}\right)\]
  • ReLU 会把一半的信号置零,为了补偿这个信息损失,方差要更大
  • 论文:Delving Deep into Rectifiers: Surpassing Human-Level Performance (He et al., 2015)

保证起步时各层反向传播的梯度不要差太多,解决初始训练时的 stability


Optimization

Problems with SGD

如果黑塞矩阵的条件数很大的话,容易来回震荡。

条件数的几何意义

Hessian 矩阵 \(H\) 的条件数:\(\kappa = \frac{\lambda_{\max}}{\lambda_{\min}}\)

  • \(\lambda\) 是特征值,代表曲率(曲率越大,梯度变化越快)
  • 条件数大 \(\Rightarrow\) 不同方向的曲率差异大
  • 优化轨迹:在一个方向走得快,另一个方向走得慢
  • 本质:loss surface 是"细长碗",最速下降方向不指向最优点

为了解决这个问题,SGD + Momentum

vx = 0
while True:
    dx = compute_gradient(x)
    vx = rho * vx + dx
    x -= learning_rate * vx

vx 对过去行走的历史做了一个指数平均,\(\rho\) 常取 \(0.9\)\(0.99\),表达对原来方向的置信程度

Momentum 的物理直觉

可以把参数更新类比于小球在碗里滚动:

  • 普通 SGD:小球只看当前坡度方向,不关心历史速度
  • SGD + Momentum:小球有"惯性",沿速度方向继续滑行

数学上,\(v_t\) 是梯度序列的指数加权移动平均:

\[v_t = \rho v_{t-1} + \nabla L(\theta_{t-1})\]

展开:\(v_t = \sum_{i=0}^{t} \rho^i \nabla L(\theta_{t-i})\)

越远的梯度衰减越快(\(\rho^i\))。以 \(\rho = 0.9\) 为例,有效利用约最近 10 步的梯度信息(\(\sum_{i=0}^{\infty} 0.9^i \approx 10\)

Nesterov Momentum

标准 Momentum 是"先累积速度、再决定方向",Nesterov 则是"先按速度走一步、再算梯度":

vx = rho * vx + compute_gradient(x + rho * vx)  # 向前看一步
x -= learning_rate * vx

优点:在大曲率方向能更快调整,比标准 Momentum 更稳定

Adam 训的快,SGD 训的好(时间够长)

Adam vs SGD 的实际表现

  • Adam:自适应学习率,收敛快,但泛化性能往往不如 SGD(存在 generalization gap)
  • SGD+Momentum:收敛慢,但最终性能更好(尤其是验证集)
  • 原因:Adam 的自适应学习率像"提前刹车",SGD 更依赖数据驱动找到更平坦的极小值

实践中常用的策略

  • 短期比赛、小数据集:Adam 快速出结果
  • 大模型、大数据预训练:先用 Adam 快速收敛,再用 SGD 微调
  • 现在的趋势:AdamW(将 weight decay 与自适应学习率解耦)+ cosine LR schedule

Adam 的核心公式

一阶矩估计(类似 Momentum):\(m_t = \beta_1 m_{t-1} + (1-\beta_1) g_t\) 二阶矩估计(类似 RMSProp):\(v_t = \beta_2 v_{t-1} + (1-\beta_2) g_t^2\)

偏差校正(因为初始化时 \(m_0 = v_0 = 0\) 会导致初期估计偏小):

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

参数更新:\(\theta_t = \theta_{t-1} - \alpha \cdot \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon}\)

默认参数:\(\beta_1 = 0.9, \beta_2 = 0.999, \epsilon = 10^{-8}\)


补充:学习率调度

除了优化器本身,学习率 schedule 也很重要:

  • Step Decay:每 \(N\) 个 epoch 乘以 \(\gamma\)(如 0.1)
  • Cosine Annealing\(\eta_t = \eta_{\min} + \frac{1}{2}(\eta_{\max} - \eta_{\min})(1 + \cos(\frac{t}{T}\pi))\),模拟余弦曲线先快后慢
  • Warmup:初期学习率从 0 逐渐增加到目标值,防止早期不稳定