当初写这篇博客的初衷只是记录自己学习 SSD 的一些心得体会,纯属学习笔记,后来由于工作上的需要,需要对小伙伴进行目标检测方面的培训,后来就基于这篇博客进行了扩展,逐渐演变成了现在的样子,本文力求从一个初学者的角度去讲述目标检测和 SSD(但是需要你具备 CNN 的基础), 尽量使用通俗的语言并结合图表的方式让更多初学者更容易理解 SSD 这个算法,但是一个人的时间精力有限,不可能深入理解 SSD 的每一个细节,加上表达能力也有限,自己理解了的东西不一定在文中能够说明白,文中有什么不妥的地方,欢迎大家批评指正,也欢迎留言一起交流讨论。

注:
博客最初写于 2018-08-27, 2019-11-10 对原博客做了一次重大修改,又经过了一年,工作中对 SSD 又有了一些新的理解,发现以前有些地方理解还是有点问题的,现在越来越能体会到,为什么经典需要反复阅读反复思考,每次都会有新的理解,每次都能发现不一样的东西。



在实际的工作中发现,一些小伙伴在学习检测的时候对一些基础的东西理解的还不够,这里总结了比较重要的几点。

传统目标检测的基本原理

为什么要提传统目标检测呢?因为理解传统目标检测对于理解基于深度学习的目标检测非常重要,因为学到最后你会发现,两者的本质都是一样的,都是对滑动窗口的分类。下面我们看一下传统目标检测的基本原理。
SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图1

主要分为两个步骤:训练 + 预测,其中训练主要是用来得到分类器,比如 SVM, 预测就是使用训练好的分类器对图像中的滑动窗口进行特征提取然后分类,最后得到检测的结果。下面以人脸检测为例:
SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图2

假设我们需要训练一个人脸检测器,那第一步就是训练一个人脸的分类器,这个分类器有什么作用呢?它的作用就是将上图左边的很多图像划分为两类:人脸和非人脸。分类器训练好了之后,就可以进行检测了。
SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图3

预测阶段有两种滑动窗口策略:

  1. 策略 1:使用不同大小的滑动窗口,对每个滑动窗口提取特征并分类判断是否是人脸,最后经过 NMS 得到最后的检测结果,本文的 SSD 本质上就是这种策略,不同检测层的 anchor 就类似于不同大小的滑动窗口
  2. 策略 2:构造图像金字塔,只使用一种大小的滑动窗口在所有金字塔图像上滑动,对每个滑动窗口提取特征并分类判断是否是人脸,最后经过 NMS 得到最后的检测结果,MTCNN 就是采用了这种策略

传统目标检测的代表主要有:

  1. HOG+SVM 的行人检测
  2. Haar+Adaboost 的人脸检测

为什么要使用全卷积神经网络做检测

我们知道经典的深度学习目标检测算法的代表 SSD,YOLOV3 和 FasterRCNN 的 RPN 都使用了全卷积神经网络,那为什么要使用全卷积呢?

分类网络

下面是一个典型的分类网络结构:
SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图4

图片来自经典的人脸识别论文 DeepID2:https://arxiv.org/abs/1406.4773

我们知道典型的分类网络,比如 VGG,ResNet 等最后都会使用全连接层提取特征,然后经过 softmax 计算每一类的概率。

典型的分类网络有如下特点:

  1. Softmax 的前一层为全连接层,且输出节点数为分类的类别数,比如 imagenet 有 1000 类,则最后的全连接层有 1000 个输出节点,分别对应 1000 类的概率,VGG16 中的 fc8 对应了这一层,上图有 10000 分类,所以 fc2 有 10000 个输出节点
  2. Softmax 的倒数第二层也为全连接层,这一层一般是提取特征用的,比如 VGG16 中的 fc7 层就是用来提取特征的,上图中 DeepID2 层也是用来进行提取特征的
  3. 由于使用全连接层提取特征,所以提取的是全图的特征,所以一张图像中只能包含一个目标,如果有多个目标,提取出来的特征就不准确,影响最后的预测
  4. 由于全连接层的存在,网络的输入大小必须是固定的

那如何才能提取多个目标的特征呢?

使用卷积层代替全连接层进行特征提取

SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图5

