seq2seq模型的字符级的向量表示

许久未更博了,在前段时间测试了用seq2seq做ner任务,可以参考之前的文章《RNN的Seq2Seq模型做命名实体识别》 ,之后通过NER做NLU,再加上RL尝试多轮对话,结果达到了期望,但是还有很多工作需要去做,多轮语料采集、句子相似度、句向量,在多轮对话中,我没有尝试将每句话进行分类,我认为句子本身表意就非常清晰,标注反而画蛇添足,特别是上下文中的句子,其意思根据上下文而变化。那么对话中去匹配距离最近的句子,并且人为的反馈,可能是一个多轮对话的主要方式。

这篇文章将简单介绍seq2seq模型+attention机制,以及在这个模型下,字符级逐字的输入和输出任务产生的句向量的特性。

句子相似度,可以计算两个向量的空间距离得出,句子的向量表示来自seq2seq模型的encoder最后输出的state,它具有句子的语意信息,在论文中常常用context表示,如下图。在神经机器翻译机中,就是通过把context放入decoder,实现自动翻译。

Seq2Seq的基本模型,采用了一个单向的RNN做Encoder,最后一个State来表示全文的内容,若将整个句子放入到一个固定长度的向量中后,这个向量对最后输入到RNN的数据表现更友好,引起最终解码效果欠佳。

目前,主流都采用双向RNNs(BidirectionalRNN,一个向左,一个向右),可以更好的记录输入的信息。

这个模型可以较好的存储全文的内容,但是对长句子,用全文信息去解码还是不能很好的抓住重点,因此引入注意力机制(arXiv:1409.0473),通过计算encoder每个时刻隐层及权重(a)点乘,得到对应的标量,再将这些标量合成一个向量,最后通过映射层输出decoder的结果。这可以减小长文本中,encoder的句向量效果减弱问题。

模型参数:

字符级的句向量处理,整个模型逐字输入,逐字输出,单层的Bidirectional-GRU+注意力机制,字符向量128,RNN大小128,字符数量8000,学习率0.8,学习率衰退0.99,每批输入样本64。

输入语料,未做任何标注,是一个大杂烩,包含了:

  • 歌手名:王力宏、孙燕姿等等
  • 歌曲名:少年游、匆匆那年、唯一等等
  • 不同类型的请求指令
    • 听歌曲名:听匆匆那年,听青花瓷等等
    • 播放歌曲名:播放匆匆那年,播放青花瓷等
    • 播放歌手名的歌曲名:播放王力宏的唯一,播放周杰伦的青花瓷等
    • 其他类似的句子

输出结果:

逐字输入/逐字输出这种方式的句向量:

  • 长度敏感,输出结果长度和原句最多相差长度1。
  • 字符敏感,有点类似编辑距离,也就是说匹配字符及位置。
  • 能基于文字的上下文,区别其中文字的类别,虽然没有标注。表现在输入歌手“韩红、孙燕姿”的时候,返回相似度高的都是其他的歌手名[图1、2];输入首曲名“三人游”的时候,返回相似度高的都是其他的歌曲名[图3];同样对整句也能支持,[图4、5]返回的相似度高的,都基本是一样的句式;[图5],还存在一些误差。

 

下一步,更详细的看看语料向量化后的分布,这里采用t-SNE将向量映射到2维空间。t-SNE是一个非常好用的工具,可以将高纬降维到二维或三维,也可以将相邻的向量映射到一块。由于语料比较大,无法全部映射,因此我选取一个中心词——“王力宏”,通过欧式距离(t-SNE默认算法)截取最相似的100, 200, 500, 1000个数据,并做映射。

上图是100个样本的数据图,能看到“王力宏”周围最靠近的以及左侧都属于歌手名,右下角的那个簇群,是句式“首歌名的歌”和“歌手名的歌曲名”这类句式的集群,而且在数据不多的请宽下,这里主要表现的是歌手名带“王”字的歌手为主。正上方的有俩个样本,是句式“歌手名的歌曲名”样本,很特别,需要扩大样本数量来看看具体表现。

在样本数量到达200个以后,上面的俩个特例就被很好的解释了,全都出现在蓝色方框中,这时候又出现了新的情况,在灰色椭圆中的3个样本属于歌曲名。另外还有两个双字的歌手名未圈出。这俩类是否会像前面一样100样本中的特例在样本增多后增加呢?

