前面两篇分别介绍了制作多标签数据,resnet多标签分类。接下来,我将介绍多标签分类的指标并分享一些关于多标签分类的细节,即如何操作可以提点。
在此之前,想提一下损失函数cross_entropy与binary_cross_entropy的区别 交叉熵的数学公式如上所示,P表示target,Q表示prediction,H就是交叉熵损失。在pytorch中可以调用 F.cross_entropy(input, target)来实现交叉熵损失的计算。其实分解一下就是下面的公式,先把prediction按照最后的dim求softmax,然后再求它们的log,最后,分别乘上对应的target就ok了。
loss = -label * F.log_softmax(pred, dim=-1)
binary_cross_entropy与cross_entropy最大的区别在于binary_cross_entropy没有采用softmax,而是使用了sigmoid来归一化prediction。在多标签分类中,这一点很重要,因为softmax.sum()=1,多标签中,一个图片存在多个属性,所以softmax.sum()=1的假设是不成立的。因此,多标签分类中会使用F.binary_cross_entropy_with_logits。
多标签分类评价指标
precision_class = tp.sum(axis=0) / np.maximum(tp.sum(axis=0) + fp.sum(axis=0), eps)
recall_class = tp.sum(axis=0) / np.maximum(tp.sum(axis=0) + fn.sum(axis=0), eps)
CP = precision_class.mean() * 100.0
CR = recall_class.mean() * 100.0
CF1 = 2 * CP * CR / np.maximum(CP + CR, eps)
OP = tp.sum() / np.maximum(tp.sum() + fp.sum(), eps) * 100.0
OR = tp.sum() / np.maximum(tp.sum() + fn.sum(), eps) * 100.0
OF1 = 2 * OP * OR / np.maximum(OP + OR, eps)
多标签分类的评价指标比较简单,一般我比较关注CP,CR,即平均准确率与召回率。在求CP,CR时,需要设置阈值thr(一般设置thr=0.5),tp是指预测值大于thr的正样本,fp指预测值大于thr的负样本,fn指预测值小于thr的正样本。准确率precision=tp/(tp+fp),召回率=tp/(tp+fn)。
多标签分类tips 相信大家在做项目时都会遇到数据量不足,数据样本分布不均等问题。下面我结合自己的经验给大家提供一些tips 1.数据量有限时(train数据少于1w张时),小模型的效果会由于大模型(过拟合)。 2.使用ClassBalancedDataset,对样本少的类别重复采样,可以有效提高召回。 3.loss,我试验过focal loss,asymmetric loss,效果很差(召回很高,但是准确率低得离谱)。focal与 asymmetric loss都是为了降低负样本在loss的占比,从而平衡正负样本。asymmetric将gamma分为gamma+与gamma-,相较于focal loss中gamma=2来说,asymmetric更加夸张的降低了负样本的loss(因为我的数据类别分布极不均匀,在实验中,正样本loss大概是负样本loss的几十倍甚至几百倍),这就导致模型极度聚焦于正样本,模型只知道什么是正确的,对错误的并不care,因此recall提高了,precision却低的离谱。focal loss也存在这样的问题,但是alpha可以稍微缓解这样的情况。 4.魔改模型结构,注意力机制,dropout,框架等等各种,大家可以试试。
|