前沿重器[32] | 域外意图检测——解决“没见过”的问题

前沿重器

栏目主要给大家分享各种大厂、顶会的论文和分享,从中抽取关键精华的部分和大家分享,和大家一起把握前沿技术。具体介绍:仓颉专项:飞机大炮我都会,利器心法我还有。(算起来,专项启动已经是20年的事了!)

2022年的文章合集,累积起来有60w字,在这:CS的陋室60w字原创算法经验分享-2022版

往期回顾

做开放域意图识别的时候,总会遇到这样的一个问题,模型总会遇到“没见过”的样本,这个样本的分类就非常不可控,可能直接根据一些关键词就被迷惑直接大概率就分到某些类目上了,也可能一脸懵,直接停留在阈值上下摇摆不定,毕竟在开放域场景,我们很难预料到用户会说什么很新的东西,而样本层面,我们也很难覆盖更多的所有情况,最近发现一个领域,似乎是专门研究这个问题的,叫“out-of-Scope intent detection”,中文就叫域外意图检测吧,当然也有叫OOD(out of domain)的,这个就更像是“拒识”,即“识别目前系统未覆盖的功能”的这么一个功能。

虽然不能算太过前沿的东西,但是对于大家来说相对比较冷门,我看起来也比较新鲜,所以还是放在前沿重器吧。

开始之前叠个甲,这块我还是刚开始看,只是看了一些被大家提的比较多和比较新的论文和论文的思想,文献调研这块深度我自己认为还有很大空间,这里如果有什么理解错误的,有劳各位前辈指出。

什么是域外意图检测

其实可以理解文本分类里面的一种比较特殊的问题。

一般的意图识别其实会抽象成一个文本分类的问题来实现,一般情况是把意图内的样本作为正类,例如要做天气的意图识别,那就是把天气相关的句子作为正类,例如“今天天气如何”、“北京的天气”,而其他的类目都会算作负类,如“周杰伦最近有什么新歌”、“深度学习入门”等,然后把他当做一个二分类问题做就好了。

对大部分意图,我们其实都能比较完整的梳理出正类的情况,能覆盖绝大多数的情况,然而负类,就是一个无底洞,即无法把“不是天气意图”的句子都梳理出来作为负样本,这就跟我前面简介里提到的一样,模型很可能不认识、没见过,从而出现误判,而且极端的,负样本手机的太多,样本的比例会非常不平衡。所谓的域外,就是这个意思,从某个程度上说,一般的文本分类是旨在把两个类目区分开,而域外意图识别更像是在做一个拒绝,聚焦负类,把“不是正类”的找出来。思想先说,大家可能不是很理解,等我后面列举一些方案大家可能就会比较明白了。

域外检测的主要思想

所谓的分类,以二分类为例,有一个这样的理解,给定了两个类目,训练出一个分类器,把数据映射到一个空间,能通过一条线把他们给区分开,如果样本落在线的一侧,则认为是正类,另一侧则是负类,简单到线性分类器、SVM之类的,复杂到各种深度学习,其实都离不开这个逻辑。而所谓的域外检测,大家可以理解为,把正类样本尽可能映射到一个封闭的空间内,例如一个圈内,此时,处于这个圈内的就是正类,圈外的就是负类,此时圈外的内容不管来的是什么,模型见没见过都关系不大,因为圈内的模型是见过的,而且比较稳定。

换个角度,一个门禁,是不需要见过这个世界所有的人才能做门禁的,只需要记住准入的人,并在遇到准入名单内的人时放行,其他情况拒绝即可。

所以我们所需要关注的,无非就是这两个点:

  • 尽可能拿到覆盖面广且明确的样本,尤其是正样本,甚至有些这个领域的数据集已经直接干掉负样本,只给正样本了。

  • 有一个高效的表征和分类方案。

现在的研究其实不外乎就是这两个方向,而前者其实更倾向于业务和一些数据增强操作,发论文不是那么容易放的上台面,所以现在绝大部分论文,其实就在研究后者。

域外检测的常见方法

样本空间的度量

首先,最想聊的是最近发布的这篇论文(KNN-Contrastive Learning for Out-of-Domain Intent Classification),这是一篇带有邱锡鹏老师民资的工作,我自己的感觉是能够比较好诠释域外意图检测核心思路的文章。

ff895d3c63146584142b974d96a1607e.jpeg

