众所周知,FocalLoss(FL)的公式是
,其中如果真实
,则
,如果真实
,那么
,我们总是希望
越大越好,所以那些
比较小,即
比较大的训练样本,它们的预测效果是不好的,应该占有更大的权重,因此,将
作为权重与原始的分类损失相乘,其次方
可以调整。
同样的众所周知,LabelSmooth(LS)也能提升分类任务的效果,其实现为,将原来的target进行soft化,比如二分类,原来的正/负类label是1/0,label smooth是将其调整为0.9/0.1(也可以是0.95/0.05或0.8/0.2),根据pytorch的文档,
根据这种计算方式,没有LS的正类的损失为:
而经过LS的正类的损失为:
。
那么如果把这两个一起用在二分类上,如何实现呢?
实现1
Richard Lee:Focal loss tf+pytorch实现(带ohem和label smoothing)zhuanlan.zhihu.com其中关键代码是这么写的:
pt = pred * label + (1 - pred) * (1-label)
diff = (1-pt) ** self.gamma
FocalLoss = -1 * alpha_t * diff * pt.log()
实现2
皮特潘:Focal loss的简单实现(二分类+多分类)zhuanlan.zhihu.com其中关键代码是这么写的,pt相当于上面的pred:
pt = torch.sigmoid(predict)
loss = - self.alpha * (1 - pt) ** self.gamma * target * torch.log(pt)
- (1 - self.alpha) * pt ** self.gamma * (1 - target) * torch.log(1 - pt)
这里我们暂时不考虑FocalLoss中的
参数,将其展开写为:
1的写法可以抽象为:
,
,
2的写法可以抽象为:
不用LS的时候,1是等价于2的。对于正类,写法1的损失:
,
写法2的损失:
。
但是,用了LS之后,1和2就不等价了,1对于正类的损失:
,
2对于正类的损失:
我们希望网络输出的正类预测值越接近0.9越好,负类预测值越接近0.1越好,所以我个人觉得需要这么写,有点像把上面两种写法综合起来,但系数不一样:
此时正类的损失为:
如果从上面两个二选一的话,我倾向于选2,因为1没有体现出来label smooth的感觉,大家觉得呢?