计算机视觉的三大基石: 识别,检测,分割。

  • 识别,是告诉你一张图像里有什么;
  • 检测,不光告诉你图像里有什么,还要告诉你目标所在的位置;
  • 分割,就更进一步,告诉你图像里有什么,目标所在的位置,还要告诉你目标在图像里是个什么形状。

在这里插入图片描述

上面这张图,形象的描述了CV中的几个基础问题, 从识别,到检测,到分割,正如我们所看到的,从图像全局层面,到图像的局部,再到图像的像素层面,一层一层的递进。

识别,是研究的最多,也相对最成熟的一个领域,从物体识别,人脸识别到细粒度识别。从传统的特征提取比如 LBP, HOG, SIFT 以及 BoW,multi-scale,高斯金字塔,到如今的 CNN,数据规模也越来越大; 从开始的成百上千,到如今的几十万,几百万的数据规模,曾经被认为高不可攀的 ImageNet,如今也渐渐的成为过去, 当人们渐渐发现,数据堆砌到一定程度,似乎也不会换来性能的明显提升时,所有人也陷入沉思,可能数据的 “质量”,比数据的 “数量” 更加重要。对于全图层面的识别,背景的干扰很大,其实,人类视觉非常厉害的一点就是选择性 “聚焦”,也就是说,可以自动聚焦到自己所关注的目标上面,并且排除其他无关背景的干扰。

所以,简单的单一主体明确的图像识别,可能不是什么问题了,而真实的世界里,场景总是很复杂的,越来越多的人将目光聚焦到了检测,分割上面。

检测,是介于全局与像素之间的一个层面,从局部考察图像的特征。在 CNN 流行起来之前,最常用的检测就是人脸检测了,通过滑动窗口,提取不同 scale 的特征,利用 Ada-boost 进行分类。

目标检测的概念

目标检测,目前来说,有两种思路,一种是基于候选区域的,比较有代表性的就是 R-CNN 系列; 另外一种,就是利用滑动窗系列的,比如 SSD, 以及 YoLo 系列都是属于滑动窗系列。

  • 基于候选区域的检测方法
    这种方法,就是利用分割的方法,先提炼出某些候选区域,然后在这些候选区域上进行识别,回归,找出含有目标物的区域,再利用一些合并原则,将一些区域合并,这种方法的优点是准确度比较高,缺点是慢,因为这是一种 two-stage 的方式,也就是说要分两步才能实现。这类算法的代表是 R-CNN, Fast-RCNN 以及 Faster-RCNN 系列。

  • 基于滑动窗的检测方法
    这种方式,就是把图像分成很多规则的窗口,然后一个窗口一个窗口进行判断,考虑到多尺度的问题,所以也会有多尺度的窗口,然后再进行分类。这种方式在 深度 CNN 时代,似乎有着天然的优势,因为我们知道,CNN 的 feature map 上的点,在原始的输入图像上,都会有对应的 receptive field,这些 receptive field 就类似在图像上画出的窗口,不同的卷积层,对应的 receptive field 的大小也不一样,所以 SSD 利用这个性质,可以直接将多尺度的目标检测,在一个 CNN 网络中实现,不过,这种方式的一个缺点是,准确率没有基于候选区域的方式高,因为一张图像,一般来说,目标区域占比较少,而背景区域一般占比较大,所以,这也会造成图像中的正样本会比负样本少很多,训练的时候,模型可能会偏向负样本,所以滑动窗口的方式,训练的时候,正负样本的比例要保证,不能负样本过多。这类算法的代表是 SSD 以及 YOLO 系列。

目标检测中的多尺度问题

我们都知道,图像中的目标,一般来说都是多尺度的,有的目标大,有的目标小,为了解决图像检测中的多尺度问题,我们可以从两个角度考虑:

  • 一个是改变输入图像的尺度,这是我们容易想到的一种方法,通过改变输入图像的尺度,进而改变了目标的尺度,这个在目前的图像增广中,是比较常用的一种策略,我们可以改变输入图像的尺度,让网络见识到不同大小的图像。
  • 另外一种,就是改变滑动窗口的大小,这就像用网捕鱼一样,不同的网眼,可以捕获不同大小的鱼,在目标检测中,我们可以通过改变滑动窗口的大小,来做多尺度的目标检测,这个策略在目前的目标检测网络中非常流行,比如 SSD, YOLO 和 FPN 等,他们巧妙的利用 CNN 中不同层的 feature map 其实就对应了原始图像中不同大小的滑动窗这个特性,构建了多尺度的目标检测的网络结构。
目标检测中的样本不平衡问题

