SSD中难分负样本挖掘
训练时需要保持样本均衡,default boxes与真实样本匹配之后负样本集数量远远大于正样本集,会导致损失不易收敛。按照分类损失对样本进行排序,选择难分负样本(损失值高的负样本,即被分类错误的负样本)参与损失计算,一般正:负=1:3,
def ssd_losses(logits, localisations,
gclasses, glocalisations, gscores,
match_threshold=0.5,
negative_ratio=3.,
alpha=1.,
label_smoothing=0.,
device='/cpu:0',
scope=None):
#……(省略)
# Compute positive matching mask...
pmask = gscores > match_threshold #分数大于阈值的为正样本
fpmask = tf.cast(pmask, dtype)
n_positives = tf.reduce_sum(fpmask) #统计正样本的个数
# Hard negative mining...
no_classes = tf.cast(pmask, tf.int32)
predictions = slim.softmax(logits)
nmask = tf.logical_and(tf.logical_not(pmask), gscores > -0.5)
fnmask = tf.cast(nmask, dtype)
nvalues = tf.where(nmask, predictions[:, 0], 1. - fnmask)
nvalues_flat = tf.reshape(nvalues, [-1])
# Number of negative entries to select.
max_neg_entries = tf.cast(tf.reduce_sum(fnmask), tf.int32) #负样本总数量
n_neg = tf.cast(negative_ratio * n_positives, tf.int32) + batch_size
n_neg = tf.minimum(n_neg, max_neg_entries)
val, idxes = tf.nn.top_k(-nvalues_flat, k=n_neg) #损失最高的n个负样本
max_hard_pred = -val[-1]
# Final negative mask.
nmask = tf.logical_and(nmask, nvalues < max_hard_pred)
fnmask = tf.cast(nmask, dtype)
Focal Loss
解决问题:
1.类别不平衡 正负样本比例悬殊
2.分类难度有差异 负样本中易分类负样本比难分类负样本多
解决办法:
以二分类交叉熵损失为例,在交叉熵损失中加入了两个因子
1.
C
E
(
p
t
)
=
−
α
t
l
o
g
(
p
t
)
CE(p_t)=-\alpha_tlog(p_t)
CE(pt)=−αtlog(pt)
2.
F
L
(
p
t
)
=
−
(
1
−
p
t
)
γ
l
o
g
(
p
t
)
FL(p_t)=-(1-p_t)^{\gamma}log(p_t)
FL(pt)=−(1−pt)γlog(pt)
1.交叉熵
其中p是预测类别的概率
y=1时,p越接近1,熵越小
y=-1时,p越接近0,熵越小
简化公式
这个损失函数对应下图的蓝线
一般来说概率大于0.5的时候,应该是比较容易预测分类的,+1,或者-1
但是损失函数在这一部分还有不是很小的值
负样本非常的多,那这样这些损失函数加起来很大
负样本对训练过程的影响远远大于正样本
2.平衡交叉熵
为了解决样本分布不平衡的问题,通常是在交叉熵中加入权重
α ∈ [0, 1] class 1
1-α for class -1
(参数α可以是超参数,也可以由类别的比例倒数决定)
C
E
(
p
t
)
=
−
α
t
l
o
g
(
p
t
)
CE(p_t)=-\alpha_tlog(p_t)
CE(pt)=−αtlog(pt)
3.Focal Loss
α改变了正负样本的权重,但是没有区分easy/hard样本
易于分类的负样本非常多,作者设计了一个损失函数降低易分样本easy-examples的权重,专注于训练难分样本hard examples
下图中 γ∈[0,5]
难分样本:一个样本被误分类,即正样本被误分类为负样本,或者负样本被误分类为正样本
(1)难分样本的
p
t
p_t
pt较小
(easy)正样本被正确分类为正样本,此时p接近1,
p
t
p_t
pt接近1
(easy)负样本被正确分类为负样本,此时p接近0,
p
t
p_t
pt接近1
(hard)正样本被错误分类为负样本,此时p接近0,
p
t
p_t
pt接近0
(hard)负样本被正确分类为正样本,此时p接近1,
p
t
p_t
pt接近0
当
p
t
p_t
pt接近0的时候,调节因子(modulating factor)接近1并且损失几乎没有被影响。
而当
p
t
p_t
pt接近1的时候,modulating factor接近0,降低了易分类样本所占权重。
(2)这个参数可以平滑的调节降低易于分类的样本比率
实际应用中加入了α,相比于不加可以提高精度
在使用这个损失函数的时候结合sigmoid来计算P会使训练更加稳定。
4.类别不平衡与模型初始化
二分类通常默认初始化为y=1和y=-1输出有相同的概率
问题:在这样的初始化之下,由于类别不平衡,出现频率高的类会主导总的损失,在训练早期导致不稳定。
解决:作者提出优先的概念,在训练初期对于模型对于低频率的类(背景)估计的p给予“优先”。
作者把这个“优先”(prior)记做 π ,设定它,以至于模型对于低频率类别(rare class)的样本的估计p很低,比如说0.001。
这是模型初始化的改变,而不是损失函数的改变。作者发现这点能改进训练的稳定性(对于在类极不平衡的情况下的交叉熵和focal loss都有效)