我们将图 1 简化为图 2 的表示形式,其中图 2 中省略了 Input 到 DeepID2 中间的层,我们看到当 DeepID2 是全连接层的时候,感受野对应了全图,所以提取的是全图的特征,现在我们把 DeepID2 替换为卷积层,其中卷积层的输出通道数为 160,这是为了能够提取 160 维的特征向量,图 3 中我们可以看到当使用卷积层的时候,DeepID2 的输出特征图的每个位置的感受野不是对应了全图,而是对应了原图的某一个滑动窗口, 这样 DeepID2 这一层就可以提取原图多个滑动窗口的特征了,图 3 中我们可以看到一共提取出了 25 个滑动窗口的 160 维特征向量,然后我们就可以对这 25 个滑动窗口做分类了。这样就使得检测成为了可能。

使用卷积层代替全连接层进行分类

我们知道在分类网络中 softmax 的前一层使用的是全连接层,且该全连接层的输出节点数为分类数,比如上文中的 DeepID2 的后面的 fc2 层。
SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图6

但是现在 DeepID2 这一层变成了卷积层之后,fc2 层就不适合采用全连接层了。下面我们将 fc2 层替换为卷积层,我们采用 1x1 卷积 (也可以使用 3x3 卷积),同时卷积层的输出通道数为 10000,对应了 10000 分类。
SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图7

我们看到当 fc2 采用 1x1 卷积的时候,fc2 层的特征图中的每个位置对应了一个滑动窗口的 10000 分类,这样一共得到 25x10000 的特征向量,表示对 25 个滑动窗口的 10000 分类。最后将这 25x10000 的特征向量输入 softmax,就可以实现对这 25 个滑动窗口的分类了。

这其实就是经典的 OverFeat 的核心思想。

注意:这里并没有说检测网络不能使用全连接层,其实检测网络也可以使用全连接层。检测网络只是使用卷积层代替全连接层提取特征,最后对特征进行分类和回归可以使用卷积层也可以使用全连接层,YOLOV1 最后就使用了全连接层对特征进行分类和回归,只是这样会有一些缺点:网络的输入大小必须是固定的,而且最后检测的效果往往没有使用卷积层做分类和回归的效果好。

确定每个滑动窗口的类别

上文中,我们将传统的分类网络一步一步的修改成了一个检测网络,知道了如何提取多个目标的特征以及使用卷积层代替全连接层进行分类,现在我们还差最后一步:要对多个目标进行分类,还需要知道他们的 groundtruth,也就是他们的类别,那么如何确定类别呢?
这里就要用到 anchor 这项技术。

anchor 就是用来确定类别的。

SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图8

我们知道 anchor 的参数是可以手动设置的,上图中
anchor 的大小被设置为 [x1,y1,x2,y2],这个 anchor 就是上文中提到的滑动窗口
groundtruth 对应 [x1’,y1’,x2’,y2’]
然后通过计算 anchor 和 groundtruth 之间的 IOU 就可以确定这个滑动窗口的类别了 (比如 IOU>0.5 的为正样本,IOU<0.3 的为负样本)。关于 anchor 在下文中会有详细讨论。

到这里,SSD 的整体框架已经基本搭建好了。其实 SSD 的多个检测层就等价于多个 DeepID2 层,不同检测层有不同大小的滑动窗口,能够检测到不同大小的目标。每个检测层后面会接 2 路 3x3 卷积用来做分类和回归,对应了 fc2 层。
SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图9

理解了上面的内容之后,其实就很容易理解 SSD 了。


虽然 SSD 这个算法出来已经两年了,但是至今依旧是目标检测中应用最广泛的算法,虽然后面有很多基于 SSD 改进的算法,但依旧没有哪一种可以完全超越 SSD。那么为什么 SSD 效果这么好?SSD 效果好主要有三点原因:

  1. 多尺度
  2. 设置了多种宽高比的 anchor
  3. 数据增强

注:

  1. anchor,default box,prior box 表示的是同一个意思,本文统一使用更加常用的 anchor 来表示。实际上,anchor 技术的鼻祖是 DeepMultiBox(2014 年 CVPR:Scalable Object Detection using Deep Neural Networks), 这篇论文里首次提出使用 prior(先验框),并且提出使用 prior 做匹配。后面的众多工作,比如 RCNN 系列,YOLO 系列都使用了 anchor 这个术语, 而在 SSD 中 anchor 又叫 default box, 本质上都是表示的同一个东西。

原因 1:多尺度

SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图10

由 SSD 的网络结构可以看出,SSD 使用 6 个不同特征图检测不同尺度的目标。低层预测小目标,高层预测大目标。

