YOLO

YOLO series: YOLO v1. YOLO v2 and. YOLO v3

1. YOLO v1

核心思想

直接在输出层回归 bounding box 的位置和 bounding box所属的类别(整张图作为网络的输入,把 Object Detection 的问题转化成一个 Regression 问题)

YOLO v1 流程

  1. 将图片Resize成448x448,分成7x7个网格(grid cell),某个物体的中心落在这个网格中此网格就负责预测这个物体。

  2. 提取特征和预测,卷积部分负责提取特征。全连接部分负责预测:

    • 两个 【bounding box(bbox) + confidence】 (2x5)
    • 20个物体的概率(20)

    总的输出为 (7X7)X30 的维度。

  3. 过滤bbox(通过nms)

2. YOLO v2

  1. class-specific confidence score:

    class-specific confidence score 是三项的成绩。第一项是 bbox每个网格预测的类别信息即20个物体的概率, 第二项是每个 bbox 的置信度, 第三项是 ground truth 和 预测框的 IOU。得到每个bbox的class-specific confidence score以后,设置阈值,滤掉得分低的boxes,对保留的boxes进行NMS处理,就得到最终的检测结果

  2. 损失函数的设计:

3. YOLOv3

论文改进点

  • BN + leaky ReLU + res connection[ 加入了BN层, 激活函数使用了Leaky ReLU, 并且引入了残差连接 ]

  • backbone(FPN multi scales)[ 仿照FPN网络结构的多尺度检测 ]

  • loss function [ 除了w、h仍然使用平方均差, 其他均使用交叉熵。然后按权重相加 ]

  • bbox anchor priors -> softmax [ 聚类获得先验框大小 ]

(1) YOLOv3 结构

​ 先使用 DBL (conv+bn+leaky_relu) 进行一个简单的滤波处理, 然后接res1, res2, res8 提取特征1, 再接 res8 提取特征2, 再接 res4 提取特征 3, 最后融合三个特征。

  • 相比于 YOLO V2 的 darknet19 采用 maxpool 进行下采样, YOLO V3 提出的 Darknet53 则使用 stride 为 2 的卷积核来实现下采样。在 YOLO v3 中, 要经历五次下采样, 特征图尺寸缩小为原来的 1/32, 即输入为 416 x 416, 输出为 13x13。

x

  • 具体的细节实现上, darknet 19 的 conv + bn + relu 被替换为 conv + bn + leaky_relu。并在此基础上添加了残差结构。

  • 三个输出分别是 13x13x255、26x26x255、52x52x255。yolo v3 输出了3个不同尺度的 feature map,YOLO v3 借鉴了 FPN(feature pyramid networks),采用多尺度来对不同 size 的目标进行检测,越精细的 grid cell 就可以检测出越精细的物体。

    255的来源 ? COCO 的类别数为 80, 加上位置信息 x, y, w, h 和 confidence 为 85。每个网格单元预测 3 个 box。 总共为 3 *( 80 + 5) = 255。

(2) 损失函数

​ 在 YOLO v3除了w、h 仍然使用平方均差, 其他 (x, y)、 class, confidence 均使用交叉熵,然后按权重相加,损失函数应该由各自特点确定。最后加到一起就可以组成最终的 loss_function 了,也就是一个loss_function搞定端到端的训练。

xy_loss = object_mask * box_loss_scale * K.binary_crossentropy(raw_true_xy, raw_pred[..., 0:2], from_logits=True)
wh_loss = object_mask * box_loss_scale * 0.5 * K.square(raw_true_wh - raw_pred[..., 2:4])
confidence_loss = object_mask * K.binary_crossentropy(object_mask, raw_pred[..., 4:5], from_logits=True) + \
                          (1 - object_mask) * K.binary_crossentropy(object_mask, raw_pred[..., 4:5],
                                                                    from_logits=True) * ignore_mask
class_loss = object_mask * K.binary_crossentropy(true_class_probs, raw_pred[..., 5:], from_logits=True)

xy_loss = K.sum(xy_loss) / mf
wh_loss = K.sum(wh_loss) / mf
confidence_loss = K.sum(confidence_loss) / mf
class_loss = K.sum(class_loss) / mf
loss += xy_loss + wh_loss + confidence_loss + class_loss

以上是一段 keras 框架描述的 yolo v3 的 loss_function 代码。忽略恒定系数不看,可以从上述代码看出:除了 w, h 的损失函数依然采用均方误差之外,其他部分的损失函数用的是交叉熵。最后加到一起。

(3) Bounding Box Prediction

