大佬博客:
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−1+(−1)k−1Sk
我们不在这里过度纠结,说一些苏剑林大佬没有说的,回到这个 loss 本身的形式,其与 softmax 的形式几乎完全一致,只不过对象从一个 si 变为了一组 {sti},仔细分析一下就会发现一个问题:
对于 softmax,我们希望目标的 si 变的足够大,而其他的 si 足够小,而对上式来说,我们希望这一组 sti 的和变的足够大,但是如果其中的一个 Sti 变得足够大,loss 也会变得足够小,这时候优化便停止了。
在此我尝试进行证明:
log(Zk)=log(1≤i1<i2<⋯<ik≤n∑esi1+si2+⋯+sik)
注意到上式其实是 LogSumExp,而 LogSumExp 是 Max 函数的光滑近似,因此 loss 就可以变形为:
L≈MAX(esm1+sm2+⋯+smk)−(si1+si2+⋯+sik)(1≤m1<m2<⋯<mk≤n)
因此,当其中的一个 Sti 变得足够大,loss 就会变得足够小。
不确定的 k
通常在多标签分类任务中,其输出的个数往往是不固定的,因此确定了一个最大目标标签数 K,使用 0 标签作为填充,输出的标签数不会多于 K,这样 loss 就变为:
logZK−(st1+st2+⋯+stk+K−k个s0+⋯+s0)
这样的做就是为了过滤掉得分小于 S0 的标签,比如我们只需要输出 2 个标签,最大目标标签数为 10,制作标签时我们只需要添加相应的标签,剩下 8 位使用 0 标签填充,这是一个无效的标签(但是网络需要预测这个标签,即将 num_classes 变为 num_classes+1,不然推理时依然无法输出不固定个数的标签),允许重复输出,推理时照样输出 topK,但是将其中的 0 标签去除,ZK 同样可以使用递归求解,这里不再赘述。
统一的 loss 形式
苏剑林大佬在验证上述 loss 的有效性的同时请教了另外一些大佬,发现了 Circle Loss(有时间就看)里统一的 loss 形式,意识到了这个统一形式蕴含了一个更简明的推广方案,并且 Circle Loss 的作者也曾说过上述方法的错误性:https://www.zhihu.com/question/382802283。
统一的 loss 形式如下:
Luni=log[1+i=1∑Kj=1∑Lexp(γ(snj−spi+m))]=log[1+i=1∑Kexp(γ(snj+m))j=1∑Lexp(γ(−spi))]
上述公式将正例和负例分开进行计算,我们将交叉熵函数也写成类似的形式:
−logi=1∑nesiest=−logi=1∑nesi−st1=logi=1∑nesi−st=log1+i=1,i=t∑nesi−st
这个公式是不是十分眼熟,这就是前面所提到的 LogSumExp 函数,Max 的光滑近似,先来说说其推导过程吧。
LogSumExp
参考:
https://kexue.fm/archives/3290
http://www.matrix67.com/blog/archives/2830
http://www.johndcook.com/blog/2010/01/20/how-to-compute-the-soft-maximum/
当 x≥0,y≥0 时:
max(x,y)=21(∣x+y∣+∣x−y∣)(2)
为了近似表示 max 函数,我们可以先寻找绝对值的近似函数,绝对值函数的导数如下:
f′(x)={1,−1,x>0x<0(3)
我们使用 单位阶跃函数 来进行近似:
θ(x)={1,0,