通过前面的学习,其实就很容易理解 SSD 中的多尺度检测,这 6 个检测层都是卷积层,对应了上文中的 6 个 DeepID2 层,每个 DeepID2 层对应了不同大小的滑动窗口 (低层滑动窗口较小,高层滑动窗口较大), 这样就可以检测到不同尺度的目标了。
SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图11

作者在论文中通过实验验证了,采用多个特征图做检测能够大大提高检测精度,从上面的表格可以看出,采用 6 个特征图检测的时候,mAP 为 74.3%, 如果只采用 conv7 做检测,mAP 只有 62.4%。

原因 2:设置了多种宽高比的 anchor

SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图12

在特征图的每个像素点处,生成不同宽高比的 anchor, 论文中设置的宽高比为 {1,2,3,1/2,1/3}。假设每个像素点有 k 个 anchor,需要对每个 anchor 进行分类和回归,其中用于分类的卷积核个数为 c_k(c 表示类别数),回归的卷积核个数为 4_k。

SSD300 中 anchor 的数量:(38_38_4 + 19_19_6 + 10_10_6 + 5_5_6 + 3_3_4 + 1_1_4)= 8732

对于初学者一定有以下几个问题:

  1. 为什么要设置 anchor?
  2. 为什么同一个检测层可以设置不同大小的 anchor?
  3. 为什么一个检测层可以设置多个 anchor?
  4. 为什么要设置多种宽高比的 anchor?

理论感受野和有效感受野

NIPS 2016 论文 Understanding the Effective Receptive Field in Deep Convolutional Neural Networks[1]提出了有效感受野(Effective Receptive Field, ERF)理论。有效感受野的理解对于理解 anchor 非常重要。

影响某个神经元输出的输入区域就是理论感受野,也就是我们平时说的感受野,但该输入区域的每个像素点对输出的重要性不同,越靠近中心的像素点影响越大,呈高斯分布,也就是说只有中间的一小部分区域对最后的输出有重要的影响,这个中间的一小部分区域就是有效感受野

有效感受野在训练过程中是会发生变化的,影响有效感受野的因素:

  1. 数据集
  2. 层的类型 (下采样,扩张卷积,跳层连接,非线性激活函数)
  3. 卷积层参数初始化方式 (Uniform(参数全部设置为 1), Random)
  4. 卷积层的个数

下图展示了不同因素对有效感受野的影响
SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图13

卷积层层数,权值初始化方式以及非线性激活对 ERF 的影响

SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图14

下采样和扩张卷积可以增大感受野

SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图15

不同数据集对感受野的影响

为什么要设置 anchor?

通过前面的学习,我们知道,在分类 / 识别问题中,通常整张图就包含一个目标,所以只需要对一个目标直接分类就好了,所以最后直接使用全连接层提取整幅图像的特征就可以了 (全连接层理论感受野大小就是输入大小)。但是检测问题中,输入图像会包含有很多个目标,所以需要对多个目标进行特征提取,这个时候就不能使用全连接层了,只能使用卷积层,卷积层的输出特征图上每个位置对应原图的一个理论感受野,该位置提取的就是这个理论感受野区域的特征,然后我们只需要对这个特征进行分类和回归就可以实现检测了。在实际训练训练过程中,要想对这个特征进行分类,我们就需要知道这个特征提取的是什么目标的特征,所以我们需要知道两个东西:

  1. 这个特征对应了原图什么区域?
  2. 这个区域的 label 是什么?
    但是在实际训练过程中,我们并不知道这个理论感受野的大小,这个时候就出现了 anchor 技术。

anchor 作用:通过 anchor 设置每一层实际响应的区域,使得某一层对特定大小的目标响应。这样检测层提取的就是 anchor 对应区域的特征了。通过 anchor 我们就可以知道上面两个问题的答案了。

论文中也提到:
Feature maps from different levels within a network are known to have different (empirical) receptive field sizes. Fortunately,
within the SSD framework, the default boxes do not necessary need to correspond to the actual receptive fields of each layer. We design the tiling of default boxes so that specific feature maps learn to be responsive to particular scales of the objects.
通过设计 anchor 的平铺可以使得特定的特征图对特定大小的目标进行响应。

下图可以更加形象的表示 anchor 的作用
SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图16

图 a 中黑色虚线区域对应图 b 中的理论感受野,红色实线框是手动设置的 anchor 大小
图 b 是使用图 a 中的 anchor 参数训练出来的模型,其中整个黑色区域就是理论感受野 (TRF), 对应 a 图的黑色虚线区域,中间呈高斯分布的白色点云区域就是由于设置了 anchor 而实际发生响应的区域,这个区域就是有效感受野 (ERF),我们用 anchor 等价表示这个区域。
我们可以看到通过在图 a 中设置 anchor 可以设置该层实际响应的区域,使得对特定大小的目标响应。

