YOLOv4中,为了防止分类过拟合,使用了标签平滑Label Smoothing的技巧。
Label Smoothing最早源于论文《Rethinking the inception architecture for computer vision》,这里不讨论。基本原理如下:通常YOLO模型中,80个分类标签都是使用0或1进行描述,在训练过程中,如果认为属于第n个分类,则该位置输出1(这种分类标签编码形式也称为one hot编码,即一位(独热)编码)。在数据集为无穷的情况下,可以对所有分类进行训练和标记,但是数据集不可能是无穷,尤其是当数据集量并不太大的时候,训练次数过多,很容易造成过拟合。采用Label Smoothing的技巧可以将标签的确定性减弱,从而降低过拟合的可能性。
在YOLOv4的实际代码中,将Label Smoothing体现在了计算分类函数求导得到的delta中,YOLO模型的分类求导和反向传播可以参考文章《YOLO中LOSS函数的计算》(https://editor.csdn.net/md/?articleId=106583800)和《YOLOv3反向传播原理 之 全流程源码分析》(https://editor.csdn.net/md/?articleId=107303735)。
关于Label Smoothing的实际操作具体而言,令
l
a
b
e
l
t
r
u
e
s
m
o
o
t
h
=
l
a
b
e
l
t
r
u
e
×
(
1
−
α
)
+
l
a
b
e
l
t
r
u
e
×
α
label_{true_{}} ^{smooth}= label_{true_{}} ×(1-α)+label_{true_{}} ×α
labeltruesmooth=labeltrue×(1−α)+labeltrue×α
这个真标签在实际应用中体现在求delta的过程中,原delta在YOLOv3代码中为:
delta[index + stride*class] = 1 - output[index + stride*class];
在YOLOv4中处理后代码如下:
void delta_yolo_class(float *output, float *delta, int index, int class_id, int classes, int stride, float *avg_cat, int focal_loss, float label_smooth_eps, float *classes_multipliers)
{
......
float y_true = 1;
if(label_smooth_eps) y_true = y_true * (1 - label_smooth_eps) + 0.5*label_smooth_eps;
float result_delta = y_true - output[index + stride*class_id];
if(!isnan(result_delta) && !isinf(result_delta)) delta[index + stride*class_id] = result_delta;
......
这里在计算delta的第二项将
l
a
b
e
l
t
r
u
e
label_{true_{}}
labeltrue写成0.5,应该是一个加强作用,另外还可以防止出现
l
a
b
e
l
t
r
u
e
s
m
o
o
t
h
>
1
label_{true_{}} ^{smooth}>1
labeltruesmooth>1的情况发生。
版权声明:本文为CSDN博主「北溟客」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41736617/article/details/115338124
暂无评论