large-scale detector专题

作者:konglanfang

大规模数据集上训练的detector比较少,本文总结了两个一阶段和二阶段的large-scale detector,并附上自己在Google open image目标检测赛道的比赛经验。

一、RFCN3000

RFCN3000

参照笔记

1.RFCN回顾

一般来说,网络越深,其具有的旋转平移不变性越强,这种特性对于分类来说有积极意义,但是对于检测任务而言,会削弱定位的精度,因为检测模型需要对位置信息具有良好的感应能力。因此在faster rcnn中,为了防止网络深度使得网络对位置的敏感度下降,RPN网络一般会向浅层特征图移动,然后再做roi-wise的分类和回归任务。但是这样明显会增加计算量。

RFCN网络是为了提高Faster RCNN的速度而提出来的,以resnet101为backbone的网络为例,faster rcnn中roi pooling的输入是在conv4_x,做完roi pooling之后还要送入conv5_x(包含9层),再还有几个全连接层。这些层作用在每个ROI上,所以会有大量重复计算(VGG16为backbone的要好些,只有两个全连接层的重复计算)。

R-FCN: 将faster rcnn中roi-wise的卷积计算都挪到ROI Pooling之前,力求实现层共享。一方面,将conv5_x的卷积计算挪到pooling层之前,然后再引入position-sensitive score map和ps roi pooling来之后需要通过在卷积层的最后一层特征图上应用$k^2(C+1)$个$1\times1$的卷积核,生成$k^2(C+1)$张位置敏感的特征图。其中:$k^2$表示一个roi中的感应位置个数,$C+1$表示类别数,特征图被分成了$C+1$个组,每组有$k^2$张特征图。进行ps-pooling操作时,每个类别对应的位置区域的特征图经过全局平均池化得到$C+1$维向量,在进行投票得到类别分数,计算分类损失。RFCN在精度较fasterRCNN提高的同时,速度也提升了3倍左右。

2.R-FCN3000

tag:

  • Large Scale Fully-Convolutional Detector
  • Decoupling Detection and Classification
  • trained on the ImageNet classification set with bounding-box supervision
  • 30fps
  • super class,k-means
  • ……

网络架构:

RFCN的弊端也很明显,当类别数很大时,生成的ps-score map的维度也要相应增多,计算量很大。因此,本文的重点就是将类别数提高到3000类的同时,通过共享卷积计算来减少卷积核数目,保证速度。

另外回归支路保持不变,因为回归与类别数无关(Faster RCNN中每个类别一个回归器,比如VOC数据集的回归支路的输出维度为$84$)。后来的大部分算法都设计成了前景和背景的两类的回归方法。所以类别数增加对回归支路没有影响。

RFCN3000是如何在增加类别数的同时,不增加计算量的呢?下面就介绍她是如何解耦的:

文章采用的就是先划分5个大类,然后再划分子类的方法。 $C$表示所有的类别数目。可以划分成$K$个super-class。。。

  • 划分方法是:在resnet101的最后一层输出(2048维)的feature 向量求均值,再使用k-means聚类得到$K$个super-class。
  • 标记方法:$ki​$表示第$i​$个super class,$cj​$表示在第$k​$个super class中的第$j​$个子类。满足$ki={c1,c2,c3……,cj}​$和$\sum^K_{i=1}|k_i|=C​$的关系。

如图2所示:上面支路表示super class的分类,position sensitive层的卷积核数是$P^2(K+1)$。该条支路对super class做分类,数目固定,即便sub class增加,也不会影响这条支路的计算量。

下面那条支路是做精细化分类的,这条支路中有$C$个卷积核,表示所有的目标类别数。该条支路没有用位置敏感的卷积层来得到ps score map,是为了减少计算量。即便$C$从20增加到3000,该条支路的分类层卷积核数目只是从20变成了3000,相比较原本的R-FCN中$(C+1)\times P^2$来说,计算量是原本的$1/P^2$,所以计算量并不大。

两条支路输出的类别概率分别是$K+1$和$C$维的,将两条支路的前景ROI概率相乘便得到了最后$C$维的输出,即最终的概率。

损失函数:平衡多任务训练损失的重要性

训练检测器时,使用了OHEM和smooth L1的定位损失。

精细化分类支路,只对正样本($C$个目标类别)应用softmax损失函数,因为正样本的ROI与所有proposal数目相比很小,所以这条分支上的损失乘以权重0.05,这样他的梯度就不会主导网络的训练。(听起来怎么这么怪呢,我觉得不对啊,正样本数目少,损失占比小,前面的权重不是应该更大才对么。。。。。)。

3.实验:

当$K$为1时,上面支路的输出即为objectness的概率,即当前ROI是否包含目标。

1.super class数目影响

(a)和(b)是在给定总的类别数的前提下,super-class数量对实验结果的影响,当super-class数量为1的时候,就相当于用于object detection的那部分(Figure2中上面那条支路)是用来检测一个object是background还是foreground。可以看出实验效果基本上随着super-class数量的增加而提升。

(c)则是在给定super-class=1的前提下,总的类别数对最后实验结果的影响。

2.聚类数目与时间的对比

总的class数量为1000前提下,对不同的聚类数目与时间和效果的对比。

二、YOLO9000

1.YOLOv1

第一代的YOLO把检测问题建模成一个回归问题,直接使用一个单一的卷积网络对整张图像进行推理,预测边界框和类别概率。极大的降低了计算量,达到了实时的效果。

