查看原文
其他

如何解构建有人情味的AI应用?如何去定义客观的情感类别?AI教你如何提供情绪价值!《追AI的人》第15期直播回放


💜 多样例学习定义介绍💜 多样例学习研究现状💜 对话质量分析中的应用💜 冒犯语言检测中的应用

《追AI的人》系列直播第15期——AAIG自然语言理解实验室EMNLP专场,分享了《机器=冰冷?看机器如何捕捉你的小情绪》和《文本如药,如何精确提炼“有效成分”?》。


以下为直播的文字回放,分为上下两篇,本文为下篇,共9684计字。


上篇回顾:文本如药?如何通过多样例学习判断有效成分?如何识别辱骂文本?对话质量分析应用场景?AAIG自然语言理解实验室EMNLP专场(上)
宋 晓 辉
中科院信工所在读博士生,阿里安全智能算法实习小二,主要研究方向为人机对话系统。

框架要点



一、对话情感分析问题的介绍
二、基于有监督原型对比学习的对话情感分析 EMNLP 2022
三、对话情感分析的一些展望




先来看一个生活的例子👇

例子:妈妈做了非常丰盛的午饭,叫你来吃饭。但是这个时候你正在打游戏,妈妈很开心地叫你说:“儿子吃饭了!”然后你说:“好,来啦!”但是你并没有停下手里的手机,5分钟后,妈妈又来催促:“快来吃饭了!”这个时候你还是没有听出来有什么不对,敷衍说:“马上玩完这把!”再过了5分钟后,妈妈又问你玩完了没有,你这边可能忙着上高地,就说“还没有,马上!”再过5分钟后,妈妈就开始生气了,就问你还吃不吃,这个时候你可能就有点害怕了,然后就抱着手机然后说来了来了来了。

这个过程是对话情感分析非常好的例子,我们的目标就是在这样的一个对话场景下,为妈妈和你分析出,每一句每个人表达出来的情绪是怎么样的,情绪的类别在每个任务或者说数据集都是预先设定好的。

这个例子也可以看出来这个任务和一般的文本分类的任务有区别。妈妈的前面的这两句话,做一下对调,比如妈妈先说快来吃饭了,那么我们也可以想象肯定还是第一句话是相对来说更加愉快的。

这就是这个任务的一个特点:它的文本和情感类别之间的关联没有像文本分类的那么强,也就是说一句话它表达什么样的情感,不仅仅取决于它的文本内容,更加取决于他在对话中所处的位置或者说所处的上下文。以上我们了解了对话情感分析任务的定义。

对话情感分析应用


1、现在有很多在线服务比如在线教育,医生的在线问诊,还有大量的人工智能客服之类的系统,在服务过程中,我们需要对客户的不良情绪进行监测,以便尽早地进行人工的介入,同时也对这些服务小二、医生的服务态度进行检测,也是服务质量控制的关键问题。

2、在人机交互系统里面去考虑用户的情感因素,来构建一个更加有人情味的人工智能应用。比如聊天机器人,或者现在大火的数字人之类的,引入用户的情感因素,可以让用户体验更加顺滑。现在大家家里面可能会有一些小爱同学、天猫精灵之类的产品,它们就已经能够一定程度上理解语言里面的情绪。比如你如果大声地指责它或者骂它,它会给相应的回复,而不是完全忽略掉你的情感。如此,就会让你和智能机器人的沟通更加的流畅。

3、对话情感分析是在一定上下文之下去学习一些句子的情感,那么它可以用在线社交网络的一些有评论转发等交互场景的情绪分析,此外立场检测之类舆论分析的领域,也可以用对话情感分析相关的技术来辅助解决。

对话情感分析的难点

1、它是上下文相关的,也就是说相同的句子它在不同的场景下会有截然不同的情感信息。


2、边界样本多,边界样本是指存在很多样本,不容易界定它的情感类别,比如说失望和伤心,开心和兴奋,这种比较细微的差别,我们人类是很容易感知的,但是如果让模型从文本的角度上去判断是比较困难的。

3、口语化,对话会产生大量的口语化的、并不是非常形式化的文本,它是客观信息含量比较低,但是情感含量信息非常丰富的文本,比如我们现在发两哈字,表示这个人一定不是真的笑了,但是发一大串哈哈的话才表示他真的被逗笑了,然后“嗯”和“嗯嗯”和也表示了两种不一样的态度,然后类似的还有“哦”和“哦哦”之类的。




