计算机视觉任务全景图:从图像分类到目标检测与分割的完整学习指南
经常有准备入坑的朋友问我:计算机视觉到底要学哪些东西?第一次接触深度学习的时候,图像分类还能听懂,但一说到目标检测、语义分割、实例分割、姿态估计、多目标跟踪,就开始晕了。这不是你理解能力的问题,而是这个领域本身就是一个巨大的谱系,从最低层的像素操作到最高层的场景理解,任务之间的跨度非常大。这篇总结我会站在“全景”的角度,把这些任务、它们之间的层级关系,以及相应的主流方法、评价指标、现实中的工程注意点一次讲清楚。适合刚学完Python基础、正在纠结学习路线的入门者,也适合做过一些小项目但缺乏系统梳理的同学。
1. 视觉任务全景图:从“看见”到“理解”的层级划分
1.1 底层感知任务:回答“图像里有什么”
底层感知任务的工作可以概括为一句话:把一张HxWxC的像素矩阵,转成某种结构化的标签或几何输出。
图像分类是其中最基础的一个,输出只是一个整数索引或one-hot向量,代表“这张图里最主要的物体是什么”。接着是目标检测,它输出的是若干个框,每个框带了类别和置信概率。再往上就是分割任务,语义分割给每个像素一个类别名,而实例分割还要把同一类别的不同个体拆开。最后还有关键点检测,比如人体姿态里每个人的五官、四肢骨架,输出是一组坐标点。
这四个任务的输出越来越细,难度和对标注的要求也随之上升。分类只需要一个标签,检测要多画一个矩形框,分割要逐像素描边,姿态估计则要标出几十个关键点。一个很直观的经验是:当你把标注工作量翻一倍、任务难度其实会翻好几倍,因为模型要拟合的输出空间变大了,而且输出结构之间的内部关联也更复杂。
1.2 中层理解任务:回答“发生了什么”
如果只看单张静态图,很多实际应用是不够的。监控要看行为,自动驾驶要看连续帧里的运动趋势,这时候就需要中层理解任务。
视频理解输入是T帧图像序列,输出往往是动作类别或事件描述。多目标跟踪的关键在于给同一个目标分配稳定的ID,跨帧不串号,你在多目标跟踪项目里最烦的往往不是“检测不到”,而是“ID切换”——同一个人走着走着编号就变了。视觉关系把一个场景表达成三元组,比如“人-骑-自行车”。视觉问答则把图像和自然语言问题同时输入,输出一个答案。
这类任务的共同点是:模型不止要看“图像里有什么”,还要能回答“发生了什么”“谁和谁是什么关系”。它们通常不单独出现,而是叠加在检测、分割之上,所以你看到的很多自动驾驶系统,底层是检测和分割,上层还要做轨迹预测和行为判断。
1.3 高层生成任务:回答“怎么造出像样的图像”
另一类任务的方向完全反过来:不是理解图,而是生成图。
超分辨率把小图变清晰,修复把破损区域补全,图像翻译把语义分割图变成写实街景,文生图更是用一段文字直接画出一张图。它们共享同一个难点:输出空间是像素级别的,且没有唯一正确答案。这也导致评估特别费劲,PSNR和SSIM测的是像素级相似度,但对纹理、语义内容,这些指标和人眼的观感经常对不上,所以实操中还要搭配FID这类分布层面的指标一起看。
从读图到写图,背后的技术路线完全不同。理解任务的主流是判别式模型,生成任务的主流则是生成式模型,两者的损失函数、训练目标、评估方式基本是两套东西。如果直接把分类的那套思路拿去训生成模型,输出通常都是模糊的均值脸。
2. 六个核心任务逐个拆开看:数学形式、输出空间与评价指标
2.1 图像分类:所有任务的起点
图像分类的数学形式很单纯:给定图像X,学习映射f(X)到类别标签y。训练时用交叉熵损失,一批批数据迭代,让模型预测的类别分布逼近真实标签的one-hot分布。
但真要评价分类模型,光看“准确率”是不够的。拿ImageNet来说,一张图里可能同时有猫和狗,标注只给一个主类别,Top-1准确率就是模型的首选预测和标注一致的比例,Top-5则允许模型在前五个预测里蒙对。为什么Top-5有意义?因为有些类别实在太像,比如十七种猛禽,人来分也费劲,工程上往往允许模型给出候选集再让下游业务做二次判断。
另一个坑是类别不均衡。如果99%的样本都是“背景”类,模型全预测背景也能拿到99%准确率,这时候最好换成平均精确率、召回率,或者直接看混淆矩阵。
2.2 目标检测:从“有没有”到“在哪、是什么”
检测比分类复杂的地方在于,它要同时回答两个问题:目标在哪里,目标是什么。输出的每一组结果包括类别、置信度、四个坐标(中心点+宽高)。
评估检测模型最怕的就是只给一个准确率。因为检测框是模型“猜”出来的,猜的位置可能偏了,猜的类别可能错了,框可能把目标包住一半也算检测到了,这都不算真懂。业界通用指标是mAP,核心是两个概念:IoU和PR曲线。
IoU是两个框交集面积除以并集面积,衡量“框得准不准”。如果预测框和真实框的IoU大于0.5,就算一个真阳性。mAP是每个类别单独算一条precision-recall曲线,曲线下的面积就是AP,最后对所有类别求平均。更严格的是[email protected]:.95,把IoU阈值从0.5每隔0.05取到0.95,算11个阈值下的平均,这个指标对框的精度要求非常高,基本逼着模型把框贴到极致。
工程上还有一个绕不开的后处理叫NMS(非极大值抑制)。检测器会在目标周围产生大量高度重叠的框,NMS的做法是:先挑置信度最高的框,把和它IoU超过阈值的框全部删掉,再继续挑下一个。不调好NMS,你的指标再好看,上线的效果都会被一堆重复框毁掉。
2.3 语义分割与实例分割:像素级身份认定
语义分割的本质是像素级分类:输入一张图,输出同样大小的标签图,每个像素标一个类别。但直接拿分类网络套根本不现实,因为普通CNN的池化层会把特征图越缩越小,最后只剩一个类别概率,根本没有逐像素结果。
FCN(全卷积网络)第一次解决了这个问题,用反卷积上采样把特征图恢复到原图分辨率,再用跳连结构把浅层细节和高层语义融合。到了U-Net,更是把“编码器-解码器+跳连”玩到了极致,医学影像领域到现在仍大量使用U-Net及其变体。
分割的评估指标主要是mIoU:把预测图和真实标注逐像素对比,算每个类别的交集除以并集,再对所有类别平均。为什么用IoU而不是准确率?因为一张街景图里“路面”这种类别可能占了半边天,模型把路全部蒙对就能拿到很高的像素准确率,但行人、车辆这种小目标全错也看不出来,mIoU对类别分布没那么偏心。
实例分割更进一步,它要把“猫A”和“猫B”两团像素区分开。Mask R-CNN的做法是在Faster R-CNN的检测分支旁边加一条掩码分支,既出框又出逐像素掩码。分割任务的另一个常见问题是类别极不均衡,在线难例挖掘和Dice损失都是为了缓解这个问题,我自己的经验是:当mIoU卡在60%上下不去,先看模型是不是把难类别全吞了,再考虑换损失函数。
2.4 姿态估计与其他结构化输出任务
姿态估计是典型的结构化输出任务:输出的是人脸的几十个关键点、人体的骨架关键点、或者手部的关节坐标。
早期做法是把关键点坐标当回归问题,直接预测(x, y)数值,但效果很不稳定。后来大家发现用heatmap效果更好:为每个关键点生成一张二维高斯激活图,模型的任务是预测“这个点出现在哪里”的概率分布,相当于把一个数值回归问题改造成一个空间位置分类问题,收敛稳定得多,精度也更高。
姿态估计的评估指标是OKS(目标关键点相似度)。它不是简单地算欧氏距离,而是把每个关键点的距离再按标注难度归一化,比如肩关节的标注方差远大于眼睛,所以同样偏差下,眼睛的惩罚更大。类似道理也适用于指纹关键点、动物姿态、车辆骨架这类结构化输出任务,凡是输出内部存在空间关联的,都不适合当独立回归问题处理。
下面列一个速查表,方便你把这些任务的关键信息记在一起:
| 任务 | 输入 | 输出 | 常见评价指标 |
|---|---|---|---|
| 图像分类 | 图像 | 类别标签 | Top-1/Top-5 Acc |
| 目标检测 | 图像 | 框+类别+置信度 | mAP@[.5:.95] |
| 语义分割 | 图像 | 逐像素标签图 | mIoU |
| 实例分割 | 图像 | 框+类别+像素掩码 | mAP |
| 姿态估计 | 图像 | Kx2关键点坐标 | OKS/PCK |
| 视频理解 | 帧序列 | 动作/事件标签 | Top-1/Top-5 Acc |
3. 方法体系二十年:从卷积核到注意力机制的接力赛
3.1 卷积时代:为什么CNN天生适合图像
图像和表格数据最大的区别是空间结构。相邻像素之间高度相关,远处的像素相关性弱,同样的物体特征平移一下,含义还是一样的。卷积层就是为这种结构设计的:局部连接让你只看一个感受野内的像素,权值共享让同一个卷积核在整张图上移动,天然具有平移等变性。
但光靠卷积还不够。网络一深,梯度在反向传播里越传越小,前面几层几乎学不到东西。BatchNorm通过在每一层把激活值拉到均值为0、方差为1的分布,让梯度传播稳定下来;残差连接则干脆让模型学“变化量”,把恒等映射这条路直接铺好。这两个技巧加上ReLU激活,才让ResNet-50、ResNet-101这些深度网络真正训练得动。
直到今天,如果你需要提取图像特征,ResNet的ImageNet预训练权重依然是最稳妥的底子之一。很多迁移学习项目直接冻结前面几层,只微调后面几层,就能得到不错的结果。
3.2 检测的两条路线:两阶段与一阶段
检测在过去十年有两条技术路线。
两阶段的代表是Faster R-CNN系列。第一阶段用RPN(区域提议网络)先产出可能包含目标的候选框,第二阶段对每个候选框做分类和精修回归。好处是精度高,因为候选框质量高,分类器不用面对海量背景;缺点是慢,因为要跑两遍网络。
一阶段的代表是YOLO和SSD。它们把检测当成一个单次回归问题,图像进去,框和类别一次出来。YOLO在很长一段时间里被吐槽小目标检测效果差,但它速度优势太明显,工业界几乎清一色选YOLO做实时推理。后来YOLO系列把多尺度预测、anchor-free机制、更强的特征融合加了进去,小目标问题改善了很多。
实操里怎么选?如果你在做一个学术研究,追求榜单精度,Faster R-CNN及其变体仍是一个稳健基线;如果你的系统要实时跑在嵌入式设备上,就老老实实上YOLO系。
3.3 Transformer改写视觉:ViT与DETR的启示
2020年之后的视觉研究被Transformer彻底搅动。ViT(Vision Transformer)的做法很简单:把图像切成一堆16x16的patch,展平成向量当成token,然后直接丢给标准Transformer编码器。它放弃了卷积的两个先验(局部性和平移等变性),完全靠注意力机制去学关系。
结果很反直觉:数据量足够大的时候,ViT的表现反而超过CNN;数据量不够时,它还不如ResNet,因为少了归纳偏置,必须靠数据自己学出图像结构。这个结论直接影响工程选型:你在刷小规模数据集时,别盲目跟风上Transformer,先跑CNN基线更划算。
DETR则把目标检测彻底改写了。它不再预定义一堆锚框,而是把检测定义成一个集合预测问题,直接用Transformer输出固定数量的预测框,再用匈牙利算法做预测和真实框的匹配,一次性端到端训练。这个方案把NMS和锚框设计整个干掉,理论优雅,但收敛速度慢,小目标仍有短板。不过它的思想已经渗透到很多新模型里。
3.4 生成方向的转移:GAN退场、扩散模型接棒
生成任务的主流方法这几年换了一轮。GAN用生成器和判别器互相对抗,生成器努力骗过判别器,判别器努力识破假图。问题在于这个min-max博弈非常不稳定,训练到后期经常模式崩塌——生成器发现只要输出少数几种能骗过判别器的方式就能拿到高分,于是生成结果越来越单一。
扩散模型的思路完全相反。它先往真实图像上逐步加噪声,直到图像变成纯噪声;再训练一个神经网络逐步去噪,把纯噪声还原成图像。训练目标非常朴素:每一步都去预测“这一层的噪声”,监督信号密集且明确,训练稳定性远好于GAN。代价是推理时要一步步采样,比较慢,但现在有大量蒸馏和一致性模型在做加速。
从我实际使用的体感来说,如果你要做一个图像生成类的项目,现在首选扩散模型,后续再看具体需求是否用LoRA或ControlNet做定制控制。
4. 计算机视觉和机器学习的边界:哪些知识被高估,哪些被低估
4.1 一句话说清三者关系
这几个术语经常被混着用,但其实角色完全不同。机器学习是“从数据中找规律”的方法论,深度学习是机器学习里基于神经网络的那一类方法,计算机视觉是“让机器理解图像和视频”的一个应用领域。
你可以这样理解:视觉任务是问题域,机器学习是工具箱,深度学习是工具箱里最趁手的那套电动工具。CV里很多任务,本质上是通用机器学习问题,只是输入换了像素数据。
4.2 通用机器学习能力直接迁移的部分
你在机器学习课上学过的模型评估、过拟合、正则化、学习率策略、早停、数据划分,在CV项目里全部直接生效。
举个例子,训练一个图像分类模型时,验证集怎么分、要不要做交叉验证、数据增强会不会导致验证集分布偏移,这些决策跟图像本身无关,是通用的实验设计问题。再比如迁移学习,把在大规模数据集上预训练好的模型拿到自己小数据集上微调,这在整个机器学习领域都是一套成熟的范式。
自监督预训练也值得提一句。MAE(掩码自编码器)把图像的一部分patch遮住,让模型用剩下的patch重建原图,这种自监督预训练在NLP里叫完形填空,在CV里其实也是同一套逻辑。通用ML能力越扎实,你转CV越顺畅。
4.3 视觉特有的难题不该被低估
但认为“我会机器学习,就自然懂计算机视觉”是不对的。图像数据有几个特点,通用ML很少正面处理。
第一,像素不是表结构。图像的每个像素孤立来看毫无意义,所有信息都在空间排列里,模型必须能从局部到全局逐层构建语义。第二,标注成本极高。检测一个框要人眼盯半天,分割一张图要描很久,所以半监督、少样本、标注效率在CV里是刚需,在通用ML里反而没那么急迫。第三,图像有大量分布偏移。训练时晴天,部署时雨天,模型性能可能掉一大截,这促使了域适应和域泛化方向。第四,几何变换是CV特有的数据增强手段,旋转、缩放、裁剪对图像语义通常是合理的,对表格数据就完全讲不通。
这些差异意味着你学CV时不能只看通用ML教材,必须在具体任务里和数据的结构打交道。我的建议是:一边学通用知识,一边在图像任务里练手,让两者互相咬合。
5. 第一次跑代码之前:环境选择、工具链与数据集避坑
5.1 IDE选型:VS Code还是PyCharm,别在这个选择上花太多时间
每次有新人来问“学习计算机视觉需要Visual Studio Code和PyCharm安装哪个”,我都会说一句实话:这个选择远没有你想象得那么重要。
PyCharm更适合纯Python工程,尤其是你经常要调试、跟踪项目结构、依赖第三方插件的时候,它的调试体验是VS Code比不了的,而且专业版自带Jupyter交互。VS Code更轻量,启动快,插件生态非常丰富,如果你以后想写脚本、接远程服务器、顺带上前端页面,它会更灵活。
一个实用的判断标准:如果你现在做的是CS231n风格的小作业,两边都可以,选你觉得看着顺眼的那个;如果你接下来要跑复杂的大作业项目,先上PyCharm,调试舒服一点。环境比IDE重要,因为IDE随时能换,但conda环境如果装乱了,重新配一遍要花掉你一下午。
5.2 真实影响体验的是conda、GPU和镜像源
学习CV的标配是conda环境加PyTorch。我建议用Miniconda而不是Anaconda,干净、体量小。
# 先查一下GPU驱动对应的CUDA版本 nvidia-smi # 创建独立环境,避免和系统里的Python打架 conda create -n cv python=3.10 -y conda activate cv # 安装PyTorch,注意CUDA版本要和你驱动匹配 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121 # 视觉项目常用的依赖 pip install opencv-python matplotlib albumentations没有GPU怎么办?也别急着买卡。Google Colab和Kaggle的免费notebook足够跑完课程作业和小型项目,唯一的限制是会话时长和数据上传。如果你用的是国内网络环境,建议把pip镜像源换到国内,装包速度能快很多。CPU训练不是不行,但一个ResNet-50跑ImageNet级别的数据会等得让人崩溃,小数据集和课程作业用CPU没问题。
5.3 数据决定了项目成败:数据集与标注工具
新手最容易犯的错误是一上来就找ImageNet,其实大多数入门项目用不太到那么多数据。常用数据集里,MNIST和CIFAR-10/100适合算法练手,PASCAL VOC只有20类、一万多张图,适合初学检测和分割,COCO规模更大,80类、超过二十万张标注图,适合做有说服力的实验。
很多大作业项目需要自建数据集。标注工具我会推荐CVAT或labelme,前者适合在网页上标检测框,后者适合标点、拖轮廓,都能导出COCO格式。这里必须提醒一句:数据清洗和标注的时间往往占项目总时间的一半以上,而且标注质量直接决定模型上限。你模型最后效果差,很多时候不是网络结构的问题,而是标注里错标、漏标太多。
6. 少刷课多动手:一份偏实操的计算机视觉学习路线
6.1 八周路线图:每个阶段都有一个看得见的里程碑
我给准备入门的同学一个八周节奏,每一周结束都必须有一个能跑通、能眼见为实的东西,避免陷入“看了很多文档却什么都做不出来”的状态。
| 周次 | 学习内容 | 完成标准 |
|---|---|---|
| 第1-2周 | Python、NumPy、OpenCV基础 | 能用OpenCV读图、画框、做颜色变换,理解图像是三维数组 |
| 第3-4周 | PyTorch核心知识 | 用多层感知机跑通MNIST,理解反向传播和优化器的作用 |
| 第5-6周 | 用CNN做图像分类 | 在CIFAR-10上训练ResNet-18,画出损失下降曲线,准确率到80%以上 |
| 第7-8周 | 用现成检测模型做项目 | 跑通YOLOv8推理,标注自己的几十张图片,训练并看mAP变化 |
这个路线刻意把“图像分类”和“目标检测”当成两个里程碑,而不是完整覆盖所有任务。因为这两个任务已经足够训练你掌握数据加载、模型训练、指标评估、结果可视化这一整套闭环。剩下分割、姿态等任务,有了闭环能力之后,换模型和损失函数是很快的事。
6.2 怎么挑一个让自己有成就感的项目
如果你是被“计算机视觉大作业”逼着来搜这篇的,那我建议把项目眼光放窄,别想着一口气做个自动驾驶。
好项目的三个标准:问题具体单一、数据容易获取、评价指标明确。比如“检测厂区工人是否佩戴安全帽”“识别马路上是否有人闯红灯”“统计货架上的商品数量”,都是窄而清晰的题目。数据集可以自己拍、可以从开源平台找,或者先用现成数据集跑通基线,再替换成自建数据。
具体操作时记住一个技巧:先跑通一个最简基线的pipeline,再迭代。不要第一版代码就想把ResNet-152、多尺度训练、复杂增强全塞进去。先用一个小模型、小数据把代码链路跑通,再逐步加复杂度,每一版只改一个变量,你才知道哪个改动真正起了作用。
6.3 资源别囤,课程作业做一遍胜过看十遍
CS231n名气太大,我不否认它是最好的视觉入门课之一。但很多同学把时间花在“搜集PPT”“找作业答案”上,这是最亏的消费方式。PPT下载下来不会长进,作业自己写完才会。特别是里面手写反向传播、自己实现两层卷积网络的部分,看起来简单,真跑到半夜报错时才会知道卡在哪。
我的建议是:课程用来搭框架,动手能力靠项目练。看视频理解概念足够了,练手一定得在自己动手的项目里练。经常有同学跟我说“我看了三遍课程还是不会做项目”,那是从“输入”过渡到“输出”的环节缺了一整块练习,这块练习只能靠做项目补回来。
我见过不少新人,最后真正拉开差距的往往不是谁聪明,而是三四个月内谁做了一个完整的“数据到指标”的闭环,谁还停留在看完一堆课程和PPT的阶段。第一次跑通模型、第一次看到自己的loss曲线降下来、第一次在测试集上看到准确的检测框,这个成就感比刷完十门课都实在。
如果你正在入门,我的建议很简单:把视频调成倍速,开源代码跑起来,数据标好,模型训起来,指标分析看明白,遇到报错就自己先排查半小时再问人。这条路走通了,计算机视觉这个领域的全景图自然就在你脑子里建立了。