它将图像分成$S\times S$的网格,每个网格预测$B$(2)个bounding box和置信度和$C$个条件类别概率,置信度,条件类别概率分别定义为
$$
Pr(Object)IOU_{pred}^{truth}
$$
预测时候类别概率:
$$
Pr(Class_i|Object)
Pr(Object)IOU_{pred}^{truth}=Pr(Class_i)IOU_{pred}^{truth}
$$
同时预测,最后在VOC数据集上,使用的$S=7,B=2,C=20$,最后的预测是一个$7\times7\times30$的张量。

在预测阶段,YOLO产生的proposal更少,只有98个,而RCNN有2000个。因此YOLO更快,且精度低,小目标检测很不准确。

2.YOLOv2

几点改进:

  • 引入batch normalization,去掉v1中的dropout,正则化模型。 gain:2%
  • 训练时使用更高分辨率的图像进行训练,(224->448),使网络能够适应更高分辨输入。gain:4%
  • anchor box: box数目从98变成$13\times13\times9=1521$,召回率提升,准确率略微下降
  • 使用k均值进行维度聚类,距离度量定义为IOU
  • 使用sigmod函数对每个cell预测的$tx,ty$进行约束到0-1之间,提高模型训练稳定性。gain:5%
  • 将大特征图$26\times26$下采样维度变高,和最后的$13\times13$的特征图拼接,获得精细化特征。gain:1%
  • multi-scale training
  • 提出了Darknet19……

3.YOLO9000

目前检测数据集因为标注成本,普遍数据量不是很大,而分类数据集的规模则很大。为了使得模型能够识别9000种的类别,作者将数据集进行了融合,提出了word tree的类别层次结构和联合训练方法。

detection的数据集类别较少,比较粗糙,而classification的数据集类别范围更宽。

以ImageNet为例:

一般训练ImageNet时,都会使用一个1000类的softmax函数,而wordtree上,作者添加了396种新类,将类别做了划分。最后使用相同训练方法的效果,word tree仅下降了一点点,而且只是新类的影响.

作者最后使用COCO和ImageNet进行融合,如下图所示:

训练的方法是,当网络看见检测标记的图片时,则回传YOLOv2的损失,当看见分类图片时,只回传分类损失。最后使得网络能够识别宽范围的类别。

三、Google Open Image-Object Detection Track

比赛首页

谷歌的OpenImageDatasetV4一共有大约900万张图片,具有几千以上的image-level的标注。其中V4的训练集包含174万张图片,标注了14.6million的边界框,600个类,所以是现在最大的检测训练集。

比赛数据集划分: train (1,743,042), validation (41,620), and test (125,436) sets.

图片大小:长边 最多 1024 pixels on their longest side, while preserving their original aspect-ratio.

试验方案1:YOLOv3

object detection using YOLOv3

这是最初采取的方案,训练了3天之后发现效果很差,出来的类别分数特别低。本来YOLO3框框是不太准,所以换了retinanet.

试验方案2:Retinanet

1.retinanet相关

两篇论文:

Feature Pyramid Networks for Object detection

focal loss

各版本code:

keras-retinanet

pytorch-retinanet

博客:

我写的博客

The intuition behind RetinaNet写的非常好

2.实验细节

关于调参方案,参照了几个链接:

fastai

neptune-git

neptune-io

neptune-retinanet

首先直接500类训练,使用的backbone是resnet50.由于训练集数目众多,为了能够尽快训练,所以没有使用更深的网络。

  1. 划分类别

比赛数据的类别层次结构参见这张图:hierarchy_visualizer

通过观察类别,发现其中person类和person相关的clothing类占了大约80类,因此,在训练整个数据集的同时,我又将这80类相关的图片挑了出来,只训练这80类。

  1. 输入大小

训练初期,将图片resize到$800\times600$,为了快速训练,尽管初期的训练不够准确,但是能让模型尽快见过尽量多的图片,从而加快训练过程。训练几个epoch之后,将图片分辨率提高到的大小在进行训练,让网络学习到更加精细化的特征。

还有一个减小训练时长的方法就是,去掉BN层中的weight decay.7 minute training of Imagenet on 2,048 GPUs

  1. 尽量使用大的batch-size训练

Multi-gpu

参照MegDet,如果使用小的batchsize来进行训练的话,可能存在:正负样本比例失调、BN层统计不准确,训练时间长、梯度不稳定等特点,因此要尽量使用大的batch-size进行训练。我使用的集群一个节点只有两张V100的GPU,且,一张有16G RAM,按理说,应该可以将batch-size设的大一点,但是总是报OOM的错误,我就只能最高设到4,即一张卡2张图片。

multi-machine

基于horvod的分布式深度学习训练方法

这个horvod居然是Uber的,咳咳咳,想不到啊。

参考论文:Horovod: fast and easy distributed deep learning in TensorFlow

3.参数:

neptune提供的实验参数

1 load_in_memory 0
3 validation_sample_size 10000
4 step per epoch 10000
5 batch-size 4
2 GPU 2张v100
6 num_threads 100
9 lr_factor 0.3
14 pad_method resize
15 encoder_depth 50
16 fixed_w 512
18 fixed_h 512
19 num_classes 10
24 pi 0.01
28 long_dim 960
30 short_dim 640
33 epochs_nr 100
35 aspect_ratios [1/2., 1/1., 2/1.]
36 num_workers 4
37 lr 1e-05
41 image_channels 3
42 scale_ratios [1., pow(2,1/3.), pow(2,2/3.)]
45 momentum 0.9
46 loader_mode resize
47 batch_size_train 4
48 batch_size_inference 1
50 l2_reg_conv 0.0001
52 classification_threshold 0.5
53 nms_threshold 0.5

4.retinanet的弊端

focal loss弊端

四、Facebook的Large minibatch SGD

论文:Accurate, Large Minibatch SGD

笔记:如何评价Facebook Training ImageNet in 1 Hour这篇论文?

1.