如何解决边界样本的问题


对已有工作进行分析,发现大多数工作使用交叉熵损失函数来做最后的分类,损失函数对边界样本可能不够敏感,交叉熵损失函数虽然被广泛的使用,但是它对于那些比较细微的差异学习的不够淋漓尽致。我们想尝试把有监督对比学习损失函数应用到这个领域里来,但是如果直接把损失函数进行替换,会有两个问题:

01

现有的对话情感分析的数据集,大多数是类别不均衡的。很容易理解,因为我们日常沟通,可能大多数的情况下是没有情感的,有情感的时候是少数,所以自然造成了这个问题天然是一个类别不均衡的现象,这样就导致了小类别的样本。


例如“暴怒”这种情感,情感出现频率比较低,在我们训练过程中,它在一小批次里边很可能见不到自己的同类,在对比学习的场景下,它学习到的表征可能就会较差。


02

部分的数据文本信息含量太低了,称为极端样本,这个是怎么造成的?比如前面提到的我们本领域的几个主流的数据集是在老友记的剧本之上构造的。老友记本身是一个情景剧,那么它在构造数据集的时候是保留了它的音频,视频,还有它的文本。


但是我们是针对文本领域做的研究,没有音频和文本的信息,就会导致部分样本它的情绪在文本上体现的不够充分,一个单独的hello或者hi或者ok这种样本,去预测他的情绪是非常困难的,所以这样就造成一些极端样本,它们对对比学习模型的性能是有负面影响的。

我们具体怎么做的?


针对第一个类别不均衡的问题,我们就提出了一个新的损失函数,这个损失函数是在有监督对比学习的基础之上,我们引入了一个叫原型网络的技术,然后提出了一个新的损失函数,叫有监督原型对比损失。

然后第二个是针对极端样本的问题,我们提出了使用课程学习策略来缓解极端样本的影响。课程学习的思想非常简单,它就是模仿我们人类从小到大,先学一些简单的东西,再去学一些比较困难的东西,所以它的核心是给样本排序的问题。

对比学习


有监督对比学习是在无监督的或者说自监督对比学习之上进行了场景迁移。我们首先介绍最原始的方法——对比学习,它是一个自监督表示学习的方法,如上图。单纯的对比学习它是不需要类别标签的,输入的两个图片,面包和下面的馒头,模型不需要知道它们是什么,然后它是通过数据增强的方式产生多个样本的视图。

数据增强是怎么回事呢?比如把第一个面包切成片,给它涂上了奶油,但这个时候它还是面包,所以没有改变它本身的性质。第二片给它撒上了葱花,但它依然是面包,所以也没有改变它的性质。所以从这一大坨面包变成这两份面包之后,它们依然都是面包。馒头同理,分一半把它蒸成小南瓜,然后再分一半把它蒸成小鸡仔,这两个也都是馒头。

然后送到这个模型之后,虽然模型此时不知道这些东西它们本身是什么,但是它们知道上面这两个东西是从同一个东西上演化过来的,下面这两个东西是从同一个东西上演化过来的,它们有同源关系。有同源关系之后就可以进行对比学习的训练,把他们分别送同时送到模型里之后,蓝色的箭头表示同源,它们之间相互拉近,非同源的样本给它们相互排斥。


对比学习如何实现?

是用一个叫做InfoNCE的这样一个损失函数,可能这个看公式可能比较模糊,但它的思想就是很简单,就是同源的拉近非同源的相互排斥。训练完之后,模型对于这几个样本的认知就会得到一个比较好的优化的结果,它可以知道,抹上奶油的和撒上葱花的都是来自于面包,整成小南瓜的,整成小鸡仔的也都是馒头。

模型对于面包、馒头给出的表示,效果会有明显的提升,可以做一些后续的任务,比如说图片分类之类的,这是一个在 CV领域用的非常多的训练方法。这是自监督对比学习,下一步用到的是有监督对比学习,既然是有监督了,就证明样本是有标签的。样本送到模型的时候,原本就知道这是馒头,它也是馒头,这个是面包,它是馒头,下面这两个也都是面包,有这一列这个标签信息的。

