分类问题后处理技巧CAN,近乎零成本获取效果提升

760f209dd541197983424e0f7d7b00fe.png

文 | 苏剑林
编 | 智商掉了一地
单位 | 追一科技

思想朴素却不平凡的分类问题后处理技巧,浅显易懂的讲解,拿来吧你!

顾名思义,本文将会介绍一种用于分类问题的后处理技巧——CAN(Classification with Alternating Normalization)。经过笔者的实测,CAN确实多数情况下能提升多分类问题的效果,而且几乎没有增加预测成本,因为它仅仅是对预测结果的简单重新归一化操作。

有趣的是,其实CAN的思想是非常朴素的,朴素到每个人在生活中都应该用过同样的思想。然而,CAN的论文却没有很好地说清楚这个思想,只是纯粹形式化地介绍和实验这个方法。本文的分享中,将会尽量将算法思想介绍清楚。

论文标题:
When in Doubt: Improving Classification Performance with Alternating Normalization

论文链接:
https://arxiv.org/abs/2109.13449

c1a434586113de3a23e963aac8613e34.png思想例子8ef9085662d277ded8dbafc416e023a4.png

假设有一个二分类问题,模型对于输入给出的预测结果是,那么我们就可以给出预测类别为;接下来,对于输入,模型给出的预测结果是,这时候处于最不确定的状态,我们也不知道输出哪个类别好。

但是,假如我告诉你:

  1. 类别必然是0或1其中之一;

  2. 两个类别的出现概率各为0.5。

在这两点先验信息之下,由于前一个样本预测结果为1,那么基于朴素的均匀思想,我们是否更倾向于将后一个样本预测为0,以得到一个满足第二点先验的预测结果?

这样的例子还有很多,比如做10道选择题,前9道你都比较有信心,第10题完全不会只能瞎蒙,然后你一看发现前9题选A、B、C的都有就是没有一个选D的,那么第10题在蒙的时候你会不会更倾向于选D?

这些简单例子的背后,有着跟CAN同样的思想,它其实就是用先验分布来校正低置信度的预测结果,使得新的预测结果的分布更接近先验分布。

2 不确定性

准确来说,CAN是针对低置信度预测结果的后处理手段,所以我们首先要有一个衡量预测结果不确定性的指标。常见的度量是“熵”[1],对于,定义为:

然而,虽然熵是一个常见选择,但其实它得出的结果并不总是符合我们的直观理解。比如对于和,直接套用公式得到,但就我们的分类场景而言,显然我们会认为比更不确定,所以直接用熵还不够合理。

一个简单的修正是只用前top-个概率值来算熵,不失一般性,假设是概率最高的个值,那么

其中。为了得到一个0~1范围内的结果,我们取为最终的不确定性指标。

683f091e9d1943d716f014514096b60b.png算法步骤954a6b23cbea2ee2182dbfd9d208b774.png

现在假设我们有个样本需要预测类别,模型直接的预测结果是个概率分布,假设测试样本和训练样本是同分布的,那么完美的预测结果应该有:

其中是类别的先验分布,我们可以直接从训练集估计。也就是说,全体预测结果应该跟先验分布是一致的,但受限于模型性能等原因,实际的预测结果可能明显偏离上式,这时候我们就可以人为修正这部分。

具体来说,我们选定一个阈值,将指标小于的预测结果视为高置信度的,而大于等于的则是低置信度的,不失一般性,我们假设前个结果属于高置信度的,而剩下的个属于低置信度的。我们认为高置信度部分是更加可靠的,所以它们不用修正,并且可以用它们来作为“标准参考系”来修正低置信度部分。

具体来说,对于,我们将与高置信度的一起,执行一次 “行间标准化

这里的,其中乘除法都是element-wise的。不难发现,这个标准化的目的是使得所有新的的平均向量等于先验分布,也就是促使式(3)的成立。然而,这样标准化之后,每个就未必满足归一化了,所以我们还要执行一次 行内标准化

理论上,这两步可以交替迭代几次(不过实验结果显示一次的效果就挺好了)。最后,我们只保留最新的作为原来第个样本的预测结果,其余的均弃之不用。

注意,这个过程需要我们遍历每个低置信度结果执行,也就是说是逐个样本进行修正,而不是一次性修正的,每个都借助原始的高置信度结果组合来按照上述步骤迭代,虽然迭代过程中对应的都会随之更新,但那只是临时结果,最后都是弃之不用的,每次修正都是用原始的。

b1324e71ee902fcb5006e917c26804c9.png参考实现993fa65149521d923ddabc6db4126151.png

这是笔者给出的参考实现代码:

