|
## 激活函数总览
激活函数核心作用:**为神经网络引入非线性**。没有激活函数,无论多少层都只能学线性关系,无法处理复杂问题。
### 经典激活函数
| 函数 | 公式 | 范围 | 优点 | 缺点 | 适用 |
|------|------|------|------|------|------|
| **Sigmoid** | $g(z)=\frac{1}{1+e^{-z}}$ | (0,1) | 平滑可导,输出可作概率 | **梯度消失**;不以0为中心 | 二分类**输出层** |
| **Tanh** | $\frac{e^z-e^{-z}}{e^z+e^{-z}}$ | (-1,1) | 以0为中心利于收敛 | 仍**梯度消失** | RNN/隐藏层(ReLU普及前) |
| **Softmax** | 向量压缩成概率(和为1) | (0,1)和1 | 多分类概率 | — | 多分类**输出层** |
### Sigmoid 梯度消失的本质
导数 $g'(z) = g(z)(1-g(z))$,最大值仅 **0.25**(z=0处)。深层网络反向传播梯度连乘 $0.25^n \to 0$,浅层权重几乎不更新。
> 直觉:Sigmoid 两端(饱和区)导数接近 0,梯度"传不回去"。
|
|
## ReLU 及其变体(现代主力)
### ReLU(修正线性单元)
公式:$g(z) = \max(0, z)$
| 优点 | 缺点 |
|------|------|
| 计算极快(无指数/对数) | **神经元死亡**:输入为负梯度恒0,永不激活 |
| 正区间梯度恒1,**缓解梯度消失** | 输出不以0为中心 |
| 加速收敛(比Sigmoid快数倍) | |
### 三大主流变体
| 变体 | 公式 | 解决问题 |
|------|------|----------|
| **Leaky ReLU** | $\max(0.01x, x)$ | 负区给小斜率,永不"杀死"神经元 |
| **PReLU** | $\max(\alpha x, x)$,$\alpha$可学习 | 斜率自适应,比Leaky灵活 |
| **ELU** | $x$(x>0);$\alpha(e^x-1)$(x≤0) | 负区趋近固定负值,均值接近0加速收敛 |
### 进阶/冷门变种
| 变体 | 特点 | 场景 |
|------|------|------|
| **SELU** | 自带"自归一化",多层分布稳定 | 全连接深层MLP |
| **CReLU** | 正负部分别过ReLU再拼接 | CV互补特征(边缘明暗) |
| **RReLU** | 训练时斜率随机采样 | 正则化防过拟合,小数据集 |
| **Swish** | $x\cdot\sigma(x)$ 平滑非单调 | 极深网络(>40层)优于ReLU |
|
|
## 行业补充:现代激活函数(GELU / GLU / SwiGLU)
课件讲了 ReLU 及变体,但 Transformer/LLM 时代的现代激活函数完全没提,是 LLM 面试必问。
### GELU(Gaussian Error Linear Unit)
$$\text{GELU}(x) = x\cdot\Phi(x)$$
$\Phi(x)$ 是标准正态分布累积分布函数。比 ReLU 更平滑,0 附近软过渡。
- **应用**:**BERT、GPT、ViT** 标配
- 近似:$\text{GELU}(x)\approx 0.5x(1+\tanh[\sqrt{2/\pi}(x+0.044715x^3)])$
### GLU(门控线性单元)
$$\text{GLU}(x) = (xW+b)\otimes\sigma(xV+c)$$
引入"门控":一部分线性变换,另一部分过 Sigmoid 当"门"控制信息通过比例。
### SwiGLU —— LLaMA 等大模型标配
$$\text{SwiGLU}(x) = \text{Swish}(xW)\otimes(xV)$$
结合 Swish 平滑性和 GLU 门控,**LLaMA、PaLM、Qwen** 等主流 LLM 的 FFN 激活函数。
### 激活函数演进时间线
| 时代 | 主流 | 代表模型 |
|------|------|----------|
| 2012前 | Sigmoid/Tanh | 早期MLP |
| 2012~2017 | ReLU及变体 | AlexNet、VGG、ResNet |
| 2017~ | GELU | BERT、GPT、ViT |
| 2022~ | SwiGLU | LLaMA、Qwen 等现代LLM |
|
|
## 激活函数选择指南
### 隐藏层首选
- **ReLU** 是最安全、最高效的起点
- 担心神经元死亡 → **Leaky ReLU**(alpha=0.01) 或 **ELU**
- 极深网络 → 尝试 **Swish**
### 输出层选择
| 任务 | 输出层激活 |
|------|------------|
| 二分类 | Sigmoid |
| 多分类 | Softmax |
| 回归 | 不激活(线性) |
### 搭配 BN 的建议
用了 Batch Normalization 后,通常 **ReLU 就够好**,不必纠结变种。因为 BN 已解决输出分布偏移问题。
### 实操建议
- **新手或工程首选**:直接用 Leaky ReLU(alpha=0.01),几乎没缺点
- **追求极致准确率**:PReLU 或 ELU,注意调学习率
- **Transformer/LLM**:GELU 或 SwiGLU
```python
import torch.nn as nn
# 隐藏层
hidden = nn.Sequential(nn.Linear(128, 64), nn.GELU())
# 输出层(多分类)
output = nn.Sequential(nn.Linear(64, 10), nn.Softmax(dim=-1))
```
|
|
## Batch Normalization 原理与作用
BN 是深度学习里程碑技术,解决"内部协变量偏移"。可理解为"数据标准化质检员"——强行把每层输出拉回标准正态附近。
### 核心原理(三步)
操作发生在**激活函数之前**,对当前 Batch 每个特征维度独立:
**① 求均值方差**
**② 标准化**:
$$\hat{x}_i = \frac{x_i - \mu_B}{\sqrt{\sigma_B^2 + \epsilon}}$$
($\epsilon$ 防分母为0)
**③ 缩放平移(反标准化,最关键!)**:
$$y_i = \gamma\hat{x}_i + \beta$$
赋予网络"反悔"能力——若标准化不利表达,可学习 $\gamma,\beta$ 恢复原分布。
### 五大核心作用
| 作用 | 说明 |
|------|------|
| ① **极大加速收敛** | 数据落激活函数敏感区,可用更大学习率 |
| ② **缓解梯度消失/爆炸** | 保证数据不落饱和区/平坦区 |
| ③ **对初始化不敏感** | 权重大点小点BN都拉回正轨 |
| ④ **正则化效果** | Batch统计量随机性引入轻微噪声 |
| ⑤ **允许更大学习率** | 梯度传播稳定,更快找最优解 |
|
|
## BN 的局限性与避坑
### 三大软肋
| 问题 | 对策 |
|------|------|
| **对Batch Size敏感** | Batch<8统计量噪声大效果差 → 改 **LN/GN** |
| **RNN中效果差** | 变长序列不同时间步分布差异大 → 用 **LN** |
| **训练/测试行为不同** | 训练用当前Batch;测试用**移动平均(全局统计量)** |
### 训练/测试切换(新手最易犯错)
- `model.train()`:BN 用当前 Batch 动态统计量
- `model.eval()`:BN 冻结,用训练集全局移动平均
**忘记切换的后果**:测试时把整个测试集当一个Batch算均值,预测结果完全飘移(Accuracy暴跌)。
### 记忆口诀
> 减均值,除方差,保证分布都一样;
> 乘 Gamma,加 Beta,网络反悔也随它;
> 训得快,不敏感,正则防过拟合;
> 注意 Batch 别太小,RNN 场景换 LN。
```python
# PyTorch 中正确用法
model.train() # 训练模式
for x, y in train_loader:
out = model(x)
...
model.eval() # 评估模式! 必须切换
with torch.no_grad():
for x, y in test_loader:
out = model(x)
```
|
|
## 归一化家族:BN / LN / IN / GN / WN
以 4D 张量 `(N, C, H, W)` 为例,按"对哪个维度归一化"区分:
| 方法 | 归一化维度 | 直觉 | 适用 |
|------|------------|------|------|
| **BN** | 跨N,每C独立 | "同一特征跨所有样本" | **CNN**,Batch≥32 |
| **LN** | 跨C/H/W,每N独立 | "同一样本跨所有特征" | **Transformer/RNN**,Batch无关 |
| **IN** | 跨H/W,每N/C独立 | "单样本单通道" | **风格迁移/GAN** |
| **GN** | C分组,组内跨H/W | LN与IN折中 | **CNN小Batch**(检测/分割) |
### LN(Layer Normalization)—— NLP标配
- BN 对"同一特征跨样本"归一化;LN 对"同一样本跨所有特征"归一化
- **不依赖Batch Size**,Batch=1 也能算
- 适合变长序列(文本、语音)
- **Transformer(BERT/GPT)、RNN/LSTM、所有LLM都用LN**
### GN(Group Normalization)—— CNN小Batch救星
- 通道分组,组内归一化
- 组数=1 → 退化为 LN;组数=总通道数 → 退化为 IN
- **不受Batch Size影响**,小Batch(2,4)下表现极稳定
### IN(Instance Normalization)—— 风格迁移神器
- 对单样本单通道归一化,去除**对比度**信息只保留结构
- 用于图像风格迁移、GAN
|
|
## 归一化实战选择指南
### 终极选择逻辑
| 场景 | 选择 |
|------|------|
| 文本/序列(Transformer/RNN) | **LayerNorm** |
| 图片/视频(CNN),显存够(Batch≥32) | **BatchNorm** |
| 图片但显存小(Batch=4/8) | **GroupNorm**(num_groups=32或8) |
| 图像风格迁移/GAN | **InstanceNorm** |
### 实战避坑(写代码必读)
1. **BN + Conv2d**:`nn.BatchNorm2d` 参数是**通道数**(不是图片尺寸)
2. **BN + Linear**:`nn.BatchNorm1d` 参数是**特征维度**
3. **训练/评估必须切换**:`model.train()` vs `model.eval()`
4. **顺序**:现代主流 `Conv → BN → Activation`(先BN再激活),Dropout 加在 BN 和激活之后
### Weight Normalization(补充)
不归一化数据,而是**归一化权重向量长度**(模长与方向解耦)。与Batch Size无关,计算比BN小,但极深网络稳定收敛不如BN。
### 为什么 Transformer 用 LN 不用 BN?
- NLP 任务**序列长度不固定**(变长)
- Batch 中不同样本同一位置**没有统计学相关性**
- LN 对**单个样本所有特征**归一化,不受 Batch Size 和序列长度影响
|
|
## CNN 四大里程碑
核心逻辑:**每一次进化都为解决"网络变深"带来的新问题**。
| 维度 | LeNet(1998) | AlexNet(2012) | VGG(2014) | ResNet(2015) |
|------|-------------|---------------|-----------|--------------|
| 层数 | ~5 | ~8 | 16~19 | 34~152 |
| 杀手锏 | 开创卷积结构 | ReLU+Dropout+GPU | 3x3小核堆叠 | **残差跳跃连接** |
| 参数量 | ~6万 | ~6000万 | ~1.38亿 | ~2300万(50层) |
| 场景 | 教学/MNIST | 仅供学习 | 特征提取骨干 | **工业界主力** |
### LeNet-5 —— "Hello World"
专为手写数字识别(MNIST),首次完整使用"卷积-池化-全连接"流水线。局限:太浅只能处理灰度图。
### AlexNet —— 深度学习引爆点
ImageNet 冠军,准确率比第二名高 10%。三大革命:
1. **首次引入 ReLU**:解决 Sigmoid 梯度消失
2. **首次用 Dropout**:缓解过拟合
3. **GPU 并行训练**:分两半放两张 GTX 580
### VGG —— 小卷积核哲学
全部用 3x3:两个 3x3 堆叠等效 5x5 但参数更少非线性更多。层数 16~19 结构整齐。局限:参数极大(90% 在全连接层)。
|
|
## 从 VGG 到 Inception:从"深"到"宽"
VGG 用堆叠小卷积证明"越深越好"代价是参数爆炸。Inception 反其道:**一个模块内并行使用多种尺寸卷积核**。
### Inception v1(GoogLeNet)—— 多尺度特征
- 同一层并行用 1x1、3x3、5x5 卷积和池化,结果拼接
- **1x1 卷积降维**:在 3x3/5x5 前用 1x1 减少输入通道控制计算量
- 仅 22 层,参数只有 AlexNet 的 1/12,不到 VGG 的 1/10
### Inception 持续进化
| 版本 | 改进 |
|------|------|
| v2/v3 | **分解卷积**:5x5拆两个3x3,nxn拆1xn+nx1 |
| v4 / Inception-ResNet | 融合**残差连接**训练更稳精度更高 |
### VGG vs Inception 对比
| 维度 | VGG | Inception v1 |
|------|-----|--------------|
| 思想 | 深度至上(堆叠小核) | 宽度+效率(并行多尺度+1x1降维) |
| 优势 | 结构规整泛化好 | 参数少计算快精度高 |
| 劣势 | 参数巨大 | 结构复杂调参难 |
|
|
## ResNet 残差革命
ResNet 解决困扰学界多年的"退化问题",让网络"深不见底"。
### 解决的三大问题
| 问题 | 困境 | ResNet 解决方案 |
|------|------|-----------------|
| **退化** | 56层不如20层(训练误差都变大) | 恒等映射(跳跃连接) `输出=F(x)+x` |
| **梯度消失/爆炸** | 浅层梯度微乎其微 | 跳跃连接提供**梯度捷径** |
| **表征瓶颈** | 深层丢浅层细节 | 原始特征**跨层传递** |
### 残差结构原理
- 以前网络学 `输出 = F(x)`
- ResNet 学 `输出 = F(x) + x`(恒等映射 + 残差)
- 即使新增层啥也没学到(F(x)=0),网络至少"不比原来差"
- 梯度可通过"高速公路"直接回流浅层,**堆叠 1000 层成为可能**
### 深远影响
> 残差连接至今是 **GPT、BERT、ViT** 等所有巨型模型的核心标配——**没有残差,就没有今天的大模型**。
|
|
## ResNet 之后 + ViT/ConvNeXt(行业补充)
### DenseNet(2017)—— 特征复用极致
把前面所有层特征图**拼接(Concatenate)**(ResNet是相加)。参数极精简(增长率k=12),但显存占用极大工业部署不友好。
### MobileNet —— 让AI跑手机
**深度可分离卷积**:拆成 Depthwise(逐通道,只提空间) + Pointwise(1x1调通道)。计算量暴降 1/8~1/9。
| 版本 | 创新 |
|------|------|
| V1 | 深度可分离卷积 |
| V2 | **倒残差**(先升维再提特征再降维) |
| V3 | NAS + h-swish 激活 |
### SENet(2017冠军)—— 通道注意力
Squeeze(全局池化) + Excitation(算每通道分数) → 有用通道增强无用抑制。为后来 Transformer 自注意力埋下伏笔。
### EfficientNet(2019)—— 科学缩放
**复合缩放**:深度+宽度+分辨率三者最佳组合(用NAS搜索)。
### ViT 与 ConvNeXt(2020+,行业补充)
- **ViT**:图像切 patch 当 token,直接用 Transformer。无归纳偏置,需海量数据预训练
- **ConvNeXt**(2022):用 Transformer 理念(7x7大核、LN、GELU)**重新改进CNN**,性能媲美ViT且推理高效
> **三大基石至今通用**:①残差连接 ②1x1卷积 ③深度可分离卷积
|
|
## 为什么用 3x3 卷积?
表面看 3x3 小计算快,深层藏着**感受野、参数量、非线性**三者博弈。
### ① 参数量大幅减少
设输入输出通道都为 C:
- 一个 5x5 核参数:$5\times5\times C\times C = 25C^2$
- 两个 3x3 堆叠参数:$2\times(3\times3\times C\times C) = 18C^2$
**相同感受野(5x5)下,两层3x3比一层5x5节省28%参数**。7x7节省更多(三层3x3 vs 一层7x7:27 vs 49)。
### ② 增加非线性
两层 3x3 中间多插一个 ReLU → **两次非线性变换**,比一层 5x5 单次非线性拟合能力更强。
### ③ 参数共享更充分
小核反向传播影响局部区域更小,梯度更新更精细,利于捕捉细微纹理/边缘。
### 为什么不用 1x1 或 2x2?
- **1x1**:只调通道数**无空间信息**,只能作"瓶颈层"降维
- **2x2**:偶数核导致池化**对齐偏移**,3x3 有明确中心像素对齐最好
### 与残差结构完美契合
经典残差块:`3x3 Conv → BN → ReLU → 3x3 Conv → BN → Add`。换 5x5 参数膨胀无法堆叠很深。
|
|
## 1x1 卷积的作用(面试必问)
课件反复提到 1x1 降维但没系统讲。1x1 卷积(Pointwise Conv)三大作用:
| 作用 | 说明 |
|------|------|
| **① 降维/升维** | $1\times1\times C_{in}\times C_{out}$,不改变 H/W 调整通道。Inception/ResNet 瓶颈层核心 |
| **② 增加非线性** | 1x1 后接 ReLU,引入额外非线性变换提升表达力 |
| **③ 跨通道融合** | 相当于每像素位置做全连接,融合不同通道信息 |
### 在 ResNet 瓶颈层(Bottleneck)的应用
ResNet-50 用 `1x1 → 3x3 → 1x1` 结构:先用 1x1 降维(减计算)→ 3x3 提特征 → 1x1 升维恢复。大幅降低计算量。
### 在深度可分离卷积中
MobileNet 的 Pointwise 就是 1x1 卷积,负责通道变换。
```python
import torch.nn as nn
# 1x1 卷积:通道从 256 降到 64
conv1x1 = nn.Conv2d(256, 64, kernel_size=1)
```
|
|
## 空洞卷积与深度可分离卷积
### 空洞卷积(Dilated Convolution)
- 卷积核中插入空洞,**不增加参数量**前提下**指数级扩大感受野**
- 用于语义分割(DeepLab 系列)
- **缺点**:栅格效应(Gridding Effect),丢失局部连续信息
直觉:3x3 核设 dilation=2,实际看到 5x5 范围但仍是 9 个参数。
### 深度可分离卷积(Depthwise Separable Conv)
MobileNet 核心杀手锏。传统卷积"一步到位"同时处理空间+通道,深度可分离拆两步:
**① Depthwise(逐通道卷积)**:每个核只负责一个输入通道,只提取空间特征不改变通道数
**② Pointwise(逐点卷积)**:用 1x1 卷积调整通道数
### 计算量对比
- 普通卷积参数:$D_k^2 \times M \times N$(核大小×输入通道×输出通道)
- 深度可分离:$D_k^2 \times M + M \times N$
- 比例约 $\frac{1}{N} + \frac{1}{D_k^2}$,约 **1/8 ~ 1/9**
> 面试常考:"深度可分离卷积计算量是普通卷积的多少?" 答:约 1/8~1/9。
|
|
## 全局平均池化(GAP)与感受野
### GAP vs 全连接层
全局平均池化(GAP):对整个特征图(H×W)求平均,得 1×1×C。比全连接层优势:
| 优点 | 说明 |
|------|------|
| **大幅减参** | 全连接占 VGG 90% 参数 |
| **强制特征-类别对应** | 每个通道直接对应一类,更直观 |
| **防过拟合** | 无额外参数 |
GoogLeNet 用 GAP 替代全连接,大幅减参。
### 感受野(Receptive Field)
定义:特征图上一个像素对应输入图像的区域大小。
- 层数越深感受野越大
- 堆叠 3x3(stride=1) 两层感受野 5x5,三层 7x7
- 下采样(stride=2 或池化)会翻倍感受野
### VGG 实验的关键发现
堆叠小卷积核不仅效果更好(分类准确率更高),参数量还更少!从此 3x3 成为 CNN 黄金标准。
### 实战建议
- 绝大多数隐藏层:`kernel_size=3, padding=1, stride=1`
- 网络第一层处理大图(224+):可沿用 ResNet `kernel_size=7, stride=2` 快速下采样
- 语义分割扩大感受野:空洞卷积 `dilation=2`,3x3 看 5x5
|
|
## 一阶段 vs 二阶段检测
CV 面试必考,区分"初学者"和"有实战经验"的分水岭。核心:**"先粗后精" vs "一步到位"**。
### 生活化类比
| 类型 | 类比 | 优缺点 |
|------|------|--------|
| **两阶段(Faster R-CNN)** | ①先把像肉块盘子筛出(候选框) ②拿近仔细确认(精细分类回归) | 准但慢 |
| **一阶段(YOLO/SSD)** | 直接扫视全桌瞬间判断 | 快但易眼花 |
### 技术原理
**两阶段(精度优先)** 代表 R-CNN 家族:
1. RPN 从原图提取几百个候选框
2. 候选框特征图送 FC 判断类别+微调位置
- 优点:误检率低小目标精度优;缺点:5~15 FPS 难上移动端
**一阶段(速度优先)** 代表 YOLO/SSD/RetinaNet:
1. 特征图每网格预设几十万 Anchor
2. 一次性完成所有框类别预测和位置回归
- 优点:YOLOv8 可达 30~100+ FPS;缺点:正负样本极度不平衡易漏检
### 两种范式根本区别
> "两者最大区别在于是否有独立的区域建议(Region Proposal)阶段。两阶段通过RPN粗筛再精细分类回归精度高但慢;一阶段直接密集分类回归极快但面临正负样本不平衡。"
|
|
## 为什么一阶段早期精度不如二阶段?Focal Loss
### 根本原因:正负样本极度不平衡
- 二阶段 RPN 先把几十万框筛到几百个,正负比例约 **1:3** 好训练
- 一阶段处理几十万框,**99.9% 是背景(负样本)**,模型会"学偏"全判背景精度崩盘
### Focal Loss(RetinaNet 2017 的贡献)
降低"简单易分样本"(纯背景)的损失权重,让模型**专注训练"难分"样本**。
标准交叉熵:$\text{CE}(p_t) = -\log(p_t)$
Focal Loss:
$$\text{FL}(p_t) = -(1-p_t)^\gamma \log(p_t)$$
- $(1-p_t)^\gamma$ 是调制系数:$p_t$ 越大(越易分),系数越小损失越小
- $\gamma$ 通常取 2,控制衰减力度
### 效果
有了 Focal Loss 后,一阶段精度**首次追平二阶段**,同时速度依然快很多。这是一阶段检测器的转折点。
> Focal Loss 不仅用于检测,还广泛用于任何**类别极不平衡**的分类任务。
|
|
## 目标检测实战选型
### 应用场景对照
| 场景 | 推荐方案 | 理由 |
|------|----------|------|
| 在线视频/手机端/自动驾驶(实时) | 一阶段 **YOLOv8/NanoDet** | 速度大于一切,YOLO精度已足够 |
| 医学影像/工业缺陷(误判代价极高) | 二阶段 **Faster R-CNN/Cascade R-CNN** | 宁漏检不误检,精度稳定画框精细 |
| 需要分割掩膜(实例分割) | **Mask R-CNN** | 先检测再分割像素,天然两阶段 |
### 工业经验
- **移动端/实时**选 YOLO(v5/v8),精度速度平衡好
- **高精度场景**选 Cascade R-CNN(多级级联提升精度)
- **实例分割**选 Mask R-CNN 或 YOLOv8-seg
### 正负样本划分(匹配策略)
通常以 **IoU 阈值**划分:
- 与真实框(GT) IoU > 0.7 的 Anchor 为**正样本**
- IoU < 0.3 为**负样本**
- 中间的**忽略**(不参与训练)
- YOLO 系列用**中心点落入网格**方法分配正样本
|
|
## 行业补充:Anchor-Free 与 DETR
课件多次提"Anchor-Free"和"DETR"是未来方向但没展开,是检测 2019 后最大变革。
### Anchor-Based vs Anchor-Free
| 维度 | Anchor-Based | Anchor-Free |
|------|--------------|-------------|
| 代表 | Faster R-CNN、YOLOv2/v3 | FCOS、CornerNet、**YOLOv8** |
| 候选框 | 预设先验框需人工设计 | 直接预测关键点/中心点 |
| 优点 | 成熟稳定 | 避免调参结构更简洁 |
| 缺点 | Anchor尺寸不符性能骤降 | — |
### FCOS(全卷积一阶段)
不用 Anchor,每像素点直接预测到边界框四条边的距离(l,t,r,b)+类别+centerness(中心度)。
### DETR(2020)—— Transformer 颠覆检测
- 把目标检测看作**集合预测问题**,Transformer 直接输出固定数量检测结果
- **彻底抛弃 Anchor 和 NMS**,真正端到端
- 用**二分图匹配(匈牙利匹配)**把预测框和真实框一一对应保证无重复
- 优点:简洁可解释;缺点:训练收敛慢(需500+epoch)
### DETR 演进
| 版本 | 改进 |
|------|------|
| Deformable DETR | 可变形注意力,加速收敛+多尺度 |
| DINO | 性能 SOTA |
> YOLOv8(2023) 已吸收 Anchor-Free 思想、解耦头、DFL(Distribution Focal Loss) 等现代技术。
|
|
## R-CNN 家族演进
四代演进逻辑:**如何把"候选框提取"和"特征提取"做得越来越高效统一**。
### R-CNN(开创者,极笨重)
- 选择性搜索(Selective Search)暴力提取约 2000 候选框
- 每个框缩放 227x227 **分别**送 CNN 提特征,SVM 分类
- **致命缺点**:一张图 40~50 秒、特征冗余巨大、训练割裂
### Fast R-CNN(强心针)
- **CNN 只跑一次**:整图送 CNN 得全局特征图,候选框在特征图上映射
- **RoI 池化层**:不同大小候选框统一池化成固定尺寸(7x7)
- 比R-CNN快200倍(训练)/40倍(推理)
- **遗留痛点**:候选框仍依赖CPU选择性搜索(每张约2秒)
### Faster R-CNN(里程碑)
- **扔掉选择性搜索,引入 RPN**
- RPN 轻量级全卷积,在共享特征图上 3x3 滑窗,预设9种Anchor,判断"有东西/背景"
- 2秒/张 → **0.2秒/张(5 FPS)**,真正端到端
### Mask R-CNN(框→像素)
- 第二阶段**并行添加像素级分割分支**
- RoI Pooling 升级为 **RoI Align**(解决像素错位)
- 既能检测(框)又能实例分割(像素边缘)
|
|
## RoI Pooling 与 RoI Align
### RoI Pooling 的问题
在区域映射时把浮点数坐标**两次取整(量化)**,导致特征图与原图像素有约 1~2 像素偏差。
- 对分类(框)影响不大
- 对**像素级分割(Mask)** 1像素偏差会让边缘锯齿严重,IoU 下降
### RoI Align 的改进
- 去掉取整操作,**保留浮点数坐标**
- 利用**双线性插值**填充非整数位置的像素值
- 保证空间精确度,分割效果细腻
### 为什么 Mask R-CNN 必须用 RoI Align?
```
RoI Pooling: 浮点坐标 → 取整 → 取整 → 两次量化 → 1~2px偏差
RoI Align: 浮点坐标 → 保留 → 双线性插值 → 无偏差
```
> 这是 Mask R-CNN 最佳论文的核心贡献之一。面试官常问:"Mask R-CNN 不仅仅是加了Mask分支,它为什么把RoI Pooling换成RoI Align?" 答:解决量化取整导致的像素错位。
|
|
## RPN 替代了什么
RPN 替代了 R-CNN/Fast R-CNN 中的**选择性搜索(Selective Search)**。
### 选择性搜索的缺陷
- 基于颜色/纹理/亮度等**手工特征**,金字塔分层分割生成约2000框
- **计算在CPU**单张1~2秒
- **不可学习**无法针对特定数据集优化
- 成为整个网络的"速度瓶颈"
### RPN 的优势
| 维度 | 替代前(SS) | 替代后(RPN) |
|------|------------|-------------|
| 性质 | 固定先验规则 | **可训练神经网络** |
| 计算 | CPU 1~2秒 | **GPU 0.01秒级** |
| 与检测器关系 | "盲盒"被动接受 | Loss反向传播**教会RPN画框** |
| 迁移学习 | 不能 | **能**(微调学习新数据分布) |
### 深远影响
RPN 标志候选框生成从"依赖人工规则的离线计算"进化为"融入神经网络可在线学习的GPU模块"。
> **面试追问**:RPN 引入了新手工成分(Anchor 尺度/长宽比),Anchor 与数据集物体不符性能骤降——这正是后来 **Anchor-Free**(FCOS、CornerNet) 出现的原因。
|
|
## R-CNN 演进逻辑总结(面试必背)
| 模型 | 核心创新 | 解决痛点 | 遗留问题 |
|------|----------|----------|----------|
| **R-CNN** | CNN提候选框特征 | 替换HOG/SIFT | 极慢、训练割裂、输入固定 |
| **Fast R-CNN** | 共享卷积+RoI Pooling | CNN只跑一次 | 候选框提取仍是CPU瓶颈 |
| **Faster R-CNN** | RPN | 候选框融入GPU,**真正端到端** | Anchor需人工设计,依赖NMS |
| **Mask R-CNN** | RoI Align+Mask分支 | 像素错位,**统一检测+分割** | 计算量更大 |
### 一句话记住每代核心
- R-CNN = **开开创**(CNN提特征,但极慢)
- Fast R-CNN = **享共享**(CNN只跑一次+RoI Pooling)
- Faster R-CNN = **学学习**(RPN让候选框生成可学习)
- Mask R-CNN = **准精准**(RoI Align+像素级分割)
### 下一步演进方向
Faster R-CNN 奠定二阶段巅峰,但依赖 Anchor 和 NMS。SOTA 已往 **Anchor-Free** 和 **End-to-End(无NMS)** 发展,如 CornerNet、FCOS、DETR(Transformer彻底颠覆)。
|
|
## YOLO v1 / v2 / v3 的改进
演进核心:**保持速度优势同时补齐精度短板**。
### YOLOv1 —— 开创性"一步到位"
- 把检测看作**回归问题**,输入图划分 7×7 网格,每网格预测 2 框 + 类别概率
- 优势:极快(Titan X 45 FPS),看整张图不易误判背景
- 短板:每网格只 2 框 1 类,难处理成群小目标,定位不准
### YOLOv2 —— "Better, Faster, Stronger"
- **引入 Anchor**(借鉴Faster R-CNN),预测相对偏移降低学习难度
- **K-means 聚类**自动找最适合数据集的 Anchor 尺寸
- **Batch Normalization** 加速收敛替代 Dropout
- **多尺度训练**:每10迭代随机换输入尺寸(320/416)更鲁棒
- 全卷积(移除FC),新骨干 Darknet-19
### YOLOv3 —— 走向成熟,多尺度预测
- **多尺度预测**(最大亮点):借鉴 FPN,3尺度独立检测
- 13×13(感受野大)→大目标
- 26×26→中目标
- 52×52(感受野小)→**小目标**
- 每尺度3个Anchor共9种,大幅提升召回
- **Darknet-53** 骨干:借鉴ResNet残差结构,53层解决梯度消失
- Logistic 回归替代 Softmax 支持多标签
### 三句话精炼总结
> **v1** 开创性将检测重构为端到端单次回归,极致速度但小目标召回低。
> **v2** 引入Anchor+K-means+BN+多尺度训练,显著增强小目标与多尺度能力。
> **v3** 三尺度FPN预测+Darknet-53残差骨干,奠定YOLO高精度实时检测标杆。
|
|
## NMS(非极大值抑制)原理
NMS 是目标检测"最后守门员":在众多重叠候选框中剔除冗余框,只保留最准的一个。
### 算法三步走
输入:N 个候选框(坐标 + 置信度)。
1. **按置信度排序**:分数从高到低
2. **循环**:选当前最高分框放入输出,计算它与所有剩余框的 **IoU**(交集面积/并集面积)
- IoU > 阈值(0.5/0.7) → 丢弃(冗余)
- IoU < 阈值 → 保留待后续
3. **重复**直到所有框处理完
### 举例
一只狗 3 个候选框 A=0.95, B=0.75, C=0.55:
- 选 A 输出;A与B的IoU=0.85 > 0.5 → 丢弃B
- A与C的IoU=0.9 > 0.5 → 丢弃C
- 最终只留 A
### 为什么非用不可?
- **消除冗余**:检测算法为不漏检会在同物体周围生成成百上千框
- **提高输出质量**:确保每物体只对应一个最准结果,便于下游(追踪/行为识别)
|
|
## NMS 阈值的影响(面试高频)
> 口诀:**阈值高,框多(挑剔);阈值低,框少(粗暴)**。
因为 NMS 逻辑是 `IoU > 阈值 = 干掉`:
### 阈值高(0.9)—— 挑剔
不等式 `IoU > 0.9` 极难成立,难有框被干掉,候选框大量保留 → **召回高、误检多**。
- 0.85分的框和0.95分框重叠度只有0.88没超0.9,不删,图上乱糟糟
- 适合**安防监控**(宁误报不漏小偷)
### 阈值低(0.3)—— 粗暴
不等式 `IoU > 0.3` 极易成立,绝大多数框被干掉 → **精确高、易漏检**。
- 只要重叠0.3就删,只剩0.95的框其他全没
- 适合**自动驾驶**(障碍物漏检后果严重,需调试到既能去重又不漏检)
### 工业默认
通常 **0.5 或 0.45** 起步,按验证集最佳 **F1-score**(精确率和召回率调和平均)调整。
### NMS 三大局限
1. **对IoU阈值敏感**:高→误检多,低→漏检多
2. **速度瓶颈**:Python循环处理上万框拖慢推理
3. **完全依赖置信度**:最高分框若定位不准会干掉定位准但分数稍低的框
|
|
## NMS 改进版本
### Soft-NMS(软化版)
- 传统NMS:IoU > 阈值直接暴力删除(分数归零)
- **Soft-NMS**:不直接删除,而是**降低**重叠框的置信度(乘衰减系数)
- 这样靠得近的两个物体(如拥抱的两人)仍有机会被选出
公式(线性衰减):$s_i = s_i(1 - \text{IoU}(M, b_i))$
### DIoU-NMS
在 IoU 基础上加入**中心点距离**,保留更准的框。
### Weighted NMS
把重叠框坐标**加权平均**,输出更精确的框。
### NMS 改进总结
| 版本 | 核心改进 | 解决问题 |
|------|----------|----------|
| **Soft-NMS** | 降低置信度而非删除 | 靠近物体被误杀 |
| **DIoU-NMS** | 加中心点距离 | 保留更准的框 |
| **Weighted NMS** | 坐标加权平均 | 输出更精确 |
> **面试金句**:"非极大值抑制是目标检测用于去重的后处理算法,通过选置信度最高的框,基于IoU阈值剔除高度重叠的冗余框,确保每目标只输出一个最优结果。"
|
|
## 优化器与学习率
### 优化器选择
| 优化器 | 特点 | 适用 |
|--------|------|------|
| **SGD + Momentum** | 泛化性好 | **CV**(ResNet系列) |
| **Adam** | 收敛快,自适应学习率 | **NLP/Transformer** |
| **AdamW** | 修正Adam的L2正则化失效 | **大模型首选**(GPT/LLaMA) |
**AdamW 为什么取代 Adam?** Adam 把权重衰减和梯度更新耦合导致 L2 正则化打折。AdamW **解耦权重衰减**正则化更有效。
### 学习率衰减策略
| 策略 | 说明 |
|------|------|
| 阶梯衰减 Step | 每 N epoch 乘 γ |
| **余弦退火** | 余弦曲线降到接近0,**现代主流** |
| 指数衰减 | 每 epoch 乘固定系数 |
| ReduceLROnPlateau | 验证集不涨点自动降 |
| **Warmup** | 前期线性升后期衰减,**Transformer/LLM必用** |
### 权重初始化
| 方法 | 适用 | 原则 |
|------|------|------|
| **Xavier(Glorot)** | Sigmoid/Tanh | 保持前向/反向方差一致 |
| **He(Kaiming)** | ReLU及变体 | 针对ReLU调整方差 |
原则:保持前向传播和反向传播时方差一致,否则信号会爆炸或消失。
### 过拟合解决办法
数据增强(翻转/裁剪/MixUp/CutMix)、Dropout、早停法、权重衰减(L1/L2)、Batch Normalization。
|
|
## 行业补充:反向传播与梯度问题
课件提"梯度消失/爆炸"但没讲反向传播原理,是面试基础必问。
### 反向传播(Backpropagation)本质
反向传播 = **链式法则**在计算图上的应用。
前向:$z = wx + b \to a = \sigma(z) \to \mathcal{L}$
反向求梯度:$\frac{\partial\mathcal{L}}{\partial w} = \frac{\partial\mathcal{L}}{\partial a}\cdot\frac{\partial a}{\partial z}\cdot\frac{\partial z}{\partial w}$
### 梯度消失的数学解释
以 Sigmoid 为例,每层梯度含 $\sigma'(z) \le 0.25$。n 层连乘:
$$\prod_{i=1}^{n}\sigma'(z_i) \le 0.25^n \to 0$$
浅层梯度接近 0 权重不更新。
### 残差连接为什么能解决梯度消失
ResNet:$y = F(x) + x$,求导:
$$\frac{\partial y}{\partial x} = \frac{\partial F(x)}{\partial x} + 1$$
那个 **"+1"** 保证梯度至少为 1,不会连乘消失——这就是"梯度高速公路"。
### 梯度裁剪(Gradient Clipping)
梯度 > 阈值时按比例缩放防爆炸:
```python
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
```
是 Transformer/RNN 训练**标配**。
### 解决梯度问题全景
| 方法 | 解决 |
|------|------|
| BN | 缓解消失/爆炸 |
| 残差连接 | 梯度捷径 |
| 梯度裁剪 | 防爆炸 |
| ReLU 激活 | 正区梯度恒1 |
| 合适初始化 | 保持方差 |
|
|
## Transformer 与 NLP 考点(CV岗也必问)
因 ViT 和 DETR 兴起,面试官默认你懂 Transformer。
### Self-Attention 公式与复杂度
$$\text{Attention}(Q,K,V) = \text{softmax}\left(\frac{QK^\top}{\sqrt{d_k}}\right)V$$
- **复杂度** $O(n^2\cdot d)$(n为序列长度),处理长序列的瓶颈
- 为什么除以 $\sqrt{d_k}$?防点积过大导致 softmax 进入饱和区(梯度消失)
### 为什么用 LayerNorm 不用 BatchNorm?
- NLP 任务**序列长度不固定**(变长)
- Batch 中不同样本同一位置**没有统计学相关性**
- LN 对**单个样本所有特征**归一化,不受 Batch Size 和序列长度影响
### 位置编码(Positional Encoding)
- Self-Attention 本身**无序**(置换不变性),不加位置编码打乱词序输出不变
- 位置编码注入单词**相对/绝对位置信息**
- 分绝对位置编码(正弦/学习式)和相对位置编码(**RoPE**,LLaMA用)
### ViT vs CNN 本质区别
| 维度 | CNN | ViT |
|------|-----|-----|
| 归纳偏置 | 平移不变性、局部性(强) | 几乎无(弱) |
| 数据需求 | 小数据学好 | 需海量数据预训练 |
| 全局/局部 | 局部为主 | 全局Attention |
|
|
## 模型部署与轻量化
涉及 AI 芯片、移动端,大厂高频。
### 模型量化(Quantization)
权重和激活从 **FP32 → INT8**,内存减4倍,推理速度提升2~4倍。
| 类型 | 说明 |
|------|------|
| **PTQ(训练后量化)** | 训练完直接量化,简单快速精度略降 |
| **QAT(量化感知训练)** | 训练时模拟量化误差,精度更高 |
### 剪枝 vs 蒸馏
| 方法 | 做法 |
|------|------|
| **剪枝(Pruning)** | 去掉冗余神经元/通道,减小体积 |
| **蒸馏(Distillation)** | 大模型(教师)教小模型(学生),学生模仿软标签输出分布 |
### ONNX 与 TensorRT
| 工具 | 作用 |
|------|------|
| **ONNX** | 开放模型交换格式,打通 PyTorch/TF |
| **TensorRT** | NVIDIA推理加速库,图优化+算子融合大幅提速 |
### 部署工具链流程
```
PyTorch模型 → 导出ONNX → TensorRT优化 → GPU部署
↘ OpenVINO → CPU部署
↘ NCNN/MNN → 移动端部署
```
### 面试回答技巧
1. **STAR原则**:带场景,如问过拟合说"我训练ResNet时验证集loss 10epoch后上升,用Dropout+早停解决"
2. **量化思维**:多用数字"Batch Size=32""学习率1e-4"
3. **对比思维**:先抛本质区别再细化
|
PyTorch nn 文档
ResNet 论文
YOLO v1 论文