Seq2seq强化,Pointer Network简介

2018 年 12 月 8 日 机器学习算法与Python学习

源/ATYUN订阅号


Pointer Network(为方便起见以下称为指针网络)是seq2seq模型的一个变种。他们不是把一个序列转换成另一个序列, 而是产生一系列指向输入序列元素的指针。最基础的用法是对可变长度序列或集合的元素进行排序。


seq2seq的基础是一个LSTM编码器加上一个LSTM解码器。在机器翻译的语境中, 最常听到的是: 用一种语言造句, 编码器把它变成一个固定大小的陈述。解码器将他转换成一个句子, 可能和之前的句子长度不同。例如, “como estas?”-两个单词-将被翻译成 “how are you?”-三个单词。


当“注意力”增强时模型效果会更好。这意味着解码器在输入的前后都可以访问。就是说, 它可以从每个步骤访问编码器状态, 而不仅仅是最后一个。思考一下它怎样帮助西班牙语让形容词在名词之前: “neural network”变成 “red neuronal”


在专业术语中,“注意力”(至少是这种特定的 基于内容的注意力) 归结为加权平均值均数。简而言之,编码器状态的加权平均值转换为解码器状态。注意力只是权重的分配。


想知道更多可以访问:https://medium.com/datalogue/attention-in-keras-1892773a4f22


在指针网络中, 注意力更简单:它不考虑输入元素,而是在概率上指向它们。实际上,你得到了输入的排列。有关更多细节和公式, 请参阅论文:

https://arxiv.org/abs/1506.03134


注意, 不需要使用所有的指针。例如, 给定一段文本, 网络可以通过指向两个元素来标记摘录: 它的起始位置和结束位置。

实验

我们从顺序数字开始?换句话说,一个深入的argsort:


1

In [3]: np.argsort([10,30,20 ])

2

Out[3]: array([0,2,1], dtype=int64)

3


4

In [4]: np.argsort([40,10,30,20 ])

5

Out[4]: array([1,3,2,0], dtype=int64)


令人惊讶的是,作者在论文中没有继续进行完成任务。相反的,他们使用两个奇特的问题:旅行推销员和凸包(参考README), 虽然结果是好的。但为什么不按照数字顺序呢?

原来,数字排序很难做到。他们在后续文件中提到了这个问题(Order Matters: Sequence to sequence for sets)。重点是顺序不能错。也就是说,我们讨论的是输入元素的顺序。作者发现,它对结果影响很大, 这不是我们想要的。因为本质上我们处理的是集合作为输入, 而不是序列。集合没有固定的顺序,所以元素是如何排列在理论上不应该影响结果。


因此, 本文介绍了一种改进的架构, 它们通过连接到另一个LSTM的前馈网络来替换LSTM编码器。这就是说,LSTM重复运行,以产生一个置换不变的嵌入给输入。解码器同样是一个指针网络。


让我们回到数字排列。较长的集合更难去排列。对于5个数字,他们报告的准确度范围是81%-94%, 具体取决于模型 (这里提到的准确度是指正确排序序列的百分比)。当处理15数字时, 这个范围变成了0%-10%。


在我们的研究中,对于五个数字,我们几乎达到了100%的准确度。请注意, 这是Keras所报告的 “分类精度”, 意思是在正确位置上元素的百分比。例如, 这个例子是50%准确度,即前两个元素不动, 但最后两个被调换:


1

4 3 2 1 ->3 2 0 1


对于有八元素的序列, 分类精度下降到大约33%。我们还尝试了一个更具挑战性的任务, 按它们的和对一个集合进行排序:


1

[1 2] [3 4] [2 3]->0 2 1


网络处理它就像处理简单的(un)标量数字。

我们注意到的一个意想不到的事情是, 网络倾向于重复指针, 尤其是在训练的早期。这是令人失望的:显然它不记得它不久之前的预测。


1

y_test: [2 0 1 4 3]