500样本-图1
500样本-图2

200样本中的“歌曲名特例”在样本增加到500个以后还是不明显,我们放大了“500样本-图1”中的紫色位置及其附近,在“500样本-图2”中看到,歌曲名有所增加,但是不明显。不过“两字歌手名特例”却有了很大的增加,在“500样本-图1”的绿色圈内。由于语料的增加,也出现了“500样本-图1”蓝色圈类别——“放歌曲名”。

1000个样本中,“歌曲名特例”的增长也不是特别明显(样本1000-绿色方框),而“听歌曲名”增加了不少(样本1000-紫色方框),也增加了另外一类“听歌手名的歌曲名”(样本1000-绿色椭圆)。

在500样本和1000样本中,未圈出部分属于“歌手名的歌曲”和“歌手名的歌”俩主要类别,由于样本增加幅度很大,数据比较多,就没做进一步解释。

样本1000
样本1000-绿色方框
样本1000-紫色方框
样本1000-绿色椭圆
样本1000-红色圈
样本1000-紫色椭圆

定了一个中心点,再慢慢增加样本,我们发现,“三字歌手名”和“两字歌手名”被区分成了俩类,我将这点理解为字符级别的模型,对长度比较敏感;而在每一个类别中,文字重复率高的,越相近,这属于字符敏感;模型能够从未标注语句找出文本的类别,比如“歌手名”和“歌曲名”俩类相差甚远,我认为模型能够结合上下文理解来区分文字,这点十分的符合人类学习语言的习惯,就像我们学习方言一样。

最后,基于模型能学习上下文的句式,我尝试了词向量的经典玩法,虽然是字符级组成的句向量,也是把一个词,如“刘德华”当成一个句子,那么它们之间就可以任意的计算了,这和Quoc Le &Tomas Mikolov(点击阅读)的文档向量的概念相似。中间这幅图表示出如果“播放刘德华的歌”减去”刘德华“,但是还是和播放XXX的歌相似,这里也验证了这个模型学会了句式,不过我们对于这个操作,也会有一种理解是“播放刘德华的歌-刘德华=播放歌”。右边这幅图表示机器还无法理解隐藏在文字后的常识,通过Mikolov句向量的理论,如果加入更多的语料,比如百科的语料,也许能学习到这个常识。

总结:

这次实验,做了一个单层的双向+注意力机制的RNN模型,主要测试了字符级的处理在这个模型下产生的效果,长度敏感、字符敏感、会学会句式、取名习惯,还可以实现句子和词的加减,其实都属于文本的加减。这次任务无法获取更多的语义,也许和语料有关系,也许和解码任务有关,后续的工作,做seq2seq的多任务实验,此前,[Dongetal.2015]做了多语言翻译的seq2seq模型,将一个语言翻译成多个语言的任务,取得了很好的效果,而我打算将这个方法应用在将一句话做多个任务的理解,以此加大句向量的信息量,机器若要理解人类语言,就需要对所处环境、社会文化有所了解,对于一句话的不同解读方式,会是机器理解人类语言的重要一步。

评论

《 “seq2seq模型的字符级的向量表示” 》 有 8 条评论

  1. […] seq2seq模型的字符级的向量表示 […]

  2. xillkey 的头像
    xillkey

    您好,你这个模型的解码任务是什么?是原样逐字输出吗?谢谢!

  3. 程名 的头像
    程名

    您好 我是一名在校大学生,我姓程。我现在对于将注意力机制融入命名实体识别的任务比较感兴趣,希望能得到您的微信或其他联系方式,想跟您请教。期待得到您的回复,谢谢。

    1. Kun 的头像
      Kun

      您哈,可以给我发邮件jin.kun@flykun.com

    2. Kun 的头像
      Kun

      另外,Attention这个资料,网络上的资料已经很多,推荐多看看原论文,再找一些review看看如何操作,也可以读读代码,这样更了解其原理。

  4. xiang 的头像
    xiang

    网上t-sne的数据大多来源于minist这种处理过的数据,请问一下您,要是我想可视化自己的文本数据,该怎么预处理呢。我看您分类的就是歌手歌曲的信息。谢谢。

    1. Kun 的头像
      Kun

      数据可视化是做结果的,当你将词或者句子embedding之后,就会形成一个很长很长的向量,之后通过t-SNE,直接降维映射就好了。阅读t-SNE的说明,就应该能明白的。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据