你能向一张图片提出的最简单问题
在你能就一张图像向计算机提出的所有问题中,最基础的也是研究最多的:「这是一张什么的图片?」你给机器看一张照片,它返回一个词——猫、消防车、金毛寻回犬。这就是 图像分类,现代计算机视觉最先在这项任务上得到验证,至今仍以它为基准。上一篇你已经认识了「图像即张量」;这里我们要问的是:拿到这个张量之后,究竟该拿它*做什么*。
从机制上看,分类就是一套披着视觉外衣的、我们熟悉的 监督学习。输入的 特征 是一格格像素数字组成的网格;标签 则是从设计者预先选定的固定清单中取出的一个类别。网络的任务,是把这张网格变成一个分数向量——每个类别一个分数——再由 softmax 把这些分数转成加和为一的概率。预测的类别,无非就是得分最高的那一项。
为什么像素是一种残酷的输入
一个诱人的念头,是把像素网格摊平成一长串数字,喂给普通的全连接网络。人们试过;效果很差。一张不大的 224×224 彩色图像就有十五万多个数字,仅第一层就要数以亿计的 权重——这是成本失控、又会带来惨烈 过拟合 的配方。更糟的是,这种网络把左上角的像素和正中央的像素当作毫不相干的坐标,于是一只猫往右移了三个像素,看上去就成了一个全新的输入。
解法就是你早先认识的 卷积神经网络:让一个小小的滤波器在图像上滑动,从而把同一个图案探测器在各处反复使用,一层层地堆叠出 先是边缘、再是纹理、再是部件、最后是整体物体。这条内建的假设——一个有用的图案,无论出现在哪里都同样有用——是一种强有力的 归纳偏置,恰恰正是对自然照片做分类所需要的。像素不再是一张扁平的清单,而成了网络可以推理其上的一张空间地图。
ImageNet 与 2012 年的地震
若没有一个东西来证明这一切,上述一切都无从证明。2000 年代后期,李飞飞与合作者建起了 ImageNet:约一千四百万张照片,每张都被人工标注进 WordNet 层级所组织的数万个类别之一。其巧思与其说在算法,不如说在 标注——成群的众包工人,以任何学术 数据集 都未曾达到的规模为图像贴标签。一项年度竞赛,即 ImageNet 大规模视觉识别挑战赛,在约一百二十万张训练图、共一千个类别的子集上评判各系统。
多年来,获胜者都是精雕细琢、由人手工设计的流水线,进展缓慢如爬。直到 2012 年,一个名为 AlexNet 的网络——由 Alex Krizhevsky、Ilya Sutskever 与 Geoffrey Hinton 打造——以令整个领域震惊的优势夺冠:它的 top-5 错误率降到约 16%,而次优者还停在 26% 附近。这里没有哪一招独门绝技。它就是一个深度卷积网络,在两块消费级 GPU 上训练,用了 ReLU 激活、用 Dropout 对抗过拟合、并施以大量 图像增强。教训在于:各样配料终于同时到齐了——足够的数据、足够的算力,以及一个结构对路的模型。
迁移学习:不要从零开始
2012 年最深远的后果,不在那个夺冠的分数——而在那个训练好的网络最终被发现「内含」了什么。一个学会区分一千个 ImageNet 类别的网络,在这一路上,必然学到了普遍有用的视觉机件:边缘探测器、纹理探测器、形状与部件探测器。那些靠前和居中的层,根本无关乎「狗性」;它们关乎的是*看见*这件事本身。这正是 迁移学习 的许诺:在一个大任务上学到的特征,可以被复用到另一个不同的、更小的任务上。
在实践中,这就是视觉领域天天上演的工作流。你拿来一个骨干网络——它在 ImageNet 上的 预训练 早已完成、可免费下载——砍掉它最后那个一千路的分类头,再装上一个为你自己的类别准备的小小新头部——比如十种皮肤病变。然后你做 微调:在你那几千张带标签的图像上训练,常常把靠前的层冻结、只调整靠后的层。一项曾经需要一百万张图和一整片 GPU 农场的任务,如今用单张显卡、几千张图就能成功。
backbone = load_pretrained("resnet_imagenet") # features, learned once
freeze(backbone.early_layers) # keep generic edge/texture detectors
backbone.head = NewHead(num_classes=10) # your task: 10 skin lesions
for images, labels in your_small_dataset: # only a few thousand examples
loss = cross_entropy(backbone(images), labels)
update(backbone.head, backbone.late_layers) # adjust the top, not the bottom有一个较新的转折值得点名。在卷积之外,视觉 Transformer 把一张图像切成小块、当作词元来对待,套用你在语言模型里见过的同一套注意力机件。视觉 Transformer 能够胜过 CNN——但主要是在以真正海量的数据集做预训练时,因为它内建的空间偏置更少、必须从数据中把它学出来。对多数日常项目而言,一个微调过的卷积骨干仍是一个强而廉价的 基线;越大并不自动越好。
排行榜藏起来的东西
看到 95% 的准确率,就假定模型「理解」了图像,这很容易。它并没有。一个分类器优化的,是其训练集中一切与标签相关的东西,而这往往包括没人想要的 捷径——一个本该识别肺炎的模型,可能在悄悄地读取是哪家医院的扫描仪拍的这张 X 光片,只因为某家医院收治的病人病得更重。这就是「学会了疾病」与「学会了一条 伪相关」之间的区别。高测试准确率并不能证明学到的是对的东西;它只能证明测试集也共享了那条捷径。
ImageNet 本身就携带 数据集偏差:它偏向于西方的、由互联网拍摄的物体,于是在它上面训练的分类器,对西式婚纱的识别远好过对世界许多地方传统服饰的识别。模型对 分布漂移 也很脆弱——光照、相机或背景的些微变化,就能把在实验室里看似完美的准确率打到谷底。这并不意味着分类坏掉了;它意味着排行榜上的一个数字,是评估的开端,而非终点。诚实的从业者要问的,不只是「有多准?」,而是「对谁准,又是靠读取什么而准?」
退后一步,这条弧线就清楚了。分类给了这个领域一个干净、可计分的问题;ImageNet 给了它规模大到让 深度学习 终于划算的数据;而迁移学习,把那一次昂贵的胜利,变成了如今整个社区据以构建的一座可复用的地基。本阶梯接下来的篇章会补上分类所缺的本领——定位物体、分割场景、生成图像——但它们每一个,都站在这项任务教会机器去看的那些表征之上。