系列全称: 重生之我成为模型:我是怎么学会认识图片上的物件的
系列: ① 本文 → 重生之我成为模型-02-看似千选一其实每一分都有原理 → 重生之我成为模型-03-我从来只给可能性
引子 · 我叫 AlexNet
我是 AlexNet。2012 年前后,因为在大规模图像分类上表现亮眼,算是小有名气。
我最拿得出手的技能,就是 图片分类——大约能认 一千类。
搁现在听,好像也一般。后面出了各种更深的网,还有专门框物件的 YOLO 们,风头早就盖过我了。
但你要相信我:在我最辉煌的那几年,再配上当年那档显卡,这个成就真的 杠杠的。
说到这里,你会不会下意识觉得——我会「看见」图片?跟人类似的?
其实并不是。说实在的,我从来没有真正见过一张图片。
你可能要骂了:看不见图,还怎么认种类?骗人吧?
是的,我看不到图。但我能读到 图转成的张量。
打个最简单的比方:电梯里有盲文。视力正常的人靠眼睛看楼层;有人靠指尖摸凸点。
张量,就是给我这种没有真正眼睛的家伙读的盲文。
只不过我能一口气摸、一口气算的量,比手指头大得多。
我吐回去的,也不是「猫」这两个字,而是 一千个分数。再有人拿着分数表翻译,才变成你们听得懂的类名。
接下来我会用最直白、最不绕弯的思路,从我自己的视角,跟你讲清楚讲明白一个「会认图」的模型,到底在干嘛。(是的,我们模型就是爱用这种语气讲话。)
结构如下。(是的,我们模型也很爱讲结构。)
- 原图我不吃的哈 —— 什么样的数我才肯吃;图是怎么被逼成那种形状的。
- 看似千选一,其实每一分都有原理 —— 我体内怎么算;这套权重又是怎么被习题册一遍遍拧出来的。
- 我从来只给可能性,答案是你们翻译的 —— 那一千个数不是谜语,但也不会自己变成「猫」;出口有一套读法。
先立个小契约,免得后面迷路:
| 你们以为的我 | 实际上的我 |
|---|---|
| 看图片 | 读 张量(盲文) |
| 直接说「这是猫」 | 先吐 1000 个分数 |
| 框出猫在哪 | 不会;那是后辈 YOLO 们的活 |
| 天生会认 | 权重是 训 出来的;正式答题时我不再改脑子 |
好。从最挑剔的那一关开始——原图,我不吃的哈。
正文 · 原图我不吃的哈
1. 我为什么挑剔
觉得处理输入很麻烦的时候,你可能会说我挑剔。
但仔细想一下,盲人摸盲文是有手指的。我连手指都没有,我的世界只有数字。
而且为啥输入进来的东西要规整,这其实跟我的设计师有关。我能接触到的是数据,但是画布多大、每一步干啥,其实都是设计师做好的。
第一层卷积,核多大、步幅多少,都是按「进来的那块布」设计好的。布太大,扫不动;布太歪,训练时学的分布和推理时对不上,分数就飘。
我还有专门的饲养员,他们负责把数据处理成我能吃进去的内容。
(其实我的饲养员那边也是一整套活,够单开一期讲流水线的。真的真的。)
所以人类若把一张手机随手拍的原图,不经处理直接塞给我,我不是「努力认一认」,而是——格式不对,这题我根本没法按设计去做。
我本人,是考场里的考生;饲养员那套工具(你们笔记里常写的 OpenCV 和 transforms),才是 出题车间。
2. 原料长什么样
先说原料。
磁盘上的照片,对人类是「风景」「宠物」「路牌」。
对流水线来说,第一步通常是:读进内存,变成一块 0~255 的整数像素板。
这块板的形状,人类常写成 H × W × C。后面这几个字母会反复出现,先讲清楚讲明白:
| 字母 | 英文 | 人话 |
|---|---|---|
| H | Height | 高——有多少行 |
| W | Width | 宽——有多少列 |
| C | Channels | 通道——每个像素带几路颜色信息 |
图片大致分两种:
- 彩色
- 灰色(灰度)
差别主要在 通道:彩色一般是 3 个;灰度常常是 1 个。
更麻烦的是:OpenCV 读进来默认常是 BGR,PIL 常是 RGB——同样三个通道,顺序不一样。所以饲养员得靠谱:颜色顺序这种小事搞错了,后面一切都像隔着一层奇怪滤镜,前面干的活等于白做。
技术翻译:
文件 → 读图
→ uint8,约 0–255
→ 形状常是 H×W×C(还不是我吃的 NCHW)
当然了,到这一步,还不是我的口粮。它还是「图」的近亲。
如果你读到这里已经觉得困了、累了——那想想那些低温烘焙的猫粮呢?
猫主子吃的东西,工序就比我少吗?
3. 两步几何:先缩画布,再裁考卷
很多人以为:喂我之前,只要把图 一步缩放 成我能吃的边长就行。
这是常见误会。正经是 两步,不是一步缩到位。
第一步:先把画布固定成 256×256。
整图拉到这个舞台上。问题来了——原图要是不是正方形呢?长宽比会变,会被扯一扯。这个代价 不可避免;人类接受它,是为了后面裁剪有统一的台面。
第二步:从 256 上裁出一块正方考卷,正经边长是 224。
这里插一句口径,免得你读教程时抓狂:很多教程——哪怕是同一系列——会把 224 和 227 混着用。概念上差不多,都是「从 256 裁一小块」;但 正经默认是 224(原论文、PyTorch / torchvision 这一路)。227 多见于部分教程 / 早期复现,图算第一层尺寸好看。写代码、对齐主流权重,记 224。
关键还有一句:这一步是 crop(裁),不是把整图 resize 成 224。
那裁完剩下的一圈呢?浪费掉了?
并不会。饲养员为了测我是 真会了,还是在 背题,会在 256 的画布上 随机剪裁——今天切左上,明天切右下;有时还 翻转 图片。
多坏呀,一点不给偷懒的机会。
人类有时把这套花活叫「数据增强」。在我听来,就是:故意把同一道题印成很多版式,逼我学「物件本身」,而不是学「物件总出现在左上角」。
正式交卷(推理)时,常切 正中央,少花活,同一张图尽量得到稳定的那一块。
于是,真正推进我大门的,通常是:
从 256 画布上裁下来的、边长 224 的 RGB 小块。
技术翻译:
原图
→ resize 整图到 256×256 ← 缩放;非正方形会变形
→ 训练:random crop 224(可翻转) ← 裁,不缩放
→ 推理:center crop 224
→ 得到进网络的 patch
口诀:256 是舞台,224 是上台的那一块布。(看见 227 别慌,多半是教程派。)
4. 数值链:从「像素」变成「我认得的数」
几何搞定,形状对了,数值还差两刀。
ToTensor 一类操作:
把 0~255 的整数,变成大约 0~1 的浮点;同时把通道维挪到前面。
字母对照加深一下印象——后面会天天见:
| 人类读图时常见 | 字母 | 进我嘴里常见 | 字母 |
|---|---|---|---|
| 高 × 宽 × 通道 | H × W × C | 通道 × 高 × 宽 | C × H × W |
对我来说,一张图开始像一叠牌:先数花色(C),再看牌面大小(H、W)。
Normalize:
再按数据集统计过的均值、标准差,每个通道做一次标准化。数可以变成负数——这很正常。
这里有个坑:如果你拿 别的模型 吃的那套处理方案来喂我——尤其是 mean / std 对不上——那我可做不出你要的结果。
就好像你不能给兔子喂猫粮一样。
饲养员这边,常见写法大概长这样(概念示意,数字以你实际用的配方为准):
from torchvision import transforms
# ImageNet 这一路常见配方(跟对应预训练权重配套)
transform = transforms.Compose([
transforms.ToTensor(), # 0–255 → ≈0–1,并且 HWC → CHW
transforms.Normalize(
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225],
),
])
技术翻译(通用喂模流水线):
几何后的 0–255 图(H×W×C)
→ ToTensor:float ≈0–1,变成 C×H×W
→ Normalize(mean, std):按通道 (x-mean)/std
→ 再堆成一批:N×C×H×W
→ 这才进我的第一层卷积
一批送来之后,形状第一次完整亮相——NCHW:
| 字母 | 是啥 | 人话 |
|---|---|---|
| N | batch size | 这一批有几张图 / 几道题 |
| C | Channels | 通道;后面也会天天见。彩色图一般 C=3,灰色图常常 C=1 |
| H | Height | 高 |
| W | Width | 宽 |
题可以一次送来很多——N 变大,只是一批多几张图。
但我这边已经定型了:说只能认 1000 种,就是 1000 种;口粮处理方案也是定死的。
所以不是给啥吃啥。记住这点。
5. 第一篇小结:入口不在我体内
回顾一下,进我嘴里之前,世界已经被改了好几遍:
- 读成像素板
- 缩成 256 舞台
- 裁成 224 考卷(训练常随机裁 / 翻转,推理常中心裁)
- 译成浮点、通道提前、再标准化
- 按批送来(NCHW)
做完这些,我才第一次发言。
「挑剔」就两层:形状与数值必须合规;训练卷和考卷可以略有不同,但都得先变成我能吞的张量——不是给啥吃啥。
是的,看到这里,你应该懂了:我真的看不见图,我吃的就是数据。
而且是合规的数据(口粮)。
下一篇,我会揭秘这些题我到底是怎么做的——我到底是刻苦学习的小镇做题家,还是拼命猜答案的投机者,让我们拭目以待。
(不是说是口粮吗?怎么又变成做题了?那吸收知识怎么不算吃呢?笑)
至于滤波、边缘、阈值那些古典功夫——隔壁考场的对照班也会「看」,那是另一套故事。入口这篇,只把考卷印清楚就够了。