一般训练模型的时候,我们都希望样本能够均衡,如果样本不均衡,会让模型偏向于样本多的类别,目标检测,是一个典型的样本分布不均衡的问题,因为对于一张图像来说,一般都是背景区域的占比面积远远大于目标区域的占比面积,这样就会导致每次训练输入网络的负样本会多于正样本,这不利于网络的训练,为了保证样本的一定均衡,在目标检测的训练中,一般都会用一定的样本选择策略,一般是保证正反样本的比例大致为 1:3,为啥是这个比例,可能也是实验验证出来的吧,没有什么道理可言。
另外,为了提升模型的泛化能力,一般都会做一些困难样本的挖掘,让模型对困难样本拟合的更好,一般训练集中,肯定是容易拟合的样本占大多数,而困难样本一般占比较少,这也是一个不均衡的问题,也就是所谓的难易样本不均衡问题,为了解决这个问题,一般是针对性的对困难样本进行挑选,或者修改 loss 的设计,不管是困难样本挖掘还是修改 loss,对困难样本的 loss 赋予更高的权重,本质上来说,都是为了提高困难样本在整个数据集上的比重,这里比较简单优雅的就是 focal loss 这种方法,focal loss 是在常规的二分类 loss 上修改而来,常规的二分类loss 就是一个二分类交叉熵:

L=ylog⁡p+(1−y)log⁡(1−p)L = y\log p + (1-y) \log (1-p)L=ylogp+(1y)log(1p)

这种 loss 对所有样本是一视同仁的,不会区分样本的难易程度,这种 loss 在样本均衡的时候,还是可以的,如果样本不均衡,loss 就会好逸恶劳,趋向于拟合大量的容易样本,忽视掉少量的困难样本,为了让模型重视困难样本的拟合,就要加大对困难样本的权重,所有 focal loss 就是从这点出发,设计了如下的 loss 函数:

FL(pt)=−αt(1−pt)γlog⁡(pt)FL(p_t) = -\alpha_{t}(1-p_{t})^{\gamma} \log (p_{t})FL(pt)=αt(1pt)γlog(pt)

这个 loss 既考虑了样本整体的分布(通过 αt\alpha_{t}αt 体现),也考虑单个样本的训练难易(通过 γ\gammaγ 的调节 )

目标检测中的 loss 设计

目标检测中的 loss 设计,也是非常重要的,不同的网络结构,也会有不同的 loss 设计,不过总的来说,目标检测中的 loss 一般包含两个部分,一部分是分类 loss, 一部分是回归 loss,分类 loss 就是用来确定当前的滑动窗里具体是什么类别,而回归 loss 用来评判当前的滑动窗对目标框的回归精度,所以检测算法中一般会有两个loss

L=Lclf+LregL = L_{clf} + L_{reg}L=Lclf+Lreg

我们以 YOLOv3 的框架为例,来看检测中的 loss 设计,YOLOv3 应该是目前很受工业界青睐的一个检测框架,很好的平衡了速度与精度,并且结构相对来说简单清晰,这个框架也借用了多尺度检测的概念,每个 box 的输出是 4 + 1 + C 的维度,4 表示 box 的参数,中心位置 (cx,cy)(c_x, c_y)(cx,cy) 以及 box 的宽,高 w,hw, hw,h,1 是一个二分类,表示这个 box 是否含有物体目标,而 C 表示类别数量,为了能够更好的拟合,YOLO v3 将预测值做了一些处理:

bx=σ(tx)+cxby=σ(ty)+cybw=pwetwbh=phethb_x = \sigma(t_x) + c_x \\ b_y = \sigma(t_y) + c_y \\ b_w = p_w e^{t_w} \\ b_h = p_h e^{t_h} bx=σ(tx)+cxby=σ(ty)+cybw=pwetwbh=pheth

其中 tx,tyt_x , t_ytx,ty 表示预测 box 的中心坐标,tw,tht_w, t_htw,th 表示预测 box k宽,高,这里都经过了一些处理,以便更好地收敛。所以 YOLO v3 一共有四部分的 loss,

L=Lxy+Lwh+Lobj+LclfL = L_{xy} + L_{wh} + L_{obj} + L_{clf} L=Lxy+Lwh+Lobj+Lclf

前面两个是回归 loss,用来预测框的位置以及大小,第三个是二分类 loss,表示该框是否含有目标物体,最后一个是分类 loss,这里没有用 softmax,而是用二分类交叉熵来实现的多分类,这个 loss 对于多目标的识别效果更好

目标检测中的 NMS 处理

我们知道,目标检测,一般都会输出很多的预测框,很多框是高度重合的,这个时候,就需要对这些框进行处理,目标检测中一般会用到一种 Non-maximum suppression (非极大值抑制)的方法,非极大值抑制的方法,可以保证从多个预测框中,最后挑选出置信度最高的一个框。NMS 的算法原理也比较简单,就是利用集合中的交与并的概念,计算两个框的 IOU, 要计算 box a, b 的 IOU 可以用如下的表达式:

IOU=a∩ba∪b IOU = \frac{a \cap b}{a \cup b }IOU=abab

很显然,如果 a,b 完全重合,则 IOU 为 1,如果 a, b 没有任何交集,则 IOU 为 0,用 IOU 可以衡量两个 box 的重合度,对于重合度高的 box,是可以删掉冗余的,这就是 NMS 的原理。

NMS 实现的时候,一般是先选择一个置信度最高的 box,然后用剩余的 box 与该 box 计算 IOU,对于 IOU 高于某个阈值的,就直接删除,剩下的就是与该 box 重合度较低的,然后从剩下的 box 里,再选择一个置信度最高的,重复上面的步骤,这样直到所有的 box 都被遍历完,对于多个类别的情况,可以单独对每个类做 NMS,经过 NMS 的处理,一般一个区域就会只剩下一个 box 框。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