JOVANA
Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

计算机如何"看见"图像

在网络能叫出"猫"或找到肿瘤之前,一张图像必须先变成数字。本文讲清楚:一张照片如何化为像素网格、这些像素如何堆叠成张量、一条"边缘"究竟是什么,以及为什么"看见"远比它看上去要难。

照片就是一张数字网格

把任意一张数码照片放得足够大,画面就会化解成一个个微小的彩色方块。每个方块就是一个像素(pixel,即"图像元素"),而在计算机眼里它根本不是颜色,而是一个度量亮度的数字。在灰度图像里,一个像素就是单个数值,按惯例从 0(黑)到 255(白),中间一切都是某种灰。于是一张 1000×1000 的照片,不过是一百万个这样的数字排成网格:一行行、一列列的亮度而已。那里面没有"猫",也没有"天空"——只有一张巨大的强度数值表。

彩色的原理一模一样,只是叠了起来。一个彩色像素通常是三个数字——它发出多少光、绿光和光——因为人眼有三类颜色感受器,把这三种原色混合起来就能重现我们能看到的大多数颜色。所以一张彩色照片其实是三张网格相互叠放:一张管红、一张管绿、一张管蓝。这些叠起来的网格就叫通道(channel)。

从网格到张量

你已经熟悉这条"形状"的阶梯:单个数是标量,一排数是向量,一张网格是矩阵,而轴更多的东西就是张量。灰度图像恰好就是一个矩阵——高 × 宽。彩色图像再上一层:高 × 宽 × 3 个通道——一个有三条轴的张量。这正是流入每个视觉模型的标准形状,而把轴的顺序摆对(通道在前还是通道在后)是这份工作里每天都要做、却毫不光鲜的一环。

实践中我们很少一次只处理一张图。我们会把许多图像堆成一个批次(batch),在最前面再添一条轴,于是真正在训练中流动的张量是 批次 × 高 × 宽 × 通道。这个四维的数字块才是真正的"输入"——而你之前学过的每一层、每一次矩阵乘法卷积,无非都是在对这个块做算术、重塑它的形状。

grayscale  shape = (H, W)            # one value per pixel
color      shape = (H, W, 3)         # red, green, blue stacked
batch      shape = (N, H, W, 3)      # N images flowing together

# a single pixel in a color image is just three numbers:
img[120, 64] = [231, 76, 60]         # reddish: high R, low G, low B
同一幅画面化作数字:一个灰度矩阵、一个三通道彩色张量,以及一个含 N 张图的批次——这正是每个视觉模型所期待的形状。

一条"边缘"究竟是什么?

孤立的原始像素几乎毫无用处——知道像素 (120, 64) 偏红,并不能告诉你这张图画的是什么。你能提取的第一个有用东西是边缘(edge):亮度在相邻像素间骤然变化的地方。把目光扫过一张"桌上有个马克杯"的照片,杯子与背景的界线,正好就是数字跳变的地方。一条边缘,无非是相邻像素之间一处很大的局部*差异*。

你可以用一个微小的滑动窗口来找边缘——一张小小的权重网格,让它在图像上滑过,边滑边做乘法再相加。把权重设计成:像素有差异处窗口输出大值、平坦处输出近零,你就有了一个边缘检测器。这个滑动窗口运算*就是*一次卷积,它的输出是一张新网格,叫特征图,哪里出现那种模式,它就在哪里"亮"起来。几十年里,工程师都是手工设计这些小滤波器——Sobel、Canny——因为判定什么才算有用的特征,本身就是一门手艺。

卷积网络悄然带来的革命,是不再手工设计这些滤波器,而是去*学*它们。每个窗口里的权重都变成由梯度下降调节的参数。叠上几层,网络就建起一座层级:第一层学到边缘和色块,下一层把边缘组合成角点和纹理,再下一层组合成眼睛、车轮和叶片,最顶层组合成完整的物体。边缘不过是这座阶梯最底下的一级——而关键在于,机器是自己发现它的。

为什么视觉是真的难

真正的难处在这里。单一一个物体——比如某一只特定的猫——可以产生几乎无限多张完全不同的像素网格。把它移近,每个数字都变了。旋转它、调暗灯光、让一把椅子遮住它一半、把背景从草地换成雪地——每一次,原始张量都变得面目全非,可你的大脑却瞬间断定"是同一只猫"。计算机必须学会:一个稳定的概念("猫")藏在多得惊人的像素排布背后。这道横在原始像素与含义之间的鸿沟,叫做语义鸿沟(semantic gap),跨越它就是视觉的全部难题。

数字会让这一点变得鲜活。一张并不算大的 224×224 彩色图就有超过 15 万个原始数值,而所有可能图像构成的空间浩瀚得无法想象——可其中只有薄得难以置信的一小片,看起来像是真实存在的东西。模型必须从相对少得可怜的一堆样本里,把这片巨大空间中"有意义"的区域切割出来——这正是你早先见过的维度灾难的一副面孔。它竟然行得通,原因在于真实图像并不随机:它们充满结构——邻近像素彼此相关、边缘连成线条、纹理不断重复——而像卷积这样恰当的归纳偏置,正好把这种结构事先嵌了进去。

本阶的其余部分如何由此搭建

本阶接下来的一切,都立在你现在拥有的这幅图景上:图像是张量、特征是分层学来的、而核心的敌人是"变化"。说出画面里那个唯一的主导物体,是图像分类;给每个物体画一个框、说出它*在哪*,就成了目标检测;给每一个像素都贴上标签,就成了分割。后面的指南还会重新审视卷积这一假设本身——视觉 Transformer丢掉了滑动窗口,把图像切成一块块小补丁,让注意力机制自己决定什么和什么有关。

有两个实用习惯会贯穿始终。第一,既然"变化"是敌人,那我们就在训练时故意制造更多变化——翻转、裁剪、改色、旋转图像,好让模型学会忽略那些其实无关紧要的变化;这就是数据增强,也是让视觉模型变得稳健的最廉价办法之一。第二,几乎没人会从零训练:人们往往从一个已经在巨型带标注数据集 ImageNet 上训练好的网络出发,再去适配它——这正是你早先见过的迁移学习招式,它让一个小数据集得以站在一个庞大数据集的肩膀上。