这里还有几个问题需要说明一下。

  1. 为什么 anchor 可以设置实际响应的区域?
    这就是 CNN 的神奇之处,这个问题目前我还不知道如何解释,就像目前的深度学习依然是不可解释的一样,这点就当作一个结论记住就可以了。
  2. 为什么同一个检测层可以设置不同大小的 anchor
    我们知道可以通过 anchor 设置每一层实际响应的区域,使得某一层对特定大小的目标响应。
    是否每一层只能对理论感受野响应呢?有效感受野理论表明,每一层实际响应的区域其实是有效感受野区域,而且这个有效感受野区域在训练过程中会发生变化 (比如不同数据集的影响等),正是由于有效感受野有这个特性,所以我们可以在同一个检测层设置不同大小的 anchor,也就是说你既可以设置 anchor 大小为理论感受野大小,也可以将 anchor 大小设置为其他大小,最后训练出来的网络会根据你的设置对特定大小的区域响应。
  3. 为什么在同一个特征图上可以设置多个 anchor 检测到不同尺度的目标
    刚开始学 SSD 的朋友一定有这样的疑惑,同一层的感受野是一样的,为什么在同一层可以设置多个 anchor,然后在分类和回归两个分支上只需要使用不同通道的 3x3 卷积核就可以实现对不同 anchor 的检测?虽然分类和回归使用的是同一个特征图,但是不同通道的 3x3 卷积核会学习到那块区域的不同的特征,所以不同通道对应的 anchor 可以检测到不同尺度的目标。
  4. anchor 本身不参与网络的实际训练,anchor 影响的是 classification 和 regression 分支如何进行 encode box(训练阶段)和 decode box(测试阶段)。测试的时候,anchor 就像滑动窗口一样, 在图像中滑动,对每个 anchor 做分类和回归得到最终的结果。
  5. 关于 anchor 的进一步探讨,见另一篇博客:深入理解 anchor,欢迎大家畅所欲言

anchor 与滑动窗口

上文中提到了两个概念:滑动窗口和 anchor, 每个检测层对应了不同大小的滑动窗口,也对应着不同大小的 anchor, 那这两个概念有什么区别呢?

这里我们不严格区分这两个概念,我们可以认为这两个表示的是同一个东西。

这里有一点要注意:由于 anchor 是可以手动设置的,所以某一个检测层的滑动窗口大小是会随着 anchor 的大小发生变化的,这就是 anchor 的神奇之处!

anchor 的匹配

前面我们知道了 SSD 提取的是 anchor 对应区域的特征,实际训练的时候还需要知道每个 anchor 的分类和回归的 label,如何确定呢?SSD 通过 anchor 与 groundtruth 匹配来确定 label。
在训练阶段,SSD 会先寻找与每个 anchor 的 IOU 最大的那个 ground truth(大于 IOU 阈值 0.5),这个过程叫做匹配。如果一个 anchor 找到了匹配的 ground truth, 则该 anchor 就是正样本,该 anchor 的类别就是该 ground truth 的类别,如果没有找到,该 anchor 就是负样本。图 1(b) 中 8x8 特征图中的两个蓝色的 anchor 匹配到了猫,该 anchor 的类别为猫,图 1© 中 4x4 特征图中的一个红色的 anchor 匹配到了狗,该 anchor 的类别为狗。图 2 显示了实际的匹配过程,两个红色的 anchor 分别匹配到了猫和狗,左上角的 anchor 没有匹配,即为负样本。

SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图17

图 1

SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图18

图 2(图中红色框表示 anchor, 绿色框表示 groundtruth)

关于匹配更多的细节,参考 Caffe 源码 multibox_loss_layer.cpp 中的 FindMatches() 函数,前面的博客:SSD 源码解读 3-MultiBoxLossLayer中也讲到了该函数。

为什么要设置多种宽高比的 anchor?

由于现实中的目标会有各种宽高比 (比如行人),设置多个宽高比可以检测到不同宽高比的目标。
SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图19

作者实验结果表明,增加宽高比为 1/2,2,1/3,3 的 default box,mAP 从 71.6% 提高到了 74.3%。

如何选择 anchor 的 scale 和 aspect ratio?

