在本文开篇之前,我们先来了解下关于计算机视觉的定义,本段定义取自维基百科
计算机视觉(Computer vision)是一门研究如何使机器“看”的科学,更进一步的说,就是指用摄像机和计算机代替人眼对目标进行识别、跟踪和测量等机器视觉,并进一步做图像处理,用计算机处理成为更适合人眼观察或传送给仪器检测的图像。
这段话读起来有点拗口,简单总结下这段话。计算机视觉的目标,就是让计算机拥有“眼睛”去感知世界。
计算机视觉三大经典任务
既然是感知,那感知的维度和细粒度也是有区别的,不同的感知程度在计算机视觉中的对应的任务模型也是不同的, 今天我们来介绍三个最经典的计算机视觉任务:图像分类、目标检测、实例分割。 这三大经典任务在实现方式、输出形式、网络结构和训练目标上都有明显区别。
图像分类
第一类任务是图像分类,图像分类是计算机视觉中最简单的一类任务。图像分类任务的输出的是类别标签,当我们只需要知道图像属于哪个类别时,图像分类非常有用。
像下面的这张图中,一共识别出来了三个物体,人(PERSON)、三脚架(TRIPOD)、安全背心(SAFETY VEST)。
举个例子,当我们进行人脸识别扫描的时候,如果只需要知道图片中是否有人脸,就可以使用图像分类任务。图像分类任务,只关心图片中是否存在某个类别。如果有,则对该图片添加类别标签,如果没有,则不添加标签。
目标检测
第二类任务是目标检测,目标检测任务的输出是一组边界框,这些边界框覆盖了图像中的目标物体,并且会输出每个边界框的类别标签和置信度分数。
当我们需要在场景中识别感兴趣的目标,并且需要知道该目标的坐标和大小的时候,目标检测是一个不错的选择。
那我们在什么场景下需要知道检测物体的坐标和大小呢?我们来举一个具体的例子:在人脸识别场景中,通常需要准确获取人脸的坐标和大小。为了确保识别的准确性与安全性,要求人脸在画面中清晰且完整,一般应占据图像面积的 30% 以上,并且人脸需要在图片的正中间。若检测到的人脸区域过小、位置过偏,在左上角,或者右下角,往往意味着该人脸距离较远、画面不清晰,或可能为非目标人员(如路人、偷拍者等),因此不符合有效识别的标准。
实例分割
第三类任务是实例分割。实例分割比目标检测更进一步,目标检测它是用方框去标注目标物体,而实例分割则是需要明确边界,需要明确勾勒出物体的边界。实例分割模型的输出是一组掩码或轮廓,它们勾勒出图像中每个对象,以及每个对象的类别标签和置信度分数。 实例分割可以看作是目标检测的高级形式。当任务对检测类别的精度要求较高时,通常会采用实例分割模型。
例如,阿里正在开展的 CT 肝胆肿瘤图像分析项目中,通过对医学影像进行像素级分析,可以判断患者是否存在肿瘤。此类任务对模型的精度要求极高,因此需要实例分割方法来获得更加精确、细致的像素级边界信息。
我们也以人脸识别举例子,大家在人脸识别的时候应该遇到过这个场景,在人脸检测的视频页面有一个标注的人脸虚线框,只有当我们把人脸对准到虚线框时,才会开始进行人脸识别,这里就是不仅仅知道需要图片中是否有人脸,并且还要知道人脸的精确位置,这里就可以使用实例分割的任务模型。
视觉任务的精度升级路径
在计算机视觉领域,图像分类、目标检测和实例分割是三类常见任务,它们对模型精度的要求会随着任务复杂度逐步提升。
- 图像分类是最基础的任务,只需判断图像中包含的对象类别,因此对精度的要求相对较低。
- 目标检测在分类的基础上,还需要定位物体在图像中的位置,通常以边界框的形式给出,因此其精度要求适中。
- 实例分割则进一步在检测的基础上,为每个目标提供精确到像素级的轮廓,属于精度要求最高的任务。
目标检测
在本次分享中,我们将重点聚焦于“目标检测”,它是实际应用中最常见、应用场景最广的计算机视觉任务之一。
接下来,我们将以“人脸目标检测”为示例,带大家了解目标检测模型的完整训练流程。整体流程可以分为三个阶段:
- 准备数据集
- 模型配置与训练
- 验证与推理
在本次示例中,我们的目标是训练一个能够检测人脸的模型,因此首先需要收集与人脸相关的数据集。在目标检测任务中,数据集的质量至关重要:
- 低质量的数据集 即使经过充分训练,模型的准确率和泛化能力也会受到明显限制;
- 高质量的数据集 则能显著提升模型的整体性能,为后续训练奠定良好基础。
数据集收集
获取训练数据集,主要有两种方式:公开数据集、自行采集。
对于人类及身体部位、常见交通工具、常见动物,以及一些日常用品(如牙膏、杯子)等类别,通常都有现成的公开数据集,这意味着我们可以直接利用这些数据进行训练。
然而,如果我们要针对公司自研的产品或特定场景进行训练,这类数据往往没有公开的数据集。此时,如果想进行图像识别训练,通常需要人工对图片进行标注,才能生成高质量的训练数据。
公开数据集
- ImageNet 由华人李飞飞团队创建的公开数据集网站,覆盖 20000 多个类别。
- COCO 由微软发布的通用数据集,覆盖 80 多个常见类别,约 33 万张图片。
- Kaggle 全球数据科学竞赛平台,这个平台也被称为数据科学领域的黄金敲门砖,里面会举办机器学习与计算机视觉竞赛,当然里面也有大量高质量数据集。
自行采集
自行采集,根据自己的需求收集数据集图片,然后进行人工标注,标注我们通常借助工具进行标注。
- Label Studio 推荐⭐️,开源数据标注平台,部署到本地或者服务器后即可进行人工标注,支持多种数据类型,不仅包括图像,还包括文本、音频、视频、HTML 等,适用范围更广。
- Labelme 开源数据标注平台。
- Makesense 在线数据标注平台,仅适合体验一下标注的流程。
目标检测的标注格式
在学习本小节之前,我希望你已经尝试了人工标注,否则理解下来会有些困难。
在目标检测任务中,图片和标注数据是紧密关联的。左边是标注的原始图片,右边是标注后生成的标签文件。标签文件的格式通常如下:
-
第一位数字表示类别编号,例如
0代表人脸; -
后四位数字表示目标的位置和大小:
- 第二、第三位是目标的中心坐标
(x, y); - 第四、第五位是目标的宽度和高度
(w, h)。
- 第二、第三位是目标的中心坐标
这里的坐标和宽高通常经过 归一化处理,以百分比的形式记录相对于图片尺寸的比例。
如果同一张图片中还有其他物体需要检测,例如照明灯,我们可以将其类别编号设为 1,并提供对应的标注数据。一张图片可以同时包含多个类别的目标。
因此,在进行目标检测训练时,我们需要对所有感兴趣的物体进行标注,明确告诉模型“哪些是重要的目标”。此外,提供的图片数量越多、标注质量越高,训练出的模型准确率和泛化能力也会越好。
模型训练 和 模型部署
有了数据集之后,下一步就是将数据集输入模型进行训练。关于后续的 模型配置与训练 以及 验证与推理,我在本次分享前已经完成了训练演示。
如果大家对训练过程感兴趣,我准备了一个 口罩识别 的示例项目。大家可以 Fork 该项目,并按照 README 中的操作步骤,亲自运行一次完整的模型训练流程。
由于人脸检测任务对模型的泛化能力要求较高,因此对数据集的多样性和质量也有较高要求。本次实验中,我们使用了约 1.2 万张人脸图像 作为训练数据,并在 NVIDIA A10 GPU 上进行了 100 轮训练。
在训练过程中,每一轮都会遍历完整的 1.2 万张图片,并在前一轮训练的基础上对模型参数进行优化。例如,第二轮训练的模型是基于第一轮训练结果更新的,第 100 轮训练的模型则是在第 99 轮模型的基础上继续优化得出的。
模型推理
接着刚才的人脸检测模型,我们来看一个问题:如果把这四张图片输入模型进行推理,哪些图片能够被正确识别人脸,才算合理呢?大家可以先花二十秒思考一下。
好了,我相信大家心里也有了自己的答案。我们的训练数据有 1.2 万张人脸图片,训练了 100 轮,相当于这个模型总共“看过”了 120 万次人脸——这可能比大多数人一生中见过的人脸还要多。
接下来,我们可以将模型返回的人脸检测结果与我们直觉认知中的人脸进行对比,看看它是否符合我们的预期。我们来看一下检测结果:
- 第一张图片顺利通过,人脸检测正常,完全符合预期,是一个标准的真实人脸。
- 第二张图片也被正确检测出了四张人脸,其中有不少是侧脸,这说明模型在识别侧脸时也相当精准。
重点是 后两张图片:
- 第三张图片虽然看起来像人脸,但实际上并不是生物人脸,却也被模型识别为人脸。
- 第四张图片更夸张,也被模型识别为人脸。
得到这种结果,我的第一直觉是不是模型训练的不到位?前面100轮总共是120万张图片。
于是又追加了100轮的训练,那么模型总的数据集图片数量就来到了240万张图片。但是最后得到的结果却令我震惊,100轮出来的模型和200轮出来的模型,在检测结果上几乎没有太大差别。100轮的训练结果和200轮的训练结果对于检测人脸结果几乎相差无几,我相信即使追加到300轮、400轮,也很难有太大的突破。所以到底是哪里出现了问题?
人脸检测能力对比
想要知道自己做的好不好,最简单的方法就是比较嘛。于是我找了国内两家提供静态人脸识别服务的厂商来试试,一家阿里云的产品,一家百度云的产品。
大家可以拿这张图片,访问上面的两个网站,亲自体验一下识别结果。
这里我只截取了一张阿里云人脸检测的结果截图。值得注意的是,百度云和阿里云对于这张图片的检测结果基本一致——都认为图片中存在人脸。
这说明,即便是国内顶尖科技公司的产品,也无法完全正确地区分真实人脸与非人脸图片。即使我们用肉眼一眼就能辨别,这些模型也可能出现误判。
因为我们的认知很大程度上来自于经历。判断一张图片是否为人脸,是基于我们过去看到的无数真实人脸与非人脸的经验。而机器判断人脸的标准,则完全依赖于训练数据——也就是我们提供的成千上万张图片。
在现实生活中,我们看到足够多的 负样本(非人脸物体),大脑就能形成对人脸的抽象概念。但机器如果没有见过足够多的负样本,就可能把卡通或动漫人脸误判为真实人脸。如果我们在训练中加入大量动漫或卡通人脸作为负样本,检测结果可能会有所改善。
因此,静态人脸识别和检测终究存在局限。如果对人脸检测要求较高,建议结合活体检测功能,以提高识别的可靠性和安全性。
YOLO:You Only Look Once
YOLO 是本次使用的目标检测算法模型,在图像检测领域非常知名。YOLO 是 “You Only Look Once” 的缩写,从字面上理解就是“只看一次”。
之所以称为“只看一次”,是因为在 YOLO 出现之前,主流检测方法多为 两阶段方法,需要先生成候选区域,再进行分类,相当于“看两次”。而 YOLO 属于 单阶段方法,一次性完成目标检测。
单阶段的优势在于 检测速度快,这是 YOLO 的核心亮点之一。速度快带来的好处在于,很多场景需要实时检测,例如自动驾驶,如果检测延迟过高,可能出现“快撞到人了才识别到前方有人”的危险情况。因此,实时检测能力对于很多场景下是至关重要。
YOLO 发展历史
目前,YOLO 已经发展出十二个被主流认可的版本。那么为什么说是“被主流认可”呢?原因在于,真正意义上的官方 YOLO 版本只有 v1 到 v4,v4 之后的版本大多为社区版本。这里我们主要介绍 官方版本系列 和 Ultralytics 系列。
-
官方版本:
- 2015 年,Joseph Redmon 发布了 YOLO v1,并在 2016 年发表论文《You Only Look Once: Unified, Real-Time Object Detection》,YOLO 的名字由此而来。v1 的最大优势是检测速度遥遥领先当时主流检测器,但精度表现一般,因此初期关注度不高。
- 2016 年,YOLO v2 发布,相比 v1 在检测精度上大幅提升,实现了 “实时检测 + 高精度” 的双赢,这在当时的目标检测领域几乎是革命性的,使 YOLO 开始流行起来。
- 2018 年,YOLO v3 发布。
- 2020 年,原作者 Joseph Redmon 宣布退出计算机视觉研究,同年,YOLO v4 由项目继承者发布。YOLO v4 通常被视为 官方 YOLO 系列的最后一代。
-
社区版本:
- 同年,Ultralytics 公司发布 YOLO v5。由于不是官方版本,使用 YOLO 命名,有人认为有些“碰瓷”,但 v5 的性能确实非常强大,因此逐渐获得社区认可。YOLO v5 是 Ultralytics 系列的开山之作,使用 PyTorch 重构,训练和部署更加方便,同时在精度和速度上对比 v4 也有优势。
- 随着 YOLO 开源社区的发展,出现了多个社区分支版本。需要注意的是,每个社区版本几乎都是独立实现,可以看作一个全新的框架和模型。在 YOLO 中,版本号并不一定代表性能高低,每个版本都有各自擅长的应用场景。
综上所述,如今的 “YOLO” 已经不再是单一官方项目,而是一种 算法思想 + 命名约定,包含官方系列和多样化的社区版本。
YOLO 单阶段 VS 两阶段
讲完了发展历程,我们来看下支撑 YOLO 的核心思想:单阶段。单阶段和两阶段的区别到底是什么?在以往的传统的图像识别通常都是两阶段,两阶段的模型需要处理两次图像才能完成对图片的预测,而YOLO只需要处理一次图片,就能完成对图片的预测。
两阶段
我们先来看一个 两阶段检测模型 的流程,举例使用的算法是 Faster R-CNN。实际上,绝大多数两阶段目标检测模型的原理差别不大。
第一阶段:生成候选框
生成候选框的意思是,在真正寻找目标物体之前,模型会先提取出一堆 可能包含目标的区域。打个比方,就像我们找某件物品时,脑海中会先想到它可能出现的地方。例如,要找梳子,我们不会第一时间跑去厨房,而是先在卫生间或卧室里寻找。
对于 Faster R-CNN 来说,第一阶段就会生成 2000 多个候选框。你可能会疑问,一张小小的照片里生成这么多候选框,不会全是密密麻麻的吗?确实如此,因此需要利用 非极大值抑制(NMS) 去除重叠冗余框,只保留最优候选框,进入第二阶段。
第二阶段:分类与回归
在这一阶段,模型会对每个候选框进行 类别预测和位置回归,也就是对每个区域再次分析,确定目标类别并精确定位。可以理解为模型对图片的 第二次观察。
简单来说,两阶段模型的逻辑就是:
- 先确定可能的目标区域(第一次看)
- 再在这些区域里精确识别目标(第二次看)
这种设计虽然精度较高,但处理速度相对较慢,因为每张图片都需要被“看两次”。
非极大值抑制
我们来看一下两阶段中非极大值抑制(NMS)的过程。
当图片被输入模型后,模型会生成上千个初始候选框,如下图中的 右上图。
第一步:置信度阈值筛选
我们会先根据置信度进行一次快速过滤,例如将阈值设为 0.4,所有置信度低于 0.4 的候选框全部丢弃。经过这一步,我们得到上图中 右下图 的候选框,候选框数量减少了不少,但依然存在大量的重叠框。
第二步:使用交并比(IoU)去除冗余框
为了处理这些彼此重叠的候选框,我们使用 IoU(交并比)进行筛选。当 IoU 的值越高时,说明两个框的重叠部分就越大。例如设置 IoU 阈值为 0.5,当多个候选框之间的 IoU 超过 0.5 时,我们会从这些重叠框中选择置信度最高的那一个 保留,其余全部丢弃。
通过这一系列筛选,最终就能获得一组(如上图中的左下图) 干净、不重叠且最优 的检测框。
单阶段
好了,我们来看 YOLO 单阶段检测 的工作模式,看看它是如何“一次看完”就能预测整张图片的。
首先,YOLO 会将图片划分成 X * Y 的网格,每个网格都会预测类别概率。这里可能会有人有疑问:网格这么小,连一个完整的物体都放不下,它能预测出什么呢?
实际上,每个网格内部都有若干个 锚点(Anchor) ,锚点可以是 3×3 网格 或 6×6网格 等不同设置。每个锚点都会生成候选框,并在候选框上进行边界框回归 + 分类预测。因此,YOLO 中的网格并不局限于自身,而是能以自身为中心,向外扩散感受野。一个 YOLO 网格通常会生成多个候选框,并且整张图片的所有网格会同时并行执行这些操作,极大程度提升检测效率。
单阶段和两阶段的区别
两阶段模型是先生成候选框,再对候选框进行分类回归,YOLO 单阶段模型则是直接将图片划分网格,对每个网格的锚点进行预测,一次性完成位置和类别的检测。有趣的是,YOLO 的网格划分与某些网站的人机验证很相似:将图片切成若干小块,让你选择符合条件的格子。每一次点击,实际上也是在为网站标记训练数据。
目标检测网络框架
从深度学习时代开始,目标检测网络的框架也逐渐地被确定了下来。一个常见的目标检测网络往往可以分为三大部分:主干网络、 颈部网络和检测头。
- 主干网络是目标检测网络中最核心的部分,其关键作用就是提取输入图像中的高级特征,减少图像中的冗余信息。
- 颈部网络的作用是融合不同层级的特征,让模型同时理解小目标和大目标。
- 检测头的作用就是在前两步网络的基础下,进行输出,我们先前提到的无论是单阶段和两阶段的工作步骤,都是在检测头内进行完成。
卷积神经网络的工作原理
最后我们来简单了解下卷积神经网络的工作原理,卷积神经网络本质上是一种特征学习方法。对于计算机而言,它只能看到图片的阵列,在灰度图里面他就是代表1和-1,其中1是亮的,-1是暗的,计算机需要在这一串数字阵列中学习特征。
现在我们要对 字母X 进行图片识别,我们可以将 X 划分为三部分:
- 左边的斜线
- 中间部分
- 右边的斜线
由这三个特征组成了 字母X,这三个被提取的特征,在卷积神经网络中也被称之为卷积核。
每一个卷积核都是 3*3 的大小,并且每一个卷积核都有它所代表的特征, 我们现在将这三个卷积核进行组合,就能得到 字母X。那么我们如何让计算机知道这三个卷积核的特征叠加在一起就等于X呢?
我们可以通过下面这段卷积核扫描动画,更深入地理解卷积是如何工作的:左侧绿色区域表示原始图像,左侧黄色区域表示 3×3 的卷积核,右侧红色区域则是经过卷积后生成的特征图。
卷积的过程非常直观:卷积核会不断向右(以及向下)滑动。每移动一次,都需要将卷积核中的 3×3 数字,与原图对应位置的 3×3 灰度值逐项相乘,然后再把所有乘积求和,将这个结果填写到特征图的相应位置中。随着卷积核在整张图上滑动,我们就能得到一张完整的卷积特征图。
我们尝试带入 字母X 的 左斜线特征 来计算,一起来计算下左斜线特征和绿色方框内的卷积特征值:
| 1 * 1 | -1 * -1 | -1 * -1 |
|---|---|---|
| -1 * -1 | 1 * 1 | -1 * -1 |
| -1 * -1 | -1 * -1 | 1 * 1 |
因为 左斜线特征 和扫描到的 绿色方框 完全吻合,所以每一个块值相乘的乘积都会为1,所以就是9个1,我们可以将 9 / 9 = 1,除以 9 是因为卷积核为 3*3,得到 1 即为此处卷积核和扫描部分完全相似。
我们可以在看看当 左斜线特征 扫描到 中间的绿色方框 时,得到的结果,因为卷积核和扫描到的区域并不完全吻合,我们可以看到结果只有0.55。
我们将 左斜线特征 这个卷积核扫描原图后,即可求出当前卷积核下的卷积特征图谱,颜色越深,就代表特征值越低,当为黑色时,则特征值最低。我们现在只用一个卷积核扫描了原图,剩余两个卷积核扫描原理相同。剩下的就是把生成的特征图丢入激活函数进行运算,这里我们就不再演示了。
总结
- 计算机视觉是让计算机“看懂”图像和视频的技术
- 计算机视觉三大经典任务:图像分类、目标检测、实例分割
- 目标检测三步骤:准备数据集、模型与训练、验证与推理
- 获取数据集方式:公开数据集、自己采集
- 计算机对于世界的认知经历,取决于我们投喂的数据
- YOLO 是一种快速的、单阶段的,用于图像分类、目标检测、实例分割的模型
- YOLOv1 - YOLOv4 是官方版本,其它都是社区版本
- 单阶段模型生成候选框和分类回归是同步进行的,两阶段模型是先生成候选框,在进行分类回归
- 卷积神经网络本质上是一种特征学习方法,每个卷积核对应一类特征