date: 2020/04/28

烦恼歌 - 张学友:“心事像羽毛 越飘越逍遥”


最近YOLOv4居然更新了,正好最近要准备实习面试,是该好好把YOLO系列整理一下。


先前有两场面试的面试官说着是要问我SSD的细节,问得我云里雾里,都怀疑我们看的是不是同一个SSD。后来看了YOLO的文章发现他们是混淆了SSD和YOLO的细节……哭了QAQ,让我把YOLO的知识补起来,下次再遇到这样的面试官就痛快地怼回去!!(╯‵□′)╯︵┴─┴


参考:


DarkNet

DarkNet既是一个小众的训练框架,也是一类分类网络,这里主要介绍DarkNet分类网络。


v1启发自GoogLeNet,但没有使用Inception模块,而是简单的3x3卷积和1x1卷积的堆叠(诶那不是跟VGG更像吗),标准的版本一共24个卷积层和2两个全连接层,而fast版本只有9个卷积层同时减小网络宽度。除了最后一层使用线性激活函数之外,其他位置都是用leaky ReLU


v2启发自VGG,依旧是3x3卷积和1x1卷积堆叠的直筒式结构,包含19个卷积层和5个下采样的最大池化,称为DarkNet-19。

image.png

(DarkNet-19的详细网络配置)


v3启发自ResNet,引入残差单元,并手工设计出更快且性能更好的DarkNet-53,注意输入分辨率已经提升为256x256。

image.png

(DarkNet-53的详细网络配置)


image.png

(DarkNet-53和其他网络在ImageNet上的比较,测试平台为TitanX)


v4堆了些新trick,变成了CSPDarkNet-53(暂时不展开介绍)。


YOLO-v1

image.png


栅格系统和绑定框

image.png

假设需要被检测的类别数量为将原图划分为的栅格(grid)

总的来说,YOLO-v1将为每张图片输出一个大小为的张量(原文中取而对于VOC数据集,那么张量大小就为)。


损失函数

参考:《YOLO loss理解 | CSDN, qq_652530495

image.png