那么它有什么好处呢?

这些样本送到模型里的时候,不需要再对它进行前面的数据增强的过程,我们直接就知道了它们哪些是同类样本,哪些是非同类样本,那么在训练的时候依然是同类的拉近非同类的拉远。不同的是,里面会有很多对同类或者非同类的关系,所以它会在数值计算上有一些小小的不一样的处理,所以损失函数有一点不一样,所以他就改了个名,他叫SupCon loss,不清楚没有关系,对比学习的思想,就是拉近同源排斥非同源。

有监督对比学习,它已经是能够在给定标签的情况下区分出馒头和面包它们各自是什么样的东西。对于像ERC也就是对话情感分析任务,它是一个类别不均衡的状态。在这个情况下有监督对比学习会有什么问题?


如上图:比如现在有1000个面包,10个馒头,然后我希望训练一个模型,让它去对馒头和面包进行编码,给出表示,比如后续要做馒头和面包的分类任务。

现在因为算力有限,batch size肯定要比较小一些,这里面batch size设为6,是因为这1页只能放下这6个小图,然后我们随机采一个batch之后,很可能我们就采到了5个面包1个馒头,因为我们有大量的面包,只有10个馒头,那么如果说我们更不幸地采到了6个面包,那就是更极端的情况了,我们为了给大家解释清楚,这里面我就用了一个比较普遍的分布,大类别占据一个batch的多数,小类别占据一个batch的少数。

同样的按照前一页的方式,我们把它送到对比学习的模型里边,然后就可以看到这里边这5个面包,它们彼此都知道自己是同类,它们也知道馒头和自己不是同类,所以每一个面包都知道自己该长什么样子,自己不该长什么样子,但是对于馒头来说,它就不知道别的馒头长什么样了,这样学出来的表示,在这一轮训练里边它只是在被排斥,但是它不知道该自己该去哪。


我们提出来有监督原型对比学习的思想,这个想法是来源于小样本学习领域的一个原型网络方法。原型网络的核心就是用一个类别里边少量的几个样本,就能刻画出类别里的样本大概是什么样子的。

继续回到刚才的例子,我们有5个面包1个馒头,那么因为我们有知道有一个馒头不知道自己该长成什么样了,所以在计算的时候去计算一个面包的原型和一个馒头的原型,这个原型是怎么计算出来的?比如馒头原型,就是我们在全部的10个馒头里边随机采样几个给它取了一个平均,得到了一个馒头的原型表示,这个表示可能已经不是一个长成具体馒头的样子了,已经看不出来了。

同样会去计算一个面包的原型,然后把这两个原型当成对应类别的样本,放到对比学习的训练过程中来。这样就可以看到之前见不到同类的馒头,它起码能见到自己的这一个馒头原型,虽然它没见到具体的馒头,但是可以通过这个原型看到其他的馒头大概应该长成什么样子,这样它就有了一个优化的方向,这batch里它学到的东西就不全是负面的。

有监督原型对比学习的计算过程


有监督对比损失,它原本就是我们第一个提到的自监督的对比损失对于正样本对求平均,就是对每一个样本,P是它的正样本的集合,就是那一个batch里边和自己是同类的样本的集合,a是它在batch内的补集,就是说这一个batch之内除了他自身以外,其他的样本,然后G的话是打分函数去计算两个样本的一个相似度,然后这个E是我们的一个情感类别的集合,也就是我们的标签空间。

原来的有监督对比损失就是上面是正样本,下面是负样本,它的核心的作用就是去拉近正样本之间的距离,然后疏远负样本之间的距离,将原型网络的思想引入到有监督对比的损失中,它的做法是怎么样的?具体来说,每一个类别的原型当成一个样本参与计算,就像刚才我们把面包原型和馒头原型放在我们那个圈里面,和别人去比较这样的思路。

当前的样本所在类别的原型当成正样本放在分子上,其他类别的原型当成负样本放在分母上,然后进一步原型是怎么来的,就是在训练过程中会缓存每一个类别的样本的表示。