假设我们用 m 个 feature maps 做预测,那么对于每个 featuer map 而言其 anchor 的 scale 是按以下公式计算的。
Sk=Smin+Smax−Sminm−1(k−1) Sk=S{min}+{{S{max}-S{min}} \over {m-1}}(k-1)
这里 Smin S{min} 是 0.2,表示最低层的 scale 是 0.2,Smax S{max} 是 0.9,表示最高层的 scale 是 0.9。宽高比αr=1,2,3,1/2,1/3 {\alpha}r={1,2,3,1/2,1/3}, 因此每个 anchor 的宽 wkα=Skαr w^{\alpha}{k}=Sk \sqrt{{\alpha}_r},高 hkα=Sk/αr h^{\alpha}{k}={S_k / \sqrt{{\alpha}_r}}, 当 aspect ratio 为 1 时,作者还增加一种 scale 的 anchor:Sk′=SkSk+1 S^{‘}_k= \sqrt{S_kS_k+1}, 因此,对于每个 feature map cell 而言,一共有 6 种 anchor。

示例:
假设 m=6,即使用 6 个特征图做预测, 则每一层的 scale:0.2,0.34,0.48,0.62,0.76,0.9
对于第一层,scale=0.2, 对应的 6 个 anchor 为:

宽高比
1 0.200000 0.200000
2 0.282843 0.141421
3 0.346410 0.115470
1/2 0.141421 0.282843
1/3 0.115412 0.346583
最后增加的 default box 0.260768 0.260768

注:表格中每个宽高比的 anchor 的实际宽和高需要乘以输入图像的大小,如 SSD300, 则需要使用上面的数值乘以 300 得到 anchor 实际大小。

Caffe 源码中 anchor 的宽高比以及 scale 的设置参考 prior_box_layer.cpp,前面的博客:SSD 源码解读 2-PriorBoxLayer也对该层进行过解读。

原因 3:数据增强

SSD 中使用了两种数据增强的方式
1. 放大操作: 随机 crop,patch 与任意一个目标的 IOU 为 0.1,0.3,0.5,0.7,0.9,每个 patch 的大小为原图大小的[0.1,1], 宽高比在 1/2 到 2 之间。能够生成更多的尺度较大的目标
2. 缩小操作: 首先创建 16 倍原图大小的画布,然后将原图放置其中,然后随机 crop,能够生成更多尺度较小的目标

SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图20

SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图21

作者实验表明,增加了数据增强后,mAP 从 65.5 提高到了 74.3!

数据增强是 SSD 中最大的 trick, 已经成为了后面众多检测算法的标配了。

数据增强对应 Caffe 源码 annotated_data_layer.cpp,前面的博客:SSD 源码解读 1 - 数据层 AnnotatedDataLayer也对该层进行过解读。


1. SSD 主要缺点:SSD 对小目标的检测效果一般,作者认为小目标在高层没有足够的信息。

论文原文:
This is not surprising because those small objects may not even have any information at the very top layers. Increasing the input size (e.g. from 300× 300 to 512× 512) can help improve detecting small objects, but there is still a lot of room to improve.

对小目标检测的改进可以从下面几个方面考虑:

  1. 增大输入尺寸
  2. 使用更低的特征图做检测 (比如 S3FD 中使用更低的 conv3_3 检测)
  3. FPN(已经是检测网络的标配了)

2. 关于 anchor 的设置的优化

An alternative way of improving SSD is to design a better tiling of default boxes so that its position and scale are better aligned with the receptive field of each position on a feature map. We leave this for future work. P12
论文中提到的 anchor 设置没有对齐感受野,通常几个像素的中心位置偏移,对大目标来说 IOU 变化不会很大,但对小目标 IOU 变化剧烈,尤其感受野不够大的时候,anchor 很可能偏移出感受野区域,影响性能。
关于 anchor 的设计,作者还提到了
In practice, one can also design a distribution of default boxes to best fit a specific dataset. How to design the optimal tiling is an open question as well
论文提到根据特定数据集设计 default box,在 YOLOV2 中使用聚类的方式初始化 anchor,能够更好的匹配到 ground truth, 帮助网络更好的训练


在视觉任务中经常遇到两个问题:
1. 类别不均衡
2. 简单样本和困难样本不均衡 (easy sample overwhelming)。easy sample 如果太多,可能会将有效梯度稀释掉。