2

p:      [2 2 2 2 2]



在训练的早期, 人们聚集在一起, 构想指针网络的输出。


1

y_test: [2 0 1 4 3]

2

p:      [2 0 2 4 3]


同时, 训练有时会被某种准确度所困。而一个对少量数字进行训练的网络并不能概括更大的, 比如:


1

981,66,673

2

856,10,438

3

884,808,241


为了帮助网络使用数字, 我们添加一个 ID (1,2, 3…) 到序列的每个元素。这个假设是因为注意力是基于内容的, 也许它可以使用内容中明确编码的位置。此ID是一个数字 (train_with_positions) 或独热向量 (train_with_positions_categorical)。这看起来有点效果,但没有解决根本问题。


实验代码在GitHub可以使用。与original repo相比, 我们添加了一个数据生成脚本, 并更改了训练脚本以从生成的文件中加载数据。我们还将优化算法改成RMSPro, 因为它在处理学习率的过程中似乎收敛得很好。

数据结构

3D数组中的数据。第一个维度 (行) 是像往常一样的例子。第二个维度“列”通常是特征(属性), 但带序列的特征进入第三个维度。第二个维度由给定序列的元素组成。下面是三个序列示例, 每个都有三个元素 (步骤), 每个元素都有两个特征:


01

array([[[82],

02

        [33],

03

        [103]],

04


05

       [[14],

06

        [19,12],

07

        [4,10]],

08


09

       [[190],

10

        [15,12],

11

        [86]],


目标是按特征的和对元素进行排序, 因此相应的目标将是:


1

array([[1,0,2],

2

       [0,2,1],

3

       [2,0,1],


并且,它们将被明确编码:


01

array([[[0.1.0.],

02

        [1.0.0.],

03

        [0.0.1.]],

04


05

       [[1.0.0.],

06

        [0.0.1.],

07

        [0.1.0.]],

08


09

       [[0.0.1.],

10

        [1.0.0.],

11

        [0.1.0.]],


这里有一个问题,我们一直在讨论循环网络如何处理可变长度的序列,但实际上数据是3D数组,如上所示。换句话说,序列长度是固定的。

处理这一问题的方法是在最大可能的序列长度上固定维度, 并用零填充未使用的位置。


但它有可能搞乱代价函数,因此我们更好地掩盖那些零, 确保他们在计算损失时被省略。Keras官方的做法似乎是embdedding layer。相关参数为mask_zero:


mask_zero: 无论输入值0是否是一个特殊的 “padding” 值, 都应该被屏蔽掉。当使用可变长度输入的循环层时这很有用。如果它为“True”,那么模型中的所有后续层都需要支持掩蔽, 否则将引发异常。如果 mask_zero设置为True, 那么作为一个序列,词汇表中不能使用索引0(input_dim应等于词汇量“+1”)。

关于实现

我们使用了一个Keras执行的指针网络。GitHub上还有一些其他的, 大部分用Tensorflow。


附录A:指针网络的实现


  • https://github.com/keon/pointer-networks 幻灯片

  • https://github.com/devsisters/pointer-network-tensorflow

  • https://github.com/vshallc/PtrNets

  • https://github.com/ikostrikov/TensorFlow-Pointer-Networks

  • https://github.com/Chanlaw/pointer-networks

  • https://github.com/devnag/tensorflow-pointer-networks

  • https://github.com/udibr/pointer-generator

  • https://github.com/JerrikEph/SentenceOrdering_PTR

  • https://github.com/pradyu1993/seq2set-keras


附录B:seq2seq的一些注意力的实现


  • https://github.com/philipperemy/keras-attention-mechanism

  • https://github.com/tensorflow/models/tree/master/textsum

  • https://github.com/tensorflow/tensor2tensor

  • Translation with a Sequence to Sequence Network and Attention (PyTorch tutorial)

  • https://github.com/MaximumEntropy/Seq2Seq-PyTorch

  • https://github.com/rowanz/pytorch-seq2seq

  • https://github.com/chainer/chainer/tree/seq2seq-europal/examples/seq2seq



推荐阅读

职场 | 阿里P9谈程序员的“青春饭”

下载 | 193页无监督深度学习PPT教程

收藏 | Numpy详细教程

20个堪称神器的Linux命令行软件

下载 | 9G爬虫视频教程 - 入门+进阶+实践


登录查看更多
15

相关内容

专知会员服务
44+阅读 · 2020年3月6日
Transformer文本分类代码
专知会员服务
116+阅读 · 2020年2月3日
【MIT深度学习课程】深度序列建模,Deep Sequence Modeling
专知会员服务
76+阅读 · 2020年2月3日
注意力机制介绍,Attention Mechanism
专知会员服务
165+阅读 · 2019年10月13日
深度学习的下一步:Transformer和注意力机制
云头条
56+阅读 · 2019年9月14日
多图带你读懂 Transformers 的工作原理
AI研习社
10+阅读 · 2019年3月18日
从Seq2seq到Attention模型到Self Attention(一)
量化投资与机器学习
76+阅读 · 2018年10月8日
机器翻译不可不知的 Seq2Seq 模型
AI研习社
4+阅读 · 2018年5月24日
一文读懂LSTM和循环神经网络
七月在线实验室
8+阅读 · 2018年4月18日
基础 | 基于注意力机制的seq2seq网络
黑龙江大学自然语言处理实验室
16+阅读 · 2018年3月7日
从 Encoder 到 Decoder 实现 Seq2Seq 模型
AI研习社
10+阅读 · 2018年2月10日
TensorFlow seq2seq中的Attention机制(续)
深度学习每日摘要
15+阅读 · 2017年11月16日
十分钟掌握Keras实现RNN的seq2seq学习
机器学习研究会
10+阅读 · 2017年10月13日
【推荐】(TensorFlow)RNN入门
机器学习研究会
9+阅读 · 2017年10月10日
Arxiv
6+阅读 · 2019年7月11日
Arxiv
6+阅读 · 2019年4月8日
Arxiv
4+阅读 · 2018年1月29日
Arxiv
5+阅读 · 2017年11月13日
Arxiv
4+阅读 · 2017年7月25日
VIP会员
相关VIP内容
专知会员服务
44+阅读 · 2020年3月6日
Transformer文本分类代码
专知会员服务
116+阅读 · 2020年2月3日
【MIT深度学习课程】深度序列建模,Deep Sequence Modeling
专知会员服务
76+阅读 · 2020年2月3日
注意力机制介绍,Attention Mechanism
专知会员服务
165+阅读 · 2019年10月13日
相关资讯
深度学习的下一步:Transformer和注意力机制
云头条
56+阅读 · 2019年9月14日
多图带你读懂 Transformers 的工作原理
AI研习社
10+阅读 · 2019年3月18日
从Seq2seq到Attention模型到Self Attention(一)
量化投资与机器学习
76+阅读 · 2018年10月8日
机器翻译不可不知的 Seq2Seq 模型
AI研习社
4+阅读 · 2018年5月24日
一文读懂LSTM和循环神经网络
七月在线实验室
8+阅读 · 2018年4月18日
基础 | 基于注意力机制的seq2seq网络
黑龙江大学自然语言处理实验室
16+阅读 · 2018年3月7日
从 Encoder 到 Decoder 实现 Seq2Seq 模型
AI研习社
10+阅读 · 2018年2月10日
TensorFlow seq2seq中的Attention机制(续)
深度学习每日摘要
15+阅读 · 2017年11月16日
十分钟掌握Keras实现RNN的seq2seq学习
机器学习研究会
10+阅读 · 2017年10月13日
【推荐】(TensorFlow)RNN入门
机器学习研究会
9+阅读 · 2017年10月10日
Top
微信扫码咨询专知VIP会员