# 预测结果,计算修正前准确率
y_pred = model.predict(valid_generator.fortest(), steps=len(valid_generator), verbose=True
)
y_true = np.array([d[1] for d in valid_data])
acc_original = np.mean([y_pred.argmax(1) == y_true])
print('original acc: %s' % acc_original)# 评价每个预测结果的不确定性
k = 3
y_pred_topk = np.sort(y_pred, axis=1)[:, -k:]
y_pred_topk /= y_pred_topk.sum(axis=1, keepdims=True)
y_pred_uncertainty = -(y_pred_topk * np.log(y_pred_topk)).sum(1) / np.log(k)# 选择阈值,划分高、低置信度两部分
threshold = 0.9
y_pred_confident = y_pred[y_pred_uncertainty < threshold]
y_pred_unconfident = y_pred[y_pred_uncertainty >= threshold]
y_true_confident = y_true[y_pred_uncertainty < threshold]
y_true_unconfident = y_true[y_pred_uncertainty >= threshold]# 显示两部分各自的准确率
# 一般而言,高置信度集准确率会远高于低置信度的
acc_confident = (y_pred_confident.argmax(1) == y_true_confident).mean()
acc_unconfident = (y_pred_unconfident.argmax(1) == y_true_unconfident).mean()
print('confident acc: %s' % acc_confident)
print('unconfident acc: %s' % acc_unconfident)# 从训练集统计先验分布
prior = np.zeros(num_classes)
for d in train_data:prior[d[1]] += 1.prior /= prior.sum()# 逐个修改低置信度样本,并重新评价准确率
right, alpha, iters = 0, 1, 1
for i, y in enumerate(y_pred_unconfident):Y = np.concatenate([y_pred_confident, y[None]], axis=0)for j in range(iters):Y = Y**alphaY /= Y.sum(axis=0, keepdims=True)Y *= prior[None]Y /= Y.sum(axis=1, keepdims=True)y = Y[-1]if y.argmax() == y_true_unconfident[i]:right += 1# 输出修正后的准确率
acc_final = (acc_confident * len(y_pred_confident) + right) / len(y_pred)
print('new unconfident acc: %s' % (right / (i + 1.)))
print('final acc: %s' % acc_final)

1882f17abceb708621b5d48fcca0129f.png实验结果ab8d7b20d5c21f08af716484774452ca.png

那么,这样的简单后处理,究竟能带来多大的提升呢?原论文给出的实验结果是相当可观的:

4303cd377443e2ac99430e90301ca78e.png
▲原论文的实验结果之一

笔者也在CLUE上的两个中文文本分类任务上做了实验,显示基本也有点提升,但没那么可观(验证集结果):


IFLYTEK(类别数:119)TNEWS(类别数:15)
BERT60.06%56.80%
BERT + CAN60.52%56.86%
RoBERTa60.64%58.06%
RoBERTa + CAN60.95%58.00%

大体上来说,类别数目越多,效果提升越明显,如果类别数目比较少,那么可能提升比较微弱甚至会下降(当然就算下降也是微弱的),所以这算是一个“几乎免费的午餐”了。超参数选择方面,上面给出的中文结果,只迭代了1次,的选择为3、的选择为0.9,经过简单的调试,发现这基本上已经是比较优的参数组合了。

还有的读者可能想问前面说的“高置信度那部分结果更可靠”这个情况是否真的成立?至少在笔者的两个中文实验上它是明显成立的,比如IFLYTEK任务,筛选出来的高置信度集准确率为0.63+,而低置信度集的准确率只有0.22+;TNEWS任务类似,高置信度集准确率为0.58+,而低置信度集的准确率只有0.23+。

55d44196e8908e25a9d06ddee6410b37.png个人评价a9d5301509b34d0d6319450e55dc4592.png

最后再来综合地思考和评价一下CAN。

首先,一个很自然的疑问是为什么不直接将所有低置信度结果跟高置信度结果拼在一起进行修正,而是要逐个进行修正?笔者不知道原论文作者有没有对比过,但笔者确实实验过这个想法,结果是批量修正有时跟逐个修正持平,但有时也会下降。其实也可以理解,CAN本意应该是借助先验分布,结合高置信度结果来修正低置信度的,在这个过程中,如果掺入越多的低置信度结果,那么最终的偏差可能就越大,因此理论上逐个修正会比批量修正更为可靠。

说到原论文,读过CAN论文的读者,应该能发现本文介绍与CAN原论文大致有三点不同:

  1. 不确定性指标的计算方法不同。按照原论文的描述,它最终的不确定性指标计算方式应该是

也就是说,它也是top-个概率算熵的形式,但是它没有对这个概率值重新归一化,并且它将其压缩到0~1之间的因子是而不是(因为它没有重新归一化,所以只有除才能保证0~1之间)。经过笔者测试,原论文的这种方式计算出来的结果通常明显小于1,这不利于我们对阈值的感知和调试。

  1. 对CAN的介绍方式不同。原论文是纯粹数学化、矩阵化地陈述CAN的算法步骤,而且没有介绍算法的思想来源,这对理解CAN是相当不友好的。如果读者没有自行深入思考算法原理,是很难理解为什么这样的后处理手段就能提升分类效果的,而在彻底弄懂之后则会有一种故弄玄虚之感。

  2. CAN的算法流程略有不同。原论文在迭代过程中还引入了参数,使得式(4)变为

