大佬博客:
https://kexue.fm/archives/7359
https://kexue.fm/archives/8888
从单标签到多标签
在上篇文章中已经介绍过了处理常规多分类问题(也就是单标签分类)的基本操作——softmax 和交叉熵损失函数,那么什么是多标签分类呢?
单标签分类是从 n
个候选类别中选取一个 1
个目标类别进行分 类,损失函数的优化目标则是使目标类别的得分最大,可以参考上篇文章的交叉熵损失函数;
对于多标签分类,我们从 n
个候选类别中选取 k
个目标类别(当做正例,即是与不是的问题),换种理解就是我们同时进行 n
个二分类任务。
直观上,我们可以直接选择使用 sigmoid
激活,使用二分类的交叉熵之和作为 loss,然而当 n>>k
时,会有很严重的类别不均衡问题,当 k 极小时,网络只需要简单将结果全部预测为负例也可以得到很小的 loss 值;但是单标签分类中,k=1 并没有这种类别不均衡的问题,因为我们使用了 softmax
,使得交叉熵能够不偏不倚的对每个预测获得合适的损失。
因此,一种直觉上的思路是多标签分类的损失函数可以有 softmax 进行外推,换言之,当 k=1 时,该损失函数会退化成 softmax。
组合 softmax
苏剑林大佬首先考虑了 k
固定的情形,显然推理时我们只需要输出得分的 top-k 即可,那么训练时的 loss 怎么办呢?
类比单标签的 n
选 1
,我们可以将多标签表示为 Cnk 选 1,这样便得到其 loss 应该为:
−log1≤i1<i2<⋯<ik≤n∑esi1+si2+⋯+sikest1+st2+⋯+stk=logZk−(st1+st2+⋯+stk)(1)
上式最难计算的地方便是分母,苏剑林大佬提出利用牛顿恒等式来简便计算,设 Sk=i=1∑neksi,可得:
Z1=2Z2=3Z3=⋮kZk=S1Z1S1−S2Z2S1−Z1S2+S3Zk−1S1−Zk−2S2+⋯+(−1)k−2Z1Sk