为了解决上述问题,研究人员提出了一些解决方案:

  1. Online Hard Example Mining, OHEM(2016)。将所有 sample 根据当前 loss 排序,选出 loss 最大的 N 个,其余的抛弃。这个方法就只处理了 easy sample 的问题。
  2. Focal Loss(2017), 最近提出来的。不会像 OHEM 那样抛弃一部分样本,focal loss 考虑了每个样本, 不同的是难易样本上的 loss 权重是根据样本难度计算出来的。

SSD 中采用了一种新的 Mining 机制,OHNM(Online Hard Negative Mining), 在 Focal Loss 里代号为 OHEM 1:3,是对 OHEM 的一种改进。OHNM 在计算 loss 时, 使用所有的 positive anchor, 使用 OHEM 选择 3 倍于 positive anchor 的 negative anchor。同时考虑了类间平衡与 easy sample。通过 OHNM 让训练更快收敛同时也更加稳定。

注意,SSD 中 mining 具体实现的时候,MultiBoxLoss 层的 mining_type 可以选择 MAX_NEGATIVE 或者 HARD_EXAMPL

  1. MAX_NEGATIVE 对应 OHNM, 只计算分类 loss,不计算定位 loss, 只针对负样本选择 loss 最大的 3 倍于正样本数量的负样本
  2. HARD_EXAMPL 对应 OHEM ,会同时计算分类和定位 loss, 选择出 loss 最大的前 topN 个样本
    具体实现参考 MineHardExamples() 函数。

这里为什么会提到 MTCNN[2]呢?如果你了解过 MTCNN 这个算法,一定对 PNet 这个网络不陌生,仔细比较 SSD 与 PNet, 你就会发现 SSD 与 PNet 之间有着千丝万缕的联系。

SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图22

其实我对 SSD 的理解就是源于 MTCNN 中的 PNet, 实际上 SSD 可以看成是由 6 个不同的 PNet 组合而成。

这里用原论文中的 SSD300 的结构与 MTCNN 作比较
SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图23

SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图24

SSD 与 MTCNN 对比

  1. 生成训练数据的方式不同
    MTCNN 需要事先手动将所有的训练样本生成好,然后输入到网络中训练, 而 SSD 不需要,SSD 在训练过程中自动生成所有训练样本。SSD 中实际的训练样本就是所有 anchor,每个 anchor 的 label 由 anchor 与 ground truth 匹配来确定。SSD 实现了真正意义上端到端的训练。
  2. MTCNN 和 SSD 采用了两种不同的多尺度检测策略
    MTCNN:首先构建图像金字塔,然后使用固定大小的滑动窗口在金字塔每一级滑动,对每个滑动窗口分类回归。
    SSD: 在原图中设置了不同大小的滑动窗口,对不同大小的滑动窗口进行分类和回归。
    不管是 MTCNN,还是 SSD,本质上是对所有滑动窗口的分类。这与传统的目标检测方法本质上是一样的。
  3. Mining 的方式不同
    MTCNN 需要手动做 mining, 而 SSD 采用了 OHNM 训练过程中自动完成负样本的 mining,解决了简单样本的问题和类别不平衡问题。
  4. 其实 MTCNN 中也是有 anchor 的,MTCNN 中的 anchor 就是 PNet 的滑动窗口
    MTCNN 的训练样本就是滑动窗口图像,而生成训练样本的时候使用滑动窗口与 groundtruth 进行匹配,得到分类和回归的 label,所以 anchor 就是 PNet 的滑动窗口。不过与 SSD 的区别在于这个匹配过程不是训练过程中自动完成的,而是事先手动完成。
    判断什么是 anchor 的方法:使用什么匹配 groundtruth 的,那个就是 anchor

学完 SSD,以及对比了 MTCNN 之后,我们会发现,基于深度学习的检测算法,不管是 SSD,YOLOV3,FasterRCNN 还是 MTCNN, 本质上都是一样的,都是对滑动窗口的分类


2018-8-27 08:08:36
Last Updated: 2020-6-9 14:11:48


[1] [2016 NIPS] Understanding the Effective Receptive Field in Deep Convolutional Neural Networks
[2] [2016 ISPL] Joint Face Detection and Alignment using Multi-task Cascaded Convolutional Networks
[3] [2014 NIPS] Deep Learning Face Representation by Joint Identification-Verification


非常感谢您的阅读,如果您觉得这篇文章对您有帮助,欢迎扫码进行赞赏。
SSD原理解读-从入门到精通_QQ哥的专栏-CSDN博客_ssd网络 - 图25
https://blog.csdn.net/qianqing13579/article/details/82106664