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 的结构内置了两个强假设:
-
Locality(局部性):卷积核局部滑动处理图片,认为某个位置的像素只和附近像素有关。这是视觉信息的**强先验**,现实中大部分视觉特征确实是局部的(边缘、纹理、局部形状),但也存在需要全局上下文才能判断的模式。
-
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}}\),即:
ReLU correction:
std = sqrt(2 / Din)
因为 ReLU 会导致 \(< 0\) 的信号全部丢失。
Kaiming Initialization(He Initialization)
针对 ReLU/Leaky ReLU 的改进:
- 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 = \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\) 会导致初期估计偏小):
参数更新:\(\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 逐渐增加到目标值,防止早期不稳定