(损失函数示例,取



YOLO-v2

效果做的好,论文行文就可以为所欲为。发CVPR的论文,章标题依次是“Introduction - Better - Faster - Stronger - Conclusion”还真是一股清流……

image.png

(改进和效果总览)


Dimension Clusters

YOLO-v2试图引入SSD的锚框,但发现mAP反而有少量下降,不过召回率却有明显提升(+7%)。


SSD的锚框都是手动挑选(尺寸、宽高比等)然后通过训练来调整预测框的;

YOLO-v2指出如果能在一开始就使用质量更高的先验框(Prior Box)会得到更好的效果,并提出用训练集上真实框和KMEANS聚类来辅助挑选先验框,这里KMEANS算法选用的距离函数为


针对训练集上的每个真实框,找到与其重合程度最好的先验框,计算整个训练集上的平均IOU,以此来比较不同方案下先验框的有效性。可以看到聚类得到的5个先验框,跟手工设置的9个先验框,在数据集上能取得相当的平均IOU。

image.png

(#列表示为每个栅格选取的先验框数量)


image.png

(不同聚类中心的数量对平均IOU的影响)


从VOC和COCO的聚类结果上看,先验框倾向于瘦高,而非矮胖。

image.png

(尺度和长宽比示意,VOC和COCO数据集上先验框的聚类结果)


在yolo-v2的配置文件 yolov2-voc.cfg 中可以看到,五个先验框的高宽分别为 (1.3221, 1.73145)、(3.19275, 4.00944)、(5.05587, 8.09892)、(9.47112, 4.84053)、(11.2364, 10.0071) ,yolo-v2的栅格系统取


Direct Location Prediction

考虑一下加入锚框后,记预测框的中心坐标为



Faster RCNN和SSD的做法中并没有对做约束,当其绝对值大于1时,预测框相对于先验框偏移了整整一个栅格以上的距离,这导致YOLO引入anchor之后在训练初期出现明显的不稳定现象(初期预测不准确,严重偏移锚框附近的位置)。


为了解决这个问题,YOLO-v2将约束到区间内,即把预测框的中心坐标约束在了栅格内。

image.png

(网络输出值的实际含义)


其中(这里的坐标和宽高指的都是在的栅格系统上的坐标和宽高),

是绑定框的中心坐标和宽高;

是网络对应的输出值;

是栅格左上角的坐标;

是先验框的宽高;

是sigmoid激活函数


Fine-Grained Features

为了对小目标能有更好的检测效果,YOLO-v2引入了较浅层、分辨率较大的特征图的信息。但并非像SSD那样直接从浅层特征图上直接设置锚框来进行预测,而是借鉴了PixelShuffle上采样,反过来引入passthrough做了一个下采样。

image.png

(PixelShuffle上采样图示,YOLO-v2这里相当于反过来操作)


比如YOLO-v2设置了的栅格系统,那么最后的特征图分辨率就是13x13。YOLO-v2从26x26x512的特征图上进行前述的下采样,把信息扩展到通道维度上去,也就变成了13x13x2048的特征图,接着跟原始深层的13x13的特征图拼接然后做进一步的特征提取和回归分类。


Others


YOLO-v3

image.png


sigmoid分类预测

考虑到每个绑定框可能或多或少会包含其他真实框的内容(甚至真实框之间就有重叠),而使用softmax做分类会抑制其他类别的置信度,因此改用sigmoid做分类,把每个类别作为单独的二分类任务会更好些。尤其在复杂场景下,如Open Images数据集,会有比较好的效果。


特征金字塔FPN

引入FPN,在三种不同分辨率的特征图上设置先验框。依旧用KMEANS聚类得到九种先验框,将其按尺寸大小排序后均分给三个不同分辨率的特征图。有了FPN,就不再需要v2的Passthrough结构啦。


(图源自Joe.Zhao


(图源自Joe.Zhao


一些失败的尝试


YOLO-v4

v4可以说是集合了目前目标检测各个方向上的最新成果,论文Related Works简直就是论文导读,也给出了一些目标检测模型设计的整体思路,堆料之后对已有技术做一些微小调整最终调出了最终的YOLO-v4。


本文不详细解释论文里罗列的这么一大堆trick,只简单介绍YOLO-v4最终采用的几个已经做出自己调整的几个trick。信息量太大,一时间消化不来,有时间会逐一研读这些trick,但应该不会更新在这了。

image.png


Backbone的选择

不同的计算设备有不同的选择,


目标检测与分类任务所有的模型不同,目标检测要求,

  1. 较大的分辨率,以便检测到更小的目标;
  2. 更深的网络,以获得更大的感受野来匹配较大的分辨率;
  3. 更大的参数规模,以确保模型有足够的容量能在单张图片上检测出各种不同尺度的目标


作者列出了三个GPU上的候选Backbone,EfficientNet-B3有更大的感受野,只可惜速度实在太慢了;另外两个中,CSPResNeXt50特征图的信息稍微丰富一下,但CSPDarkNet53有明显更大的感受野、更大的模型容量、更深的网络(卷积层数量,29 vs. 16),所以按照前述的三条规则,可以看到CSPDarkNet53更适合做检测任务。

image.png

(三个GPU候选Backbone的比较)


多尺度特征

不同尺度的感受野的意义在于,

  1. 允许网络捕获各种尺度的目标
  2. 允许网络捕获目标周围的上下文信息
  3. 允许图像上每个点跟最终的激活值有更多的信息流通(甚至感受野超出输入图像本身)


在多尺度特征提取上,YOLO-v4放弃了YOLO-v3的FPN设计,引入了新的SPP和PANet路径集成,但预测框的生成等依旧保留YOLO-v3的设计。


其他