SSD实现口罩识别

检测任务是做什么

  • 检测任务, 是找到一张图中所有目标物体的位置(用bounding box来表示)以及对应类别.
  • 注意: 不同图中目标物体的数量是不确定的. 也就是说, 最终输出的结果个数是不固定的.
  • 可以把检测任务分解为分类+定位两个任务, 分类负责确定目标物体的类别, 定位负责确定目标物体的位置. 但由于不同图中目标物体的个数是不缺定的, 因此不能简单地使用一个固定输出大小的multi-label模型, 需要有新的思路来实现目标物体数量不确定的情况

检测实际上就是目标物体数不确定的分类+定位问题:

检测任务基本思路

上述说到, 由于检测的输入图片的目标物体数量是不确定的, 需要想个办法解决问题. 考虑的因为一张图中, 不同物体的位置是不同的, 那么我们把一张图切分成多张子图, 每张子图只负责预测1个物体, 那么这个问题就解决了.

当然, 像上述一样的切分方式对其他图可能就没效果了.

为了保证把一张图切成多张子图的时候, 每个目标物体都能被切成独立的一张图, 我们可以使用不同尺寸的滑动窗口, 有重叠地移动, 保证了每个目标物体都能被作为一张子图来训练. 这就是最早的overfeat模型所使用的方法, 如下图所示:

检测的基本思路就是把一张图分解成多张图, 每张图都分别做一次分类和定位.

不同模型的区别就在于如何对图进行切分. 两级目标检测算法和单级目标检测算法就是两种图形切分的大方向.

本论文采用SSD模型是一种单级目标检测,如图13所示,一张遮住人脸的图像所标记候选框的结果,与两级目标检测算法作对比,单级目标检测是端到端的算法过程,并且加载速率高,倘若经过卷积网络模型的训练与整理,即便是图像的解析度不高,也可以在检测的精确度上面获取到不错的佳绩。

SSD

SSD的输入是一个大小为(300, 300)或(512, 512)的图片, 后面我们将以大小为(300, 300)的输入为例子来介绍SSD

从模型结构中, 我们可以看到, SSD实际是一个全卷积网络. 如下图左上角所示, 其最后的完整输出是一个长方体, 这个长方体长宽都为m, 通道数=k*(n_label+4), 其中n_label是预测的种类数, 4是坐标数, k是anchor种类数(anchor种类的大小与长宽比有关). 如下图右上角所示, 我们可以把一个完整的输出, 拆分成k*m*m个单独输出, 每个输出都包括类别(n_label)与4个bbox坐标, 即(n_label+4). 每一个这样的单独输出都与一个anchor对应, 即与输入的一个固定的矩形区域对应. 如图所示, 每一个输出, 都对应输入图像的一个anchor.

  • anchor是输入图像中一些固定大小位置和长宽比的矩形区域. 每个anchor都跟一个输出对应.
  • anchor的大小是根据输出位于网络哪一层确定的, 位于网络越深的层, 对应anchor面积越大, 如下图中间是浅层特征的输出, 右边是深层特征的输出. 浅层结果输出的空间分辨率较大, 每个输出对应anchor(图中用虚线表示)的面积较小, 而深层输出对应的anchor面积较大. 具体面积可以参考论文中的计算公式.
  • anchor长宽比包括1, 2, 3, 1/2, 1/3. 由于同一个位置上(anchor中心点)有不同长宽比, 所以同一个位置上的anchor不止一个。
  • anchor是输入图片上一个固定的矩形区域, 在训练时, 这个矩形区域范围附近如果存在物体(满足anchor与物体的iou大于0.5), 那么这个anchor对应的输出的label就是该物体. 否则就是背景. 如上图有两个anchor跟猫iou满足, 那么这两个anchor对应的输出为猫. 同理, 狗也是.

 SSD在训练什么

回到anchor, 每个输出都有一个对应的感受野, 也有一个anchor, 虽然我们每次输入感受野内的图像, 但并不以感受野存在物体而就认为它的输出是这个物体. 只有当感受野内的anchor满足与物体iou大于0.5, 才预测存在物体. 因此, 总结起来, 我们学习的实际是一张图(感受野)与固定范围(anchor)的iou大于0.5的物体是什么, 以及这个物体相对于anchor位置的偏移量什么. 因此, anchor实际上就是一个RoI, 相比于fast-rcnn的roi, SSD的roi是固定的, 且每个roi都有输出.

总结起来, 不严格地讲, SSD训练一张图片, 如下图左边图所示, 相当于把一张完整图切分成大大小小8732张子图(300*300的模型一共有8732个anchor), 每张子图都有一个固定的RoI区域(如下图中间部分所示), 然后以8732张子图作为一个batch进行训练. 在训练时, 如果RoI区域与物体满足IoU条件, 我们将其对应的label设为该物体, 并且预测其与对应anchor的偏移, 否则预测为背景. 这样当预测时, 也是把一张图切成这么多子图, 然后分别进行预测.

SSD预测的目标就是以一张图中所有anchor为窗口, 看其窗口是否存在物体, 如果有物体, 预测其类别以及位置. 无物体则预测为背景.

类不平衡问题

这样就引出了一个问题, 一张图, 相当于我们一次训练8732张图片, 但这8732张图片大部分是背景图, 这样就产生了严重的类不平衡问题, 如下图. SSD解决的方法就是通过启发式采样, 每次并不训练8732张图片, 而是训练所有的正样本, 然后再取loss最大的负样本k个, 使得正负样本比例为1:3. 虽然这一定程度上缓解了类不平衡问题, 但实际上, 由于训练的的负样本总数是不变的, 每次训练, 每个负样本依旧都有机会与正样本进行训练, 导致负样本在训练时, 对loss的贡献要覆盖了正样本对loss的贡献, 影响了梯度更新的正确方向, 导致模型无法学习到有用的特征.

总结

  • SSD这类1-stage的检测模型实际上是把一张完整的图分成固定大小与长宽比的成千上万个划窗, 分别预测类别与bounding box
  • 理解一个模型, 不仅仅要理解网络结构, 还需要理解训练过程的数据流, 才能知道模型到底学习了什么. 例如, SSD的训练过程, 实际上可以看成多张图片进行分类与回归, 因此会出现类不平衡问题
点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注