也就是对每个结果进行次方后再迭代。当然,原论文也没有对此进行解释,而在笔者看来,该参数纯粹是为了调参而引入的(参数多了,总能把效果调到有所提升),没有太多实际意义。而且笔者自己在实验中发现,基本已经是最优选择了,精调也很难获得是实质收益。

4bf2b9af82feea98086ce998bbc132f2.png文章小结2f0bf1ac1519cff17f2645d886e92c76.png

本文介绍了一种名为CAN的简单后处理技巧,它借助先验分布来将预测结果重新归一化,几乎没有增加多少计算成本就能提高分类性能。经过笔者的实验,CAN确实能给分类效果带来一定提升,并且通常来说类别数越多,效果越明显

61b293895a797e9a3f3eab714ebe714f.png后台回复关键词【入群

加入卖萌屋NLP/IR/Rec与求职讨论群

后台回复关键词【顶会

获取ACL、CIKM等各大顶会论文集!

fcee20fae2b9ed7cf06bf33655effa79.gif 637d6594c533b751681f1f6b1a75a30c.png

[1]  苏剑林. (Dec. 1, 2015). 《“熵”不起:从熵、最大熵原理到最大熵模型(一)》[Blog post]. Retrieved from https://kexue.fm/archives/3534

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/477936.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 840. 矩阵中的幻方(数学)

1. 题目 3 x 3 的幻方是一个填充有从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&#xff1f;&#xff08;每个子矩阵都是连续的&…

Docker系列之一:入门介绍

Docker简介 Docker是DotCloud开源的、可以将任何应用包装在Linux container中运行的工具。2013年3月发布首个版本&#xff0c;当前最新版本为1.3。Docker基于Go语言开发&#xff0c;代码托管在Github上&#xff0c;目前超过10000次commit。基于Docker的沙箱环境可以实现轻型隔离…

论文浅尝 | 动态知识图谱对齐

论文笔记整理&#xff1a;谭亦鸣&#xff0c;东南大学博士生来源&#xff1a;AAAI‘21链接&#xff1a;https://ojs.aaai.org/index.php/AAAI/article/view/16585概述本文提出了一种动态图谱(KG)对齐方法&#xff0c;在“动态”&#xff08;即图谱可能随时间更新&#xff09;的…

你的 GNN,可能 99% 的参数都是冗余的

文 | iven自从图卷积神经网络&#xff08;GCN&#xff09;面世以来&#xff0c;图神经网络&#xff08;GNN&#xff09;的热潮一瞬间席卷 NLP。似乎在一切 NLP 任务上&#xff0c;引入一个图结构&#xff0c;引入一个 GNN&#xff0c;就能让模型拥有推理能力。更重要的是&#…

LeetCode 874. 模拟行走机器人(set)

1. 题目 机器人在一个无限大小的网格上行走&#xff0c;从点 (0, 0) 处开始出发&#xff0c;面向北方。该机器人可以接收以下三种类型的命令&#xff1a; -2&#xff1a;向左转 90 度-1&#xff1a;向右转 90 度1 < x < 9&#xff1a;向前移动 x 个单位长度 在网格上有…

高级语言的编译:链接及装载过程介绍

引言 随着越来越多功能强大的高级语言的出现&#xff0c;在服务器计算能力不是瓶颈的条件下&#xff0c;很多同学会选择开发效率高&#xff0c;功能强大的虚拟机支持的高级语言&#xff08;Java&#xff09;&#xff0c;或者脚本语言&#xff08;Python&#xff0c;Php&#xf…

图谱实战 | 基于半结构化百科的电影KG构建、查询与推理实践记录

转载公众号 | 老刘说NLP本文围绕基于半结构化百科的电影知识图谱构建、查询与推理实践这一主题&#xff0c;完成基于百度百科的电影元组抽取、基于protg的电影本体构建、基于D2RQ的RDF数据转换与查询、基于Apache jena的电影知识推理四个环节的实践。这是半结构化知识图谱构建和…

推荐系统精排:看阿里妈妈再试线性模型

文 | 水哥源 | 知乎saying1.科学总是要求我们有深度&#xff0c;但在实际业务中这却是一条悖论&#xff1a;越有深度的事情往往投入产出比不够高2.当我有一个方法A&#xff0c;还有一个方法B。且B的某种简单形式就是A的时候&#xff0c;我就会很快乐&#xff0c;因为这时候B获取…

LeetCode 686. 重复叠加字符串匹配