因为域外意图(也就是我前面说的负类)是非常开放的,我们把他们强行融成一个团或者划分一个区域,非常不现实,相反,我们应该用类似KNN的手段,只要落到正类比较密集的区域内,那就更可能是正类,否则是负类,这种情况,才更加符合域外意图的空间实际分布。

说起来可能有点吹,其实和自己之前一直推行的以搜代分方案(心法利器[26] | 以搜代分:文本多分类新思路)其实有些类似,其实就是K=1的特殊情况,当然也可以说这里一定程度上借鉴了few-shot的思路,从few-shot角度看,其实就是基于度量的一种方式,因为正类的样本少(相比负类,或者说相比常规的分类任务),所以可以距离的方式来做,如果给定样本和足够多的正类足够近,此时就可以比较安全地认为他是正类了。

当然这篇文章的贡献不止于此,在进行训练的过程除了使用对比学习常用的NT-Xent,还用了ArcFace相似的加入margin的损失函数,后者的话做CV度量学习的朋友应该比较熟悉,但其实这个思想在NLP中其实也是有用的,这个我也曾经聊过,大家可以看下:前沿重器[8] | CV研究启发语义相似和表征

另外一篇文章是这篇(Enhancing the generalization for Intent Classification and Out-of-Domain Detection in SLU),这篇有意思的是他只需要正样本,他其实就是在预测阶段增加了一个DRM(domain-regularized module),如下图所示;另一方面,则是强调了距离的表示,除了使用基本的softmax的方式输出分数,还需要基于特征来进行输出,作者认为分类特征之间的维度尺寸可能存在不同,因此还要结合马氏距离,实验证明了马氏距离能有效把IND和OOD的空间给拉开的更加明显。

1439220d007484c714ecc283718a9da9.jpeg

对抗和扰动的思路

说白了就是对抗学习,简单的可以通过样本层面的增强挖掘对抗样本,复杂的可以通过embedding层面的增强,甚至是训练策略上的对抗来实现,让正类的空间更加内聚稳定,此时域外检测就会更加精准。

这篇论文(GOLD: Improving Out-of-Scope Detection in Dialogues using Data Augmentation)就是通过增强样本模型强化对OOD数据的识别,一种是用OOD样本在无标签样本中召回与之最接近的几个作为OOD数据,另一种是通过对话中的同话题多轮数据中挖掘,当然了,这种方案其实对标注数据的数量和质量都是有一定要求的。

另一种就是采用对抗学习的方式(Modeling Discriminative Representations for Out-of-Domain Detection with Supervised Contrastive Learning),直接看图就能大概明白了,说白了就是通过对抗,压缩正类的空间提升正类空间的密度和准度。

8eb7ea0fea4040b395a0065b3db79e20.jpeg

小结

简单总结一下吧,所谓的域外意图识别,其实就是做拒识,在搜索、对话场景,其实就是把为覆盖、无法解决的问题给拒绝掉的一个问题,这个问题的特点就是需要被拒识的这方面数据在样本层面无法全覆盖,看完上面的思路,包括一些空间图,其实大家能够大概明确这里面的一些思想:

  • 空间层面,把正类转化为一个样本层面的封闭空间,而把负类放在这个空间之外。只有命中这个空间以内,才能认为是正类。

  • 强调表征的重要性,一方面是通过数据样本、embedding交叉还是训练策略的对抗和增强,来让表征朝着更有利于空间划分的方向走,另一方面通过特定距离的计算,来把两类或者多类样本空间尽可能分离。

当然了,这个领域虽然已经在不少顶会里面出现(ACL、EMNLP等),但个人认为其实问题还不是很成熟,不成熟的点在于问题、数据等还没完全明确,各个论文虽然论题类似,但是数据评测层面还没有完全拉通,没拉通意味着这些方法暂未完全意义上的有对比,此阶段更像是大家在“提想法”而并非“深挖问题”,当然了截至现在已经有研究提到了这点问题并尝试迈出这步(Fine-Tuning Deteriorates General Textual Out-of-Distribution Detection by Distorting Task-Agnostic Features),但这个是否能获得广泛认可,拭目以待吧。

说实话,我自己看到这个新问题的时候是比较兴奋的,自己做了意图识别其实也有好几年了,但这个痛点似乎一直没有很好的解决,没想到其实已经有不少研究了,后续我可能还会挖掘一些完整、可靠的方案思路分享给大家,敬请期待。

