多标签分类问题的一个“临时解决方案”

近年常遇多标签分类问题,尝试过一些方案,效果平平,常感困惑,是否存在一种“放之四海而皆准”通用解决方案?而不是每次都需要重新设计feature提升效果?

分类任务流程

一般来说,针对一个分类任务,先看是不是单纯的单标签分类任务,还是多标签分类任务,抑或是混杂着部分多标签分类的单标签分类任务。第一种情况比较简单,直接用上标注数据用预训练模型finetune即可,工作量主要在数据处理以及badcase分析。第三种情况需要视情况而定,可以采样标注部分数据,统计多标签样本的总体比例,如果低于预期目标值(如5%等),大可考虑将任务当成第一种情况处理,若比例不低但不超过30%,可以考虑单标签加上一定的后处理(取模型输出topn卡阈值过滤标签等)。若是比例较大,则基本上只能归入第二种情况进行考虑。

多标签分类的困境

纯粹的多标签分类目前学术界没有比较好的能落地的成熟方案,要么是从数学建模出发,直接将分类任务替换成seq2seq任务,将数据多个标签组合作为目标seq进行训练,要么是从标签之间的独立性出发,构建标签的相关性矩阵,在分类训练中加入标签之间的相关性,辅助输出最终结果。这些大多都止于paper实验,鲜有实际工业场景使用示范。

工业界在多标签分类任务的处理上,有些会先试试直接上单标签分类,看效果如何,最不济可以当个baseline。有些会直接上BCE Loss,卡阈值输出,阈值常用0.5,有时也会根据具体情况针对不同类别使用不同阈值,不过这种方式有点过于tricky且效果一言难尽(之前在千数量级类别的任务上尝试过卡不同类别阈值,效果不佳,于是放弃)。在标签总数(不超过20个)不多的情况下,直接将任务转为二分类是个可以考虑的方向,在降低分类难度的同时,增加不多的类别不平衡程度,性价比较高。类别数量较多的情况下使用二分类需要进行精调(主要是类别平衡方面的调整),才能有比较好的提升。

从二分类到多标签分类

苏剑林在其[博文][1]中提出使用“softmax+交叉熵”推广到多标签分类,其核心观点是对单标签loss从logsumexp函数性质角度入手,推出loss背后的数学意义,然后将其推广到多标签分类,添加必要项,得到单/多标签分类统一loss形式。文章整体逻辑清晰,推导简洁易懂,更重要的是,没有对模型结构或者训练任务进行大改,而是只修改了loss部分,这一点对工业界十分友好,便于快速测试验证效果。最终的统一形式loss公式为:

$$ log(1 + \prod_{j \in \Omega_{pos}}e^{-s_j}) + log(1 + \prod_{i \in \Omega_{neg}}e^{s_i}) \tag{1} $$

评论中有人对二分类常用的BCE Loss公式进行推导,也能得到博文中的结果,在此贴一下具体的推导过程如下。去掉BCE Loss展开式(4)式的高阶项,只保留一阶项,就得到了(1)式。

$$ \begin{align} L &= -(\sum_{j \in \Omega_{pos}}log\frac{1}{1+e^{-s_j}} + \sum_{i \in \Omega_{neg}}log\frac{1}{1+e^{s_i}}) \\ &=log(\prod_{j \in \Omega_{pos}}1+e^{-s_j}) + log(\prod_{i \in \Omega_{neg}}1+e^{s_i}) \\ &=log(1 + \prod_{j \in \Omega_{pos}}e^{-s_j} + \cdots) + log(1 + \prod_{i \in \Omega_{neg}}e^{s_i} + \cdots) \tag{2} \end{align} $$

博文从单分类loss出发,一步步推导得到(1)式。上面的推导从二分类loss角度出发,一步步推导也能得到(1)式,说明在(1)式loss的监督下,多标签分类任务的训练会比单标签分类难,但训练比二分类要简单(去掉了高阶项的严格要求)。

说说自己对高阶项的一个看法: 正如“用sigmoid激活,然后变成n个二分类问题,用二分类的交叉熵之和作为loss。显然,当n≫k时,这种做法会面临着严重的类别不均衡问题,这时候需要一些平衡策略,比如手动调整正负样本的权重、focal loss等。”说道,sigmoid+交叉熵因为存在类别不平衡的原因,需要手动精调才能达到比较好的效果。其中类别不平衡问题很可能就来自于BCELoss推导公式中的高阶项。在pos和neg两边label数量本不均衡的情况下,加入高阶项会加剧这种类别不平衡的现象(展开后neg总项数»pos总项数),苏神推导的(1)式直接将高阶项去掉,只保留简单的一阶项,最大程度地减缓了不平衡问题带来的影响,避免了不必要的人工精调的人力成本投入。其实可以将(1)式看作“修正后的sigmoid+交叉熵”,针对训练loss中类别不平衡问题进行的修正。

总结

本文是对多标签分类任务优化的不完全总结,对多标签分类的本质相对之前有了一些更深刻的认识,也找到了一个“临时解决方案”,可以在今后再遇到多标签分类任务的时候多一条路可以尝试。关于该方法的实际效果,苏神在博文中也放了测试结果,可以媲美精调下的二分类。 值得进一步思考的是,对于多标签分类任务,是否有更好的方式?