从“像素”到“语义”:视觉任务与CNN的基本问题
我们之所以会觉得“看”是一种直觉能力,很大程度上是因为人类视觉系统能把二维像素阵列迅速组织成“物体—部件—关系—场景”的层级结构:在同一张照片里,我们既能辨认出边缘与纹理,也能理解“这是一辆车停在路边”,甚至能推断“这可能是一条城市道路”。机器视觉的核心困难恰恰在于:输入只是像素值,而我们期待输出的是语义判断。要跨越这条鸿沟,必须先把视觉任务说清楚,再把“为什么卷积神经网络(CNN)在早期如此关键”讲透。
---
一、视觉信息的层级:从像素到结构化表征
一张彩色图像通常可表示为张量 $X\in\mathbb{R}^{H\times W\times C}$,其中 $H,W$ 是高与宽,$C$ 是通道数(RGB 通常为 3)。像素的数值本身并不携带“物体”的概念:同样的物体在不同光照、视角、尺度下会产生截然不同的像素分布;而不同物体也可能在局部区域呈现相似纹理。这意味着,视觉学习的关键不是“记住像素”,而是学习一种逐级抽象的表示(representation),使得高层表示对语义更稳定、对无关扰动更鲁棒。
从经验上看,视觉表征往往呈现如下层级特征:
- 低层:边缘、角点、简单纹理(对局部像素梯度敏感)
- 中层:重复纹理、简单形状、部件(例如“轮子”“眼睛”)
- 高层:类别、实例、场景关系(例如“狗在草地上奔跑”)
CNN 的历史贡献之一,在于用相对简单的结构偏置(inductive bias)把这种层级抽象“写进了模型结构”:通过局部连接与多层堆叠,使得网络能从局部模式逐步组合出更复杂的结构。
<!-- TAGS: 表征学习, 结构偏置, 视觉层级 -->
---
二、典型视觉任务:分类、检测、分割
视觉任务的差异,主要体现在“输出是什么”以及“空间位置是否重要”。下面用三类最经典的任务建立共同语境。
2.1 图像分类(Image Classification)
目标:给定一张图像,输出其所属类别(或多个标签)。 输出形式:类别概率向量 $p(y\mid X)$。 常见指标:Top-1 / Top-5 Accuracy,F1(多标签情形)。
分类任务的核心难点,是在背景复杂、姿态变化、遮挡等因素下保持语义判别能力。它往往被视为视觉学习的“基本功”,因为许多检测与分割方法都依赖强分类表征作为骨干网络(backbone)。
> 例:ImageNet(约 120 万张训练图像、1000 类)长期被用作通用视觉表征训练的基准之一。2012 年 AlexNet 在 ImageNet 竞赛中显著降低 Top-5 错误率,被广泛视为深度 CNN 复兴的重要节点。[^alexnet]
2.2 目标检测(Object Detection)
目标:在图像中找出物体的位置与类别。 输出形式:一组边界框(bounding boxes)与类别/置信度,如 $\{(b_i, c_i, s_i)\}_{i=1}^N$。 常见指标:mAP(mean Average Precision),基于 IoU(Intersection over Union)阈值。
检测与分类的根本区别在于:模型不仅要“知道有什么”,还要“知道在哪里”。这引入了空间预测(坐标回归)以及候选区域选择等问题,也使得特征的空间分辨率与多尺度表达变得尤为关键。
2.3 语义分割(Semantic Segmentation)与实例分割(Instance Segmentation)
语义分割目标:对每个像素赋予语义类别(如“道路”“人”“天空”)。 输出形式:像素级标签图 $Y\in\{1,\dots,K\}^{H\times W}$。 常见指标:mIoU(mean IoU)、Dice 系数(医学影像常用)。
实例分割目标:不仅区分语义类别,还要区分同一类别的不同实例(两个人要分成两个掩码)。 这类任务对边界、细节、遮挡处理提出更高要求,通常需要更精细的多尺度特征融合与后处理策略。
为了形成整体对照,可用一张表概括三类任务的输出与指标:
| 任务 | 输出粒度 | 典型输出 | 主要指标 | 典型应用 | |---|---|---|---|---| | 分类 | 图像级 | 类别概率 | Top-1/Top-5 | 内容检索、相册归类 | | 检测 | 实例级 | 框+类别 | mAP、IoU | 自动驾驶、安防 | | 语义分割 | 像素级 | 每像素类别 | mIoU、Dice | 遥感制图、医学分析 |
<!-- TAGS: 图像分类, 目标检测, 语义分割, 评价指标 -->
---
三、从直觉到结构:为何卷积是“合乎情理”的选择
在深度学习出现之前,人们常通过手工特征(如 SIFT、HOG)把局部边缘与方向直方图编码成可用的表示。CNN 的思想可以被理解为:让网络自己学出这类“局部—组合—抽象”的特征,但仍保留三个与视觉强相关的结构直觉:局部相关性、平移性质、参数共享。
3.1 局部相关性(Locality)
自然图像具有强烈的局部统计相关性:相邻像素往往来自同一表面或同一物体部件,变化通常是连续的。若我们用全连接层直接处理 $H\times W\times C$ 的输入,则每个输出神经元都与所有像素相连,既浪费参数,也忽略“局部模式可重复出现”的事实。
卷积层通过局部感受野(receptive field)进行连接:一个卷积核只看输入的一小块区域,从而迫使网络先学习局部模式(边缘、角点等),再由更深层把这些局部模式组合成更复杂结构。
3.2 平移等变与不变性:你移动物体,答案不应改变
直觉上,如果一只猫从画面左边移动到右边,它仍然是“猫”。因此,我们希望模型对平移具有某种稳定性。
严格地说,卷积运算天然满足平移等变性(translation equivariance):输入平移会导致特征图按同样方式平移,而不是产生完全不同的响应。随后通过池化(pooling)、步幅下采样(stride)或全局平均池化(global average pooling),可以进一步获得近似的平移不变性(invariance),即“类别判断基本不变”。[^equiv]
这种性质并非“自动保证万无一失”:过度下采样会损失定位信息;过强不变性会让模型难以区分细粒度位置关系。检测与分割任务通常需要在“保持空间分辨率”和“获得鲁棒语义”之间做权衡。
3.3 参数共享:用同一套“眼睛”扫遍全图
卷积层最具工程意义的优势,是参数共享(parameter sharing):同一个卷积核在整张图上滑动,表示“同一种局部模式可能在任何位置出现”。假设卷积核大小为 $k\times k$,输入通道为 $C$,输出通道为 $C'$,则参数量为 $k^2CC'$;若用全连接层连接到同等大小的特征图,参数量将随 $HW$ 线性增长,往往不可承受。
卷积的基本形式可写为(以二维为例):
$$ Y_{i,j,c'}=\sum_{u=1}^{k}\sum_{v=1}^{k}\sum_{c=1}^{C}W_{u,v,c,c'}\;X_{i+u,\,j+v,\,c}+b_{c'}. $$
尽管实现细节(padding、stride、分组卷积等)会变化,但其核心思想始终是:以局部计算为单位、以空间共享为约束。
<!-- TAGS: 局部相关性, 平移等变性, 平移不变性, 参数共享, 卷积 -->
---
四、CNN 的基本构件:卷积、非线性与“感受野”的增长
理解 CNN 不需要一开始就陷入复杂网络(ResNet、ViT 等)的细节。把握三个构件即可解释大部分早期视觉系统的行为:卷积、非线性激活、下采样/归一化。
4.1 卷积层:把“模板匹配”推广为可学习算子
从直观上看,一个卷积核可以被理解为“可学习的模板”:它对某种局部模式(比如水平边缘)产生强响应。与手工模板不同的是,卷积核由数据与损失函数驱动自动学习,且会形成多通道、多尺度的特征集合。
4.2 非线性激活:让模型具备组合复杂性的能力
如果只堆叠线性算子(卷积本质上是线性),整个网络仍是线性映射,表达能力极其有限。ReLU 等非线性激活把模型提升为可表达复杂决策边界的系统,是从“线性滤波”走向“可学习语义”的关键桥梁。
4.3 下采样与归一化:稳定训练与尺度抽象
- **下采样(pooling/stride)**:减少空间分辨率、扩大有效感受野,使高层特征更关注“是什么”而非“精确在哪”。
- **归一化(如 BatchNorm)**:缓解内部协变量偏移(实践中表现为训练更稳定、收敛更快),并与更深网络结构相互促进。
感受野的概念常被用来解释“深层网络为何能看见更大范围”。若每层卷积核大小为 $k$、步幅为 1,堆叠 $L$ 层后,有效感受野大致随层数增长;加入下采样后,增长更快。这解释了为何深层 CNN 能在较高层捕捉到物体整体形状,而浅层更像边缘检测器。
<!-- TAGS: ReLU, 池化, BatchNorm, 感受野 -->
---
五、三个案例:同一套表征思想如何适配不同任务
为了避免“概念正确但缺乏落地感”,下面用三个简化案例说明:视觉任务的差异如何反映到模型输出形式与训练信号上。
5.1 案例一:手写数字分类——从像素到类别的最小闭环
手写数字(如 MNIST)是最典型的入门任务:输入为 $28\times28$ 灰度图,输出为 10 类。它的价值不在于挑战难度,而在于能快速建立训练闭环:数据读取、模型定义、损失函数、反向传播、验证集评估。
一个极简 CNN 通常包含两到三层卷积、一次下采样与一个分类头。它展示了 CNN 的基本逻辑:局部模式(笔画边缘)逐步组合成数字结构,最终映射到类别。
> 电子版交互示例:可视化卷积核如何响应不同笔画(建议在浏览器中打开) > [交互链接:CNN 特征可视化演示(示例页)](https://poloclub.github.io/cnn-explainer/) 〔外部资源〕
5.2 案例二:道路场景检测——“是什么”与“在哪里”的耦合
在自动驾驶或交通监控中,我们需要检测车辆、行人、交通灯等目标。与分类相比,检测不仅输出类别,还输出位置与数量,因此模型通常需要:
- 多尺度特征:远处目标小、近处目标大
- 更密集的预测:在许多空间位置上给出候选框
- 更复杂的损失:分类损失 + 边界框回归损失
- 处理重复预测:非极大值抑制(NMS)等策略
以 COCO 数据集为例,其训练集常被描述为十万量级的标注图像,包含多类别、多实例与复杂遮挡,这使得检测系统必须更重视定位精度与泛化能力。
5.3 案例三:医学或遥感分割——像素级决策与“边界”的重要性
在医学影像(如器官分割)或遥感(如道路、建筑物提取)中,分割结果直接服务于测量、规划或诊断,输出的每一个像素都可能影响后续决策。分割任务的难点常集中在:
- 细长结构与模糊边界(如血管、道路)
- 类别不平衡(病灶区域远小于背景)
- 需要保留高分辨率细节(过度下采样会“糊边”)
因此,分割模型通常采用编码器—解码器结构与跳跃连接,以在高层获得语义、在低层保留细节。评价上,IoU 与 Dice 等指标比单纯准确率更能反映“形状重叠质量”。
<!-- TAGS: MNIST, COCO, 编码器解码器, NMS, Dice -->
---
六、评价指标:我们如何判断模型“学会了看”
不同任务的指标本质上都在回答同一个问题:模型输出与真实标注的差距有多大,但差距的度量方式因任务而异。
6.1 分类:Accuracy 与 Top-k
- **Top-1**:预测最大概率类别是否正确
- **Top-5**:真实类别是否在概率最高的 5 个类别中
Top-k 的存在反映了多类别细粒度任务中“相近类别难以严格区分”的现实。
6.2 检测:IoU 与 mAP
IoU 定义为预测框与真实框的交并比:
$$ \mathrm{IoU}(A,B)=\frac{|A\cap B|}{|A\cup B|}. $$
mAP 则综合考虑不同置信度阈值下的精确率—召回率权衡,用于评估“既要找全,又要找准”。
6.3 分割:mIoU 与 Dice
对分割而言,像素级准确率在类别不平衡时会产生误导(背景太多导致“看起来很高”)。Dice 系数常写为:
$$ \mathrm{Dice}(P,G)=\frac{2|P\cap G|}{|P|+|G|}, $$
其中 $P$ 为预测掩码,$G$ 为真实掩码。它对小目标更敏感,因而常用于医学场景。
<!-- TAGS: IoU, mAP, mIoU, Top-k, 类别不平衡 -->
---
七、全书学习路线:从 CNN 直觉走向现代视觉系统
本书采用“任务牵引 + 结构演化”的路线:先用分类—检测—分割建立共同问题框架,再逐步引入更强的骨干网络、更系统的训练策略与更广泛的应用议题。读者不需要在第一章就掌握所有细节,但应建立两个长期主线:
1. 表征主线:模型如何把像素变成可泛化的语义特征 2. 任务主线:输出形式改变时,网络结构与损失函数如何随之调整
为便于读者形成全局感(并为后续 20 章铺垫),可以将学习过程粗略划分为四段:
- 基础与直觉:任务、卷积结构偏置、训练与评估基本法
- 结构进阶:更深更稳的 CNN、特征金字塔、多尺度与注意力
- 任务系统化:检测与分割范式、实例级与像素级统一建模
- 走向真实世界:自监督/迁移、部署优化、数据与伦理
> 建议的阅读策略: > 先建立“能跑通的最小系统”,再追求“更强的 SOTA(state-of-the-art)”。许多学习障碍并非来自理论难度,而是来自工程闭环缺失:数据处理、指标计算、训练可复现性等。
---
八、实践环境建议:把学习变成可复现的工程流程
视觉学习高度依赖算力与数据管线,但入门阶段完全可以从轻量环境起步。推荐的实践配置遵循“可复现、可扩展、可迁移”的原则。
8.1 软件栈建议(通用且稳定)
- Python 版本:建议 3.10 或 3.11(与主流深度学习框架兼容性较好)
- 深度学习框架:PyTorch(生态成熟,教程与示例丰富)
- 辅助库:`torchvision`(数据集与模型组件)、`numpy`、`matplotlib`
- 实验管理:从简单的日志与随机种子开始,逐步引入更系统的工具
安装示例(以 Conda + Pip 为例):
```bash conda create -n vision python=3.10 -y conda activate vision pip install torch torchvision matplotlib numpy ```
如果具备 NVIDIA GPU,可进一步安装与 CUDA 匹配的 PyTorch 版本;若只有 CPU,也完全可以完成前几章的核心实验(只是训练更慢)。
8.2 最小可运行的 CNN 示例(分类骨架)
下面代码展示了一个可运行的 CNN 结构骨架(用于理解而非追求性能):
```python import torch import torch.nn as nn
class TinyCNN(nn.Module): def __init__(self, num_classes=10): super().__init__() self.features = nn.Sequential( nn.Conv2d(1, 16, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(2),
nn.Conv2d(16, 32, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(2), ) self.classifier = nn.Sequential( nn.Flatten(), nn.Linear(32 * 7 * 7, num_classes) )
def forward(self, x): x = self.features(x) return self.classifier(x) ```
读者在本章应重点理解三点: (1)卷积如何在空间上滑动并产生特征图;(2)下采样如何改变分辨率;(3)最后如何把特征映射到类别空间。
8.3 训练闭环的流程图(便于对照实践步骤)
```mermaid graph TD A[数据集与标注] --> B[数据预处理/增强] B --> C[模型前向传播] C --> D[计算损失函数] D --> E[反向传播] E --> F[参数更新(优化器)] F --> G[验证与指标评估] G --> H[保存模型/记录实验] H --> C ```
> 电子版提示:建议把每次实验的配置写入同一份配置文件(学习初期用一个 `.py` 或 `.json` 即可),并固定随机种子,以便复现实验结论。 > 交互练习(可选):将训练循环拆解为“前向—损失—反向—更新”四步,逐行打印张量形状与梯度范数,帮助建立对训练动力学的直觉。
<!-- TAGS: PyTorch, 可复现性, 数据增强, 训练闭环 -->
---
九、小结:本章应当带走的核心结论
本章围绕“从像素到语义”的跨越,建立了三个层面的共同框架:
- 任务层面:分类、检测、分割的输出差异决定了建模与评估方式
- 结构层面:局部相关性、平移性质与参数共享共同指向卷积结构偏置
- 工程层面:实践应从最小可运行闭环开始,逐步扩展到复杂任务与真实数据
在下一章中,我们将把“卷积为何合理”的直觉进一步形式化:从张量形状、卷积参数、步幅与填充开始,严格追踪特征图如何变化,并用可视化与实验建立对模型内部计算的可解释直觉。
---
[^alexnet]: 术语说明:AlexNet 通常指 2012 年提出的深度卷积网络结构之一,因在当年 ImageNet 评测中表现突出而广为人知。 [^equiv]: 术语说明:等变性(equivariance)指输入施加某种变换后,输出以可预测的方式发生对应变换;不变性(invariance)指输出基本保持不变。两者在视觉任务中承担不同角