激活函数
## 激活函数总览 激活函数核心作用:**为神经网络引入非线性**。没有激活函数,无论多少层都只能学线性关系,无法处理复杂问题。 ### 经典激活函数 | 函数 | 公式 | 范围 | 优点 | 缺点 | 适用 | |------|------|------|------|------|------| | **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架构演进
## 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与RPN
## 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与NMS
## 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 论文