阶段 2 · 看懂图像

没数据,就制造数据

上一章《经典 CNN 家族》的模型,胃口都一样:数据。ImageNet 光人工标注就花了两年多、几万人、上百万次。 但真实场景里你手上可能只有 500 张图。
这一章讲两个让"500 张图当 5 万张用"的办法:数据增强和迁移学习。

1

模型学的是"位置",不是"猫"

假设你训练集里所有的猫都在图片正中间。会发生什么?

网络会学到一个偷懒的规律:"中间那一片有毛茸茸的东西就判成猫"。 你给它一张猫在角落的图,它一脸茫然——不是它笨,是你从来没教过它"猫可以在别的位置"。

模型只会对它见过的样子保持鲁棒(见过的猫在见过的样子里,它认;侧躺、暗光、被挡一半,它就不认)。 你没给它看过的变化,它就不会处理。 数据增强 = 主动把这些变化"造"出来,逼模型学到真正本质的东西。

🎯 类比

教小孩认猫。如果你只给他看正对着、白天、在沙发上的猫的照片, 他见到一只侧躺着的黑猫可能就不认识了。
聪明的老师会给他看:各种角度、各种光线、被遮挡一半、趴着躺着的猫。 小孩学到的就不是"沙发上的那个东西",而是"猫"这个概念本身。

2

亲手造一张:真实的像素级变换

下面的沙盘是两张 32×32 的小图(3 个颜色通道,就是 32×32×3):一张猫、一张鱼。开 Mixup 时,鱼会按比例叠到猫上。 每一张效果都是逐个像素算出来的——勾选任意组合,看它们叠加。 这些变换是训练时临时做的、不占硬盘:所谓"500 张图当 5 万张用",就是同一张图每轮看到的版本都不一样。

互动 · 数据增强沙盘(所有变换都是实时像素运算)

原图

增强后

💡 这一章的答案,就藏在这个沙盘里

上面那张猫图你随便折腾,只有一行字会跟着变——标签。四类变换里,只有混合类会改它。 ① 只开水平翻转:图片变了,但标签完全不用改——翻过来的猫还是猫。
② 开旋转 180°:这里要小心。如果任务是"识别数字",旋转 180° 的 6 会变成 9, 标签就没法照旧。所以"哪些变换可用"取决于任务。
③ 开 Mixup:图片变成两张的叠加。盯着下面那行标签——它也跟着变成了两个类别的加权和。 (标签写成 [1.00 猫, 0.00 鱼] 这种方括号形式:每个类别一格,分数加起来是 1。)

3

四类增强方法,只有一类要改标签

示意图 · 同一张猫图,四类增强各做了什么

类别代表方法改什么标签要改吗
几何变换 翻转 · 旋转 · 裁剪 · 缩放 · 仿射(放大缩小、拉伸斜切) 像素的位置 不用改(物体还是那个物体)
颜色变换 亮度 · 对比度 · 饱和度 · 色调抖动(把整体颜色往某个方向偏)· 灰度化 像素的值 不用改
遮挡 / 擦除 Cutout · Random Erasing · Grid Mask 随机挖掉一块 不用改(逼模型别只依赖局部)
混合 Mixup(按比例逐像素相加)· CutMix(剪一块贴过去,标签按面积比例混)· Mosaic(拼四张)· Copy-Paste(抠出物体贴过去) 把两张图混在一起 要改——标签变成加权组合

把猫和鱼叠在一起、标签写成 [0.6 猫, 0.4 鱼],听起来像在教模型说胡话。它其实做了一件很聪明的事: 逼着模型输出"70% 像猫、30% 像鱼"这种平滑、有刻度的判断,而不是非猫即鱼的硬判决。 普通训练下模型容易过度自信,遇到模棱两可的样本就给极端概率; 现在它得在靠近分界线时给一个中间的把握。分界线就是决策边界(模型在"猫"和"鱼"之间划的那条线), 这么一混,它变平滑了,泛化反而更好。

4

迁移学习:站在别人的肩膀上

数据增强解决"多样性不够"。但如果你只有 500 张图,再怎么增强也不够从零训练一个网络。 这时要用另一个办法:拿一个在百万张图上训练好的模型,改一改用在你的任务上——在预训练权重上接着训, 不管解冻多少,都叫微调。分类头(代码里写作 fc)是网络最后那一层,把前面抽出的特征翻成"每一类各得多少分"。

下面的真实数字按换成猫/鱼两类新头之后的模型(约 23.5M 参数)算;预训练的 ResNet-50 本身是 25.6M。再下面那张 13 层方块图是一个简化的小网络,只用来看"哪一层学到什么"。