比如说历史上我已经过了10个面包5个馒头了,我把这些10个面包5个馒头存起来,然后再计算第11个面包和第6个馒头的时候,在历史队列里面去采样1个支持集。支持集通常会比较小,比如我挑了3个面包,2个馒头出来,然后给它们求了一个平均,分别的加到上面来,然后去进行损失函数的计算。

有监督原型对比损失的计算,它能保证在任何类别不均衡的情况下,对于任意样本,在小批次内都能至少存在一个正样本和类别数减一个负样本,让这个样本在任何一轮迭代里边都不会不知道自己该向哪一个方向去优化。

有监督原型对比学习的计算过程


课程学习策略,它是一个从简单到困难的学习顺序,它就是模仿人类先上小学再上初中,再上高中再上大学的过程。也就是说对于模型来说,先去学很简单的样本,学会了一点知识之后,再去学习那些比较困难的样本。

核心的问题就是如何定义简单和困难的样本?

1、设计了难度的评估函数,前面提到了类别的原型是少数几个样本计算出来的,类别的中心就是所有样本计算出来的类别原型,那么我们就叫它类别的中心,我们用一个样本到等类别的中心的距离和该样本到所有类别中心向量距离的和的比值来作为该样本的难度。

如图,假如有5个类别的样本,我是属于第一类的,我这个样本的难度就是我到第一类的中心的距离比上我到所有类别中心距离的比值,所以第一,个两个样本谁距离它的类别中心越近,谁越简单。第二,如果两个样本距离本类的中心距离是一样的,比如它在本类中心周围的圆上,这两个样本的难度是谁距离其他类别更远,谁更简单。

如图是函数的评估效果,图上是我自己随机产生了三个类别的一个数据,可以看到是三个不同颜色的点。那么用我们上面这个评估函数,最简单的20%的数据是聚集在这三个类别的中心,就它们距离自己本类的中心都非常近的,这20%的数据就是最简单的。同样我们把选出来最难的这20%的数据,可以看到它分布在这三个类别的边缘之上,可以看到难度评估的效果是比较合理的。

然后有一点需要注意的是这里的难度评估函数,它是要结合对比学习使用的,也就是说我们这里的dis函数,对距离的评估,它是要和对比学习里的打分函数,度量方式是相互对应的,也就是距离越大,相似度越小,在我们这篇文章里面,我们用的是余弦相似度,只有用相同的度量,最后难度评估函数衡量出来的难度才能在对比学习的过程中得到反映。

我们会把样本给排序之后,发现在训练过程中,前面这个模型学到的样本过于简单了,然后后面又过于的难了,就会导致这个模型在前面几轮就过拟合掉了,它把检测样本迅速的就背下来了,但是到后面它又学不明白,然后就会导致性能的震荡。

数据采样策略


采样概率设计的非常简单,假设现在有100个样本,把它从简单到难已经排好序了,构造一个等差数列,假设一共训练6轮,如图这个例子,那么第一轮的时候,构造这样的等差序列,ST的话是1减去k除以r就相当于在第一轮的时候,我是从1开始的,然后最后一轮的时候我是从0开始的,那么第零训练开始的时候,我们的采样概率是0.99,0.98,0.97一直跌到到0,这样的话可以看到我们简单样本的采样概率更高,难样本的采样概率更低。

然后随着训练的进行,我们去调整采样概率的等差序列的斜率。然后到最后一轮的时候,我们就会做到前面第一个样本可能是零点一几,然后最后的话是零点八几。把前面的等差数列构造出来之后,它是一个浮点数的概率序列,那么我们用它来初始化一个伯努利率分布,伯努利分布就是大家在初高中阶段学到的二项分布,它可以把一个01之间的一个概率值通过采样变成一个01这样的一个离散的值。所以我们可以通过前面讲的采样的一个概率的等差序列,把它变成一个01的这样的一个离散的值。


采样结果序列上样本对应为零,就表示没有选择这个样本,采样完之后,就会得到一个全部数据的子集,子集采样的效果,我们可以看右手边这张图,在第0个epoch的时候,也就是训练第0轮的时候,下面这个图就是我们的采样概率,我们在采样简单的更多可以看到我们这个数据绿色是集中在每一个类别的中心的,但是也不完全集中在这儿,我们会在类别边缘也有一定的采样,让它不至于过于简单就去背它的质心。