​ 对于YOLO v3 而言,在 prior 这里的处理有明确解释:选用的 bbox priors 的 k=9,对于 tiny-yolo 的话,k = 6。priors 都是在数据集上聚类得来的,有确定的数值,如下:

10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326

​ 每个 anchor prior 就是两个数字组成的,一个代表高度另一个代表宽度。 v3对b-box进行预测的时候,采用了logistic regression。输出和v2一样都是 (t_x, t_y, t_w, t_h, t_o),然后通过公式1计算出绝对的 (x, y, w, h, c) 。

c

​ logistic回归用于对anchor包围的部分进行一个目标性评分(objectness score),即这块位置是目标的可能性有多大。这一步是在predict之前进行的,可以去掉不必要anchor,可以减少计算量。

4. YOLOv4

5. YOLOv5

6. PP-YOLO

7. Bag of Freebies

论文《Bag of Freebies for Training Object Detection Neural Networks》提炼了目标检测算法通用训练 tricks,论文说是 Bag of Freebies,并且更倾向于对 One-stage 系列优化,one-stage 计算量更小,在落地上更为普遍。

二、目标检测训练Tricks

论文[1]总共提到了六种通用的训练Tricks,其中有几种在yolov3原始算法中都有用到,所以说不得不承认yolo系列是非常优秀的目标检测算法。具体为

1、Visually Coherent Image Mixup for Object Detection (mixup数剧增强,借鉴文[2])

与[2]原始的mixup不同点有两点:

1)文[2]提出的mixup数据增强是一种有特色方法,但是实验对象是分类与对抗生成网络,成对图像的mixup是以resize到相同大小的图像为前提完成的。

img

目标检测问题中如果resize图像到相同大小则会造成图像畸变,检测任务对于这种变化较为敏感,因此作者采用保图像几何形状的方式对图像进行mixup,我的理解是图像直接mixup成对图像,取最大宽高并填充(constant合成的空白区域),最后计算损失时按照mixup的beta分布产生的权重,对损失进行加权求和,再反向传播loss更新模型权重。

img

2)文[2]的mixup方法中成对图像求加权和的权重是由Beta分布随机生成(Beta分布如图),Beta的两个参数默认取值1.0(源码),原始mixup论文[2]试验则是从0.2到1.0的几组试验值,论文[1]采用的Beta分布两个参数则是取值大于等于1,在实验中Beta分布的参数值取1.5时效果更好,涨点明显:

img

img

4. 标签平滑 label smoothing

label smoothing 个人感觉则是对标签放松处理(改变类别的分布),使得目标函数不至于太严格,降低不同类别的置信度,一定程度上使得模型更易于收敛且能避免模型过拟合(over fitting)。对目标类别的 Ground Truth 做如下处理,对原始标签乘上一个小于 1 且接近于 1 的数,再加上一个类似正则项的东东,其实也就是一种对目标函数做的正则化处理。

img

其中,K 为类别数目,分子为小正数, 一般取 0.1 。具体的描述可以参看论文[3]。

for images, labels in train_loader:
    ...
    N = labels.size(0)
    # C is the number of classes.
    smoothed_labels = torch.full(size=(N, C), fill_value = 0.1 / (C - 1)).cuda()
    smoothed_labels.scatter_(dim=1, index=torch.unsqueeze(labels, dim=1), value=0.9)
    
    ...
5. 数据预处理 Data Preprocessing

文章着重评估了常见的图像增强方法:

  • 几何变换:随机裁剪、随机扩张、随机水平翻转、随机 resize
  • 颜色抖动:亮度、色调、曝光度、对比度调整
6. Training Scheduler Revamping(训练策略改进)

这里主要采用的方案是: warmup + cosine schedule

7. Synchronized Batch Normalization

这个策略是针对土豪提的,对于大规模数据集的多卡训练,Batch会被分割成很多小部分(小 Batch)在不同的显卡,这样实际上虽然加速了训练,但是Batch却变小了,可能会限制Batch Normalization的作用,与大Batch训练的初衷向左。对于分类问题可能影响不到,但是对于对Batch敏感的目标检测任务则影响很大。基于此采用Synchronized Batch Normalization。

8、Random shapes training for single-stage object detection networks 多尺度训练

在训练的过程中, 每隔一定的 iterations 就改变训练图片的尺度,这样做可以实现跨尺度特征融合,也能使得模型在多种输入大小下训练以适应不同的图像大小输入。这样做也可以使得模型不容易过拟合以增强泛化性能。

8. YOLO 的轻量级改进型


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!