1.题目 给定两个字符串 A 和 B, 寻找重复叠加字符串A的最小次数&#xff0c;使得字符串B成为叠加后的字符串A的子串&#xff0c;如果不存在则返回 -1。 举个例子&#xff0c;A “abcd”&#xff0c;B “cdabcdab”。 答案为 3&#xff0c; 因为 A 重复叠加三遍后为 “abcd…

如何提升大规模Transformer的训练效果?Primer给出答案

文 | 舞风小兔编 | 智商掉了一地如何进一步提升大规模Transformer的训练效果&#xff1f;Primer给出了答案&#xff0c;一起来看看吧&#xff01;Transformer是深度学习界的明星模型。由于其具有高度的并行性&#xff0c;十分容易在并行计算系统中扩展至超大规模。自然语言处理…

会议交流|大模型与图学习等知识图谱相关技术实践探索

2021年&#xff0c;在疫情隔离和复杂国际形势的背景下&#xff0c;我们越发认识到重视核心基础技术&#xff0c;对保持国家独立自主发展的关键价值&#xff0c;互联网和科技行业也面临着新的挑战和变革机遇&#xff0c;新的AI技术正发挥越来越大的作用&#xff0c;AI技术本身正…

Kafka文件存储机制那些事

Kafka是什么 Kafka是最初由Linkedin公司开发&#xff0c;是一个分布式、分区的、多副本的、多订阅者&#xff0c;基于zookeeper协调的分布式日志系统(也可以当做MQ系统)&#xff0c;常见可以用于web/nginx日志、访问日志&#xff0c;消息服务等等&#xff0c;Linkedin于2010年贡…

LeetCode 392. 判断子序列(双指针二分查找)

1. 题目 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长&#xff08;长度 ~ 500,000&#xff09;&#xff0c;而 s 是个短字符串&#xff08;长度 <100&#xff09;。 字符串的一个子序列是原始…

仅仅因为方法 Too Simple 就被拒稿,合理吗?

文 | 小戏编 | 小轶如果你看到自己实验行之有效的论文被退稿&#xff0c;而收到的退稿理由仅仅是“方法太简单”&#xff0c;你会怎么想&#xff1f;这两天在推特上&#xff0c;佐治亚理工的 Riedl 教授吐槽了自己收到的 AAAI phase 1 退稿理由居然是因为“这方法似乎太简单”&…

论文浅尝 | 从具有数值边缘属性的知识图谱中学习嵌入

论文笔记整理&#xff1a;朱珈徵&#xff0c;天津大学硕士链接&#xff1a;https://www.ijcai.org/proceedings/2021/0395.pdf动机从遗传数据到社会网络&#xff0c;在越来越多的场景下与知识图谱边缘相关的数值已经被用来表示不确定性、边的重要性&#xff0c;甚至是带外知识。…

美团 P2P 图书馆实践:5天时间1845册图书共享入库

我们在2014年的最后一周上线了美团图书馆。在开始介绍这个项目之前&#xff0c;先和大家说明几个数字和一段对话截屏。 ![](https://awps-assets.meituan.net/mit-x/blog-images-bundle-2015/7398069d.jpg)每周读一本&#xff0c;读完这些书需要45年 ![](https://awps-assets.m…

LeetCode 459. 重复的子字符串(数学)

1. 题目 给定一个非空的字符串&#xff0c;判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母&#xff0c;并且长度不超过10000。 示例 1: 输入: "abab" 输出: True 解释: 可由子字符串 "ab" 重复两次构成。示例 2: 输入: &quo…

被放养导致申博论文难产,该不该硬gang导师?

最近一位粉丝给我发长文求助&#xff0c;说他因为申博论文的事情快崩溃了&#xff0c;让我给点建议。我把经过贴在这里跟大家探讨一下&#xff1a;985专硕一枚&#xff0c;CV方向&#xff0c;最近想申请国外博士&#xff0c;快被论文逼疯了。提交了初稿&#xff0c;隔了一个月&…

会议交流 | 第十五届全国知识图谱与语义计算大会(CCKS 2021)12月25日线上召开...

勘误&#xff1a;张伟老师为华东师范大学紫江青年学者OpenKGOpenKG&#xff08;中文开放知识图谱&#xff09;旨在推动以中文为核心的知识图谱数据的开放、互联及众包&#xff0c;并促进知识图谱算法、工具及平台的开源开放。点击阅读原文&#xff0c;进入 CCKS 2021 网站。

美团性能分析框架和性能监控平台

以下是我在 Velocity China 2014 做的题为“美团性能分析框架和性能监控平台”演讲的主要内容&#xff0c;现在以图文的形式分享给大家。 今天讲什么&#xff1f; 性能的重要性不言而喻&#xff0c;需要申明的是&#xff0c;我们今天不讲业界最佳性能实践&#xff0c;这些实践已…