然后在最后一个epoch的时候,就可以看到我们的选择主要分布在类别的外围,反而中间这部分数据最多的,这些我们没有怎么选择。总的来说,我们课程学习的整个策略就是一方面我们需要把这个数据把它变成一个从简单到困难这样一个过程,来缓解那些非常难的样本对我们模型的性能的影响。

另一方面我们又不希望它前面太简单,后面太困难,所以我们设计了采样策略,那么它的目的就是缩小前后的难度极差,然后用总的训练轮数就可以控制它难度变化的速度。

实验验证


我们使用了三个数据集来验证,这三个数据集都只使用了它其中的文本信息,然后它的统计数据可以看到是表里边的No.dials,就是说它一共有多少个对话,然后下面是它的各个数据集的一个分布的情况,然后下面CLS是表示每一个数据集有多少种类别,这里边都是六七类这个样子,然后这边的话是它各个类别的数据分布的情况。

第一个IEMOCAP数据集其实是相对来说均衡一些的,就是它最少的类别和最多的类别的差距不是特别的大。但是后面这两个数据的话就可以看到,尤其是最后MELD数据集,它的恐惧的情感,和自然情感相比已经不是一个数量级的了,它大概只有一两百个,但是自然的话可能有接近5000个,所以就能看到在后两个数据集上类别不均衡的情况还是比较严重的。

这个是实验结果,大家发论文的话,或者说看论文都知道,这个实验结果一般来说是比较漂亮的,我们也不例外,基本上在这三个数据集上都拿到了一个目前最好的结果。


消融实验是我们比较喜欢的,这里边cl就是表示我们的课程学习策略,然后SupCon的话是我们前面介绍过的,有监督对比学习,然后spcl是我们提出的有监督原型对比学习,最好的效果是结合这两部分方法。

这里就能看到,CE是我们最开始提到被广泛使用的交叉熵损失函数,可以看到我们的课程学习策略对于交叉商损失函数来说是没有增益的,可以看到用上它之后,它还变差了67.40。

这里也佐证了我们之前提到难度评估函数的时候,我们需要难度评估函数它的距离的度量和对比学习使用同样的度量方式,在交交叉熵损失函数里边我们是没有度量的,所以我们的课程学习评估出来的样本难度,对于交叉熵损失函数来说就是没有意义的。这两部分实验结合在一起,就证明了我们提出了有监督原型对比学习的损失函数,还有课程学习策略都是有效果的。


为了让差异更加明显,我们手工构造了一个极端不均衡的数据集,这是我们在MELD数据集里面抽取出来的,是右图这样的一个分布,在中性的情感里面,我们采用了1024个,那么在最后恐惧的情感里面,我们只采用了32个,它们的差异是非常的大的。

我们对比了在这种情况下,原始的有监督对比学习和我们改进的有监督原型对比学习,他们在不同的batchsize的情况下,它们的性能是怎么样的。batch size是指一次优化去采样多少个样本,可以看到在各个batch size的情况之下,我们提出的有监督原型对比学习都是要比原始的有监督对比学习要好一些,而且我们可以发现batch size越小,我们这个优势就越明显。那么我们就有进一步的猜想,是不是我们这个方法它能降低对比学习对于batch size的需求。

于是我们就做了下面的实验。在分布相对均匀的IEMOCAP数据集上,测试了在不同batch size的情况下,SPCL损失函数和传统的有监督对比损失函数的性能对比,可以看到在低batch size的时候,比如说在4的时候,比他们高了大约有6个点,就能证明一下相比于传统的supcon损失函数,我们不仅可以适用于这种类别不均衡的一些场景,同时我们也有着更低的计算资源的需求,课程学习也进一步提升了我们对比学习在文本对话情感分析任务上的性能。

彩蛋


这个彩蛋部分我们没有在论文中提及,因为解耦对比学习不是我们的贡献。解耦对比学习的核心贡献是现在对比学习需要那么大的batch size,因为InfoNCE损失的形式问题。

他们从理论上证明了,去掉InfoNCE损失分母中的正样本,可以让对比学习对batch size的需求降低,我们为我们的SPCL损失实现了解耦版本,我们叫它SPDCL,算力有限的同学可以尝试一下,我们发现大部分情况下SPCL和SPDCL性能相当,小batch size的情况下SPDCL有一些优势,但是也不够稳定。