更多文章

另外这里也摆几篇比较有用可供参考的拓展阅读文章:

  • KNN-Contrastive Learning for Out-of-Domain Intent Classification

    • https://zhuanlan.zhihu.com/p/419179272:这篇文章其中一段解读了这篇论文。

    • https://zhuanlan.zhihu.com/p/587961297:同上

  • Enhancing the generalization for Intent Classification and Out-of-Domain Detection in SLU

  • GOLD: Improving Out-of-Scope Detection in Dialogues using Data Augmentation

  • Modeling Discriminative Representations for Out-of-Domain Detection with Supervised Contrastive Learning

  • Fine-Tuning Deteriorates General Textual Out-of-Distribution Detection by Distorting Task-Agnostic Features

    • 论文解读:https://it.sohu.com/a/636870414_121119001

  • 论文笔记 - 对话系统中的 OOD 问题:https://zhuanlan.zhihu.com/p/435989760

946b70b83c7791c697cd631b9f46038d.png

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在拖拽的过程中,我们经常会遇到快速拖拽的问题,也就是鼠标移动速度太快,导致拖拽元素跟不上鼠标的移动速度,造成拖拽效果的不流畅。解决这个问题的方法有很多种,下面介绍两种常见的方法。 #### 方法一:使用 requestAnimationFrame requestAnimationFrame 是一个浏览器提供的 API,它可以让浏览器在下一次重绘之前执行指定的函数,这样可以保证函数执行的频率跟浏览器的重绘频率一致,避免了浏览器过度绘制和卡顿的问题。我们可以利用 requestAnimationFrame 来优化拖拽的效果。 具体实现方法如下: ```javascript let startX, startY, currentX, currentY; let element = document.getElementById('drag'); element.addEventListener('mousedown', function (event) { startX = event.clientX; startY = event.clientY; document.addEventListener('mousemove', onMouseMove); document.addEventListener('mouseup', onMouseUp); }); function onMouseMove(event) { currentX = event.clientX - startX; currentY = event.clientY - startY; requestAnimationFrame(updatePosition); } function updatePosition() { element.style.transform = `translate(${currentX}px, ${currentY}px)`; } function onMouseUp() { document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); requestAnimationFrame(() => { element.style.transform = `translate(${currentX}px, ${currentY}px)`; currentX = 0; currentY = 0; }); } ``` 在 onMouseMove 函数中,我们使用 requestAnimationFrame 来更新元素的位置,这样可以保证元素的位置更新频率跟浏览器的重绘频率一致,从而避免了拖拽效果的不流畅问题。在 onMouseUp 函数中,我们也使用 requestAnimationFrame 来更新元素的位置,并且将 currentX 和 currentY 重置为 0,这样可以避免多次拖拽时元素位置的累加。 #### 方法二:使用 CSS3 动画 除了使用 requestAnimationFrame,我们还可以使用 CSS3 动画来优化拖拽效果。具体实现方法如下: ```javascript let startX, startY, currentX, currentY; let element = document.getElementById('drag'); element.addEventListener('mousedown', function (event) { startX = event.clientX; startY = event.clientY; document.addEventListener('mousemove', onMouseMove); document.addEventListener('mouseup', onMouseUp); }); function onMouseMove(event) { currentX = event.clientX - startX; currentY = event.clientY - startY; element.style.transform = `translate(${currentX}px, ${currentY}px)`; } function onMouseUp() { document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); element.style.transition = 'transform 0.2s ease-out'; element.style.transform = `translate(${currentX}px, ${currentY}px)`; setTimeout(() => { element.style.transition = ''; currentX = 0; currentY = 0; element.style.transform = ''; }, 200); } ``` 在 onMouseUp 函数中,我们首先给元素添加了一个过渡动画,这样可以让拖拽效果更加流畅。然后使用 setTimeout 函数来清除过渡动画,并将 currentX 和 currentY 重置为 0,最后将元素的 transform 属性重置为空。这样可以让元素回到原来的位置,同时避免了多次拖拽时元素位置的累加。 需要注意的是,这种方法需要我们手动设置过渡动画的时间,并且需要等待过渡动画执行完毕之后才能重置元素的位置,因此需要在 setTimeout 函数中设置一个适当的等待时间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值