为什么能迁移:网络的不同层学到的东西不一样(「可复用度」是示意刻度)

浅层学到的东西跨领域大体还能用,深层学到的东西只认原任务。 边缘、颜色块、纹理——不管是自然照片还是 X 光片,都是这些,所以前面几段可以冻住复用; 越往深,越是"猫耳朵检测器""胡须检测器"这种只对原任务有用的东西,必须换掉重训。 跨度也不能太大:自然图像迁到医学影像,整体收益比在同领域里迁移小得多(2019 年 Raghu 等人的研究 Transfusion)。

互动 · 三种微调策略的真实代价

可训练参数
—
占总参数
—
优化器状态(粗估)
—
👆 先悬停,再切那个按钮

把鼠标移到公式卡里的 P 上——上面那排「微调策略」按钮会亮起来。然后在「只换分类头 / 解冻最后 N 段 / 全量微调」之间切一遍, 盯着「优化器状态」那个数:它从 49 KB 一路涨到 282 MB,而模型一个参数也没变多。
这里只算优化器状态(每个可训练参数 12 字节:梯度、一阶动量、二阶动量各 4 字节);权重本身和中间结果另算。

策略改哪些层什么时候用风险
只换分类头冻结全部,只训新换上的分类头(2 类 = 4,098 个参数) 新任务和原任务很像(都是自然图像分类),数据很少(几百张) 如果两个领域差太远,前面的特征根本用不上
解冻最后 N 段训最后几段 + 分类头 最常用的折中。领域有差异但不完全陌生 N 怎么选要试
全量微调所有层都训(全部解冻) 数据够多(几万张以上),或者领域差异大(自然图像 → 医学影像) 数据少时几轮就过拟合;容易遗忘预训练学到的通用能力
从零训练不用预训练权重 只在你有百万级数据、且领域极其特殊(比如雷达图)时才考虑 几乎总是更差。除非数据量真的很大,否则不要这么做。
5

一个魔改细节:学习率要分层设

全量微调(全部解冻)时如果所有段用同一个学习率,效果往往不好。原因是: 浅层已经学得很好了,你不想大改;深层需要为新任务重新学习,需要大改。

浅层学习率 = 基础学习率 × 0.1  (只做微调)
深层学习率 = 基础学习率 × 1.0  (放开改)
这叫"判别式学习率"(discriminative learning rates),几行代码就能开

互动 · 每一层的实际学习率:浅层小、深层大

⚠️ 但预训练权重有个坑:归一化的统计量

BatchNorm 层里存着"均值"和"方差"这些统计量,它们是在原来的数据集上算出来的。 如果你的新数据集和原来差别很大(比如原来是彩色自然图,你的是灰度高对比医学图), 这些统计量就是错的——会严重拖累效果。
解法:把 BatchNorm 也放开训练(哪怕其它层冻结),或者在新的小数据集上重新估计。

M

数学 · 混一张图,和冻一层楼

这一章的两个办法,各只有一条式子。这里看「混合」那条;「冻结」那条在第 4 节那张公式卡里。 用的是 §2 沙盘里那两张 32×32 的猫和鱼——拖一下 λ,符号行里的 λ 跟着变,卡里那张混出来的小图也会重画。

互动 · 混合的数学:两张图按一个比例,逐像素加起来

公式卡 · 混合的公式,和它的像素级图解

互动 · 那个混合比例从哪来:从一条分布里随机抽

💡 这就是「哪些增强要改标签」那条分界线

几何、颜色、遮挡都只是把像素搬家或改值——猫还是猫,标签一个字不用动。 Mixup 真的把两张图的每个像素加起来,所以标签也必须跟着变成 [λ 猫, 1−λ 鱼]: 上面那条分两色的条就是它。「混合类必须改标签」这句话,画出来就是那条条。

6

这两个办法都会骗你

示意图 · 同一个旋转 180°,两个任务两种下场