1、情感的定义问题



人类是可以感受到情感的微妙变化的,尤其是一些共情能力比较强的人,可能一些很细微的态度的变化他都能捕捉到,然后从我们丰富的表情和社交网络中的表情包文化就可以体现到这一点。

每一个emoji都能表现非常细致的情感,但是对话情感分析领域里的标签数量大概只有7个,多一点的也只有12个,显然它是不足以描述我们所有的情绪状态的。我们一共有多少种情感,如何去定义客观的情感类别?大的方向就是喜怒哀乐,那么还有一些比如日常会有的一些尴尬,害怕的情感,它们和喜怒哀乐的关系是怎么样的,可能是我们需要去研究的问题。

2、情感的强度问题



这是在现实的场景会遇到的问题,在人机交互系统里面,比如客服系统,一般来说它是先进入到智能客服的环节,可能智能客服不能解决用户的问题的时候,用户可能会发火,用户甚至会有骂脏话之类的情况。用户接进来了之后,他的情感最开始的时候可能是无所谓,后面渐渐地有一些不满了,然后开始不耐烦,生气,最后可能演变成暴怒的状态。

那么这些中间的情感我们该如何去界定?这个强度很明显是一个连续的状态,我们该如何建模?然后另一个问题是我们应该在哪种程度情绪被触发的时候,启用一个人工介入的操作。有的语音的对话机器人是有这样的功能,打电话过去是由人工智能接听的电话,虽然它语气很生硬的,但是如果在你表达了一些负面的情绪,它是会比较智能的去转接到人工为你服务。他们用的模型目前来说还是一个分类模型,只是做到了判断这个人有没有负面情绪,那么进一步如何去区分情绪的强度,是一个比较值得研究的问题。

3、情感的分解问题


目前数据集里的这些情感的类别,主要是借鉴于心理学领域的分类,如果我们作为做计算机的做算法的,给不出更合理的定义,我们就暂时沿用心理学领域的成果。我就以现有的情感分类作为基底,用户表达出来的情感,情感可能比较复杂,肯定不是说只是单一的这一种情感,如果这个情感比较复杂,我们能不能把它分解到几个基底之上?


如上图:大家和伴侣有吵架或者拌嘴的过程,对方可能表达出来的复杂情绪,是需要比较细腻地去体会的,从而我们要采取不一样的行动,比如目前他生气比较严重,我们要做的先要道歉,熄火,去平复他的情绪,要让大家能冷静坐下来对话,这是首要的。

如果是第二种,可能做了一些不太好的事情让人家失望了,这个时候对方感觉到很无力很失望,我们要努力的展示一下自己积极的态度。第三种情况,太伤心了,我们就要去做一些安慰的事情,提升一下情绪基调之类的。可以看到同样这些都是负面情绪,然后他们不同情感的含量不同,指导出来的行为也是不一样的,对于构建人机交互系统是非常重要的事情,它直接影响着我们的对话策略模块。

对话策略就是说用户输入来一句话之后,我们去采取什么样的行为,回复什么样的话,给用户决策模块是非常重要的,那么情感的分解对于指导我们人机交互系统去进行回复是比较重要的。

直播预告


 今日推荐 
往期精彩推荐
点击标题查看文章

 专题|如何构建行之有效的算法透明《人工智能治理与可持续发展实践白皮书》



● AAIG成立一周年!砥砺前行,谱写新时代的科技之歌~请查收这份最新的自我介绍


● AI治理必修第16刊|国产AI作画神器来了!日增5万用户的背后有什么秘诀?DeepMind攻克50年数学难题!


 听委员说|AAIG薛晖出席杭州市"两会",提出加快建立人工智能产业的多元协同治理机制


 文本如药?如何通过多样例学习判断有效成分?如何识别辱骂文本?对话质量分析应用场景?AAIG自然语言理解实验室EMNLP专场(上)


 “算法偏见”是概念炒作吗?「这个AI不太冷」第3期带你揭秘现实AI!

更多人工智能治理和可持续发展好文点击下方名片关注和星标【阿里巴巴人工智能治理与可持续发展研究中心】👇AAIG课代表,获取最新动态就找她

 关注公众号发现更多干货❤️


有启发点在看喔👇
继续滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存