陷阱怎么回事
增强用错了会伤效果 旋转 90° 对数字识别是破坏性的;颜色抖动对"辨别颜色"的任务是破坏性的。 增强必须符合"这个变化不应该改变标签"这个前提。 拿不准就先想一个问题:这个变化在真实数据里会不会出现、该不该改答案;再在验证集上比开、关两种训练的效果。
训练和验证的增强不一致 验证集通常只做中心裁剪(从图中间裁一块,不随机)、不做随机增强(因为要可复现)。 如果两边都乱加,指标会剧烈跳动,你根本分不清是模型变好了还是随机性。 那用 Mixup 训练、验证时也混两张图吗?不混——验证一律用原图。
迁移学习会掩盖数据问题 预训练权重太强了,它能让一个标注得很烂的数据集也跑出不错的指标。 指标好看不等于数据没问题。
训练集和测试集"泄漏" 用预训练模型 + 你自己的数据时,如果预训练数据里恰好包含了你的测试集图片, 指标会虚高。这在用大规模网络数据预训练的模型上越来越常见。 怎么防:先看模型卡(模型发布时附带的一份说明,写了它是用什么数据训出来的);还拿不准就做去重——比较图片的哈希或特征,把和测试集重复的图找出来。
以为增强等于有更多数据 增强提供的是"已知的变化",它造不出全新的信息。 500 张猫的增强版仍然是那 500 张猫——缺的品种、姿势、光照它补不上
7

小结

这一章和上一章(CNN)回答的是同一道题,只是换了答卷的位置。

它对应哪条线 ② 没有免费午餐 → 必须有归纳偏置——但这一章是从数据那一侧回答它的: CNN 把“邻近像素更相关”焊进结构,数据增强则把“旋转不重要、颜色不重要”写进样本。 同一个假设,两种投入方式。
一句话 数据增强和迁移学习,都是在替模型提前回答“哪些变化不该改变答案”—— 然后把这份答案以样本(增强)或权重(迁移)的形式交给它。
它牺牲了什么 牺牲了“我不知道的东西也能自动学到”这件事。 增强只能造出你已经知道该忽略的变化;更危险的是,假设写错会直接教坏模型—— 把数字 6 旋转 180° 就变成了 9。
🎬 自己验一遍

回到第 2 节那个增强沙盘,切两下:把「旋转」切成 180°——对猫/鱼来说,猫转 180° 还是猫,标签不用改, 那行字还是 [1.00 猫, 0.00 鱼];可要是做数字识别,6 转 180° 就成了 9,标签必须跟着变——第 6 节那张对照图画的就是这两种下场。 再把「混合方式」切到 Mixup、λ 拉到 0.6——标签当场变成 [0.60 猫, 0.40 鱼]。 两下的差别就是这一章的重点:标签的每一处改动,都来自你事先写进数据的一条断言(旋转在这个任务里不该改答案 / 两张图可以叠加),算法本身一个字没改。

它在暗线里站在哪

暗线这一章的回答
信息流动 形状全程不变:增强是 32×32×3 进、32×32×3 出;变的是标签——几何/颜色/遮挡不动它, 混合类把它变成软标签 [λ, 1−λ];被冻结的层梯度恒为 0
参数账本 增强不加参数,只多花算力;迁移的账全在优化器状态上:换成猫/鱼两类新头后的模型约 23.5M 参数, 只换分类头只训 4,098 个(0.02%),优化器状态从 282 MB 掉到 49 KB
跑在什么上 增强的瓶颈常在数据加载(CPU / 硬盘 IO),所以工业界把它搬到 GPU 上做; 迁移是显存受限——冻结层省的就是每参数 12 字节的梯度 + 优化器状态
它假设了什么 假设你手里有一份“不变性清单”,而且源任务的浅层特征对你还能用—— 跨度一大(自然图 → 医学影像)收益就缩水
违背了哪个直觉 两条:把两张图叠成一团、标签也混着写,居然能提升泛化;用别人的权重不是“不干净”,实测通常更好
🎯 前后钩子

它接住了上一章的什么:《经典 CNN 家族》列了 CNN 的两大代价—— 「需要海量标注」和「归纳偏置太强」。这一章从数据那一侧回应前者:增强和迁移让「海量标注」不再是硬门槛。

它给后面留了什么:下一章《目标检测》接着算这笔账—— 分类只点一下,画框要贵得多;而更后面的自监督(《自监督与对比学习》) 把“造变化”交给模型自己(遮住一块重建),那正是大模型预训练的地基。

一句话带走这两件事

数据增强 = 主动把"不应该改变标签的变化"造出来,逼模型学本质而不是学位置。 四类方法:几何、颜色、遮挡、混合。
迁移学习 = 拿别人在百万张图上训好的权重,浅层的边缘和纹理还能用,冻住复用; 深层是任务专用的,换掉重训。三种策略:只换分类头 / 解冻最后 N 段 / 全量微调。
两者都会骗你:增强可能破坏标签含义,预训练会掩盖标注问题。 指标好看不等于数据没问题。

8

拓展阅读

上面讲的都是「够用」的版本。想往下挖,这里有三个入口—— 它们不是必修内容,是给想再往前走一步的读者准备的。

📄 这一章的说法从哪来

💻 工业界怎么写

∑ 更严格的形式