Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
橘蓝
Paddle
提交
00b86b1f
P
Paddle
项目概览
橘蓝
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
00b86b1f
编写于
12月 07, 2016
作者:
Y
Yu Yang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Follow comments
上级
aed8803a
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
35 addition
and
23 deletion
+35
-23
doc_cn/algorithm/rnn/hrnn_rnn_api_compare.rst
doc_cn/algorithm/rnn/hrnn_rnn_api_compare.rst
+35
-23
未找到文件。
doc_cn/algorithm/rnn/hrnn_rnn_api_compare.rst
浏览文件 @
00b86b1f
...
...
@@ -4,14 +4,14 @@
单双层RNN API对比介绍
#####################
这篇教程主要介绍了\ :ref:`glossary_双层RNN`\ 的API接口。
本文以PaddlePaddle的\ :ref:`glossary_双层RNN`\ 单元测试为示例,用多对效果完全相同的、分别使用单双层RNN作为网络配置的模型,来讲解如何使用\ :ref:`glossary_双层RNN`\ 。本文中所有的例子,都只是介绍\ :ref:`glossary_双层RNN`\ 的API接口,并不是使用\ :ref:`glossary_双层RNN`\ 解决实际的问题。如果想要了解\ :ref:`glossary_双层RNN`\ 在具体问题中的使用,请参考\ :ref:`algo_hrnn_demo`\ 。本文中示例所使用的单元测试文件是\ `test_RecurrentGradientMachine.cpp <https://github.com/reyoung/Paddle/blob/develop/paddle/gserver/tests/test_RecurrentGradientMachine.cpp>`_\ 。
本文以PaddlePaddle的\ :ref:`glossary_双层RNN`\ 单元测试为示例,用多对效果完全相同的、分别使用单双层RNN作为网络配置的模型,来讲解如何使用\ :ref:`glossary_双层RNN`\ 。本文中所有的例子,都只是介绍\ :ref:`glossary_双层RNN`\ 的API接口,并不是使用\ :ref:`glossary_双层RNN`\ 解决实际的问题。如果想要了解\ :ref:`glossary_双层RNN`\ 在具体问题中的使用,请参考\ :ref:`algo_hrnn_demo`\ 。本文中示例所使用的单元测试文件是\ `test_RecurrentGradientMachine.cpp <https://github.com/reyoung/Paddle/blob/develop/paddle/gserver/tests/test_RecurrentGradientMachine.cpp>`_\ 。
示例1:双层RNN,子序列间无Memory
================================
在\ :ref:`glossary_双层RNN`\ 中的经典情况是将内层的每一个\ :ref:`glossary_sequence`\ 数据,分别进行序列操作
。并且内层的序列操作之间是独立没有依赖的,即不需要使用\ :ref:`glossary_Memory`\ 的
。
在\ :ref:`glossary_双层RNN`\ 中的经典情况是将内层的每一个\ :ref:`glossary_sequence`\ 数据,分别进行序列操作
;并且内层的序列操作之间独立无依赖,即不需要使用\ :ref:`glossary_Memory`\
。
在本示例中,单层\ :ref:`glossary_RNN`\ 和\ :ref:`glossary_双层RNN`\ 的网络配置,都是将每一句分好词后的句子,使用LSTM作为encoder,压缩成一个向量。区别是\ :ref:`glossary_RNN`\ 使用两层序列模型,将多句话看成一个整体
,同时使用encoder压缩,二者语意上完全一致。这组语意相同的示例配置如下
在本示例中,单层\ :ref:`glossary_RNN`\ 和\ :ref:`glossary_双层RNN`\ 的网络配置,都是将每一句分好词后的句子,使用LSTM作为encoder,压缩成一个向量。区别是\ :ref:`glossary_RNN`\ 使用两层序列模型,将多句话看成一个整体
同时使用encoder压缩。二者语意上完全一致。这组语义相同的示例配置如下:
* 单层\ :ref:`glossary_RNN`\: `sequence_layer_group.conf <https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/gserver/tests/sequence_layer_group.conf>`_
* :ref:`glossary_双层RNN`\: `sequence_nest_layer_group.conf <https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/gserver/tests/sequence_nest_layer_group.conf>`_
...
...
@@ -28,7 +28,7 @@
:language: text
- 双层序列数据一共有4个样本。 每个样本间用空行分开,整体数据和原始数据完全一样。
而对于双层序列的LSTM来说,第一条数据同时encode两条数据成两个向量。这四条数据同时处理的句子
为\ :code:`[2, 3, 2, 3]`\ 。
- 双层序列数据一共有4个样本。 每个样本间用空行分开,整体数据和原始数据完全一样。
但于双层序列的LSTM来说,第一个样本同时encode两条数据成两个向量。这四条数据同时处理的句子数量
为\ :code:`[2, 3, 2, 3]`\ 。
.. literalinclude:: ../../../paddle/gserver/tests/Sequence/tour_train_wdseg.nest
:language: text
...
...
@@ -51,17 +51,17 @@
:lines: 42-71
:linenos:
-
这是对于同样的数据,本示例中双层\ :ref:`glossary_sequence`\ 的\ :ref:`glossary_DataProvider`\ 代码,
其说明如下:
-
对于同样的数据,双层\ :ref:`glossary_sequence`\ 的\ :ref:`glossary_DataProvider`\ 的代码。
其说明如下:
- :ref:`glossary_DataProvider`\ 共返回两组数据,分别是sentences和labels。即在双层序列的原始数据中,每一组内的所有句子和labels
- sentences是双层\ :ref:`glossary_sequence`\ 的数据。
他内部包括了每组数据中的所有句子,又使用句子中每一个单词的词表index表示每一个句子,故为双层\ :ref:`glossary_sequence`\ 。类型为 integer_value_sub_sequence
。
- labels是每组内每
一
个句子的标签,故而是一个单层\ :ref:`glossary_sequence`\ 。
- sentences是双层\ :ref:`glossary_sequence`\ 的数据。
由于它内部包含了每组数据中的所有句子,且每个句子表示为对应的词表索引数组,因此它是integer_value_sub_sequence 类型的,即双层\ :ref:`glossary_sequence`\
。
- labels是每组内每个句子的标签,故而是一个单层\ :ref:`glossary_sequence`\ 。
:ref:`glossary_trainer_config`\ 的模型配置
------------------------------------------
首先,我们看一下单层\ :ref:`glossary_RNN`\ 的配置。代码中9-15行即为单层RNN序列的使用代码。这里使用了PaddlePaddle预定义好的\ :ref:`glossary_RNN`\ 处理函数。在这个函数中,\ :ref:`glossary_RNN`\ 对于每一个\ :ref:`glossary_timestep`\ 通过了一个LSTM网络。
首先,我们看一下单层\ :ref:`glossary_RNN`\ 的配置。代码中9-15行
(高亮部分)
即为单层RNN序列的使用代码。这里使用了PaddlePaddle预定义好的\ :ref:`glossary_RNN`\ 处理函数。在这个函数中,\ :ref:`glossary_RNN`\ 对于每一个\ :ref:`glossary_timestep`\ 通过了一个LSTM网络。
.. literalinclude:: ../../../paddle/gserver/tests/sequence_layer_group.conf
:language: python
...
...
@@ -70,19 +70,19 @@
:emphasize-lines: 9-15
其次,我们看一下语义相同的\ :ref:`glossary_双层RNN`\ 的网络配置
。
其次,我们看一下语义相同的\ :ref:`glossary_双层RNN`\ 的网络配置
\:
* PaddlePaddle中的许多layer并不在意输入是否是\ :ref:`glossary_sequence`\ ,例如\ :code:`embedding_layer`\ 。在这些layer中,所有的操作都是针对每一个\ :ref:`glossary_timestep`\ 来进行的。
* 在该配置
中,7-26行将双层\ :ref:`glossary_sequence`\ 数据,先变换成单层\ :ref:`glossary_sequence`\ 数据,在
对每一个单层\ :ref:`glossary_sequence`\ 进行处理。
* 在该配置
的7-26行(高亮部分),将双层\ :ref:`glossary_sequence`\ 数据先变换成单层\ :ref:`glossary_sequence`\ 数据,再
对每一个单层\ :ref:`glossary_sequence`\ 进行处理。
* 使用\ :code:`recurrent_group`\ 这个函数进行变换,在变换时需要将输入序列传入。由于我们想要的变换是双层\ :ref:`glossary_sequence`\ => 单层\ :ref:`glossary_sequence`\ ,所以我们需要将输入数据标记成\ :code:`SubsequenceInput`\ 。
* 在本例中,我们将原始数据的每一组,通过\ :code:`recurrent_group`\ 进行拆解,拆解成的每一句话再通过一个LSTM网络。这和单层\ :ref:`glossary_RNN`\ 的配置是等价的。
* 与单层\ :ref:`glossary_RNN`\ 的配置类似,我们只需要
知道使用LSTM encode成的最后一个向量。所以对\ :code:`recurrent_group`\ 进行了\ :code:`last_seq`\ 操作。但是,和单层\ :ref:`glossary_RNN`\ 有区别的地方是,我们是对每一个子序列取最后一个元素。于是我们设置
\ :code:`agg_level=AggregateLevel.EACH_SEQUENCE`\ 。
* 与单层\ :ref:`glossary_RNN`\ 的配置类似,我们只需要
使用LSTM encode成的最后一个向量。所以对\ :code:`recurrent_group`\ 进行了\ :code:`last_seq`\ 操作。但和单层\ :ref:`glossary_RNN`\ 不同,我们是对每一个子序列取最后一个元素,因此
\ :code:`agg_level=AggregateLevel.EACH_SEQUENCE`\ 。
* 至此,\ :code:`lstm_last`\ 便和单层\ :ref:`glossary_RNN`\
的
配置中的\ :code:`lstm_last`\ 具有相同的结果了。
* 至此,\ :code:`lstm_last`\ 便和单层\ :ref:`glossary_RNN`\ 配置中的\ :code:`lstm_last`\ 具有相同的结果了。
.. literalinclude:: ../../../paddle/gserver/tests/sequence_nest_layer_group.conf
:language: python
...
...
@@ -93,30 +93,34 @@
示例2::ref:`glossary_双层RNN`,子序列间有\ :ref:`glossary_Memory`
==================================================================
本示例中,意图使用单层\ :ref:`glossary_RNN`\ 和\ :ref:`glossary_双层RNN`\ 同时实现一个完全等价的全连接\ :ref:`glossary_RNN`\ 。对于单层\ :ref:`glossary_RNN`\ ,输入数据为一个完整的\ :ref:`glossary_sequence`\ ,例如\ :code:`[4, 5, 2, 0, 9, 8, 1, 4]`\ 。而对于\ :ref:`glossary_双层RNN`\ ,输入数据为在单层\ :ref:`glossary_RNN`\ 数据里面,任意将一些数据组合成双层\ :ref:`glossary_sequence`\ ,例如\ :code:`[ [4, 5, 2], [0, 9], [8, 1, 4]]`。
本示例意图使用单层\ :ref:`glossary_RNN`\ 和\ :ref:`glossary_双层RNN`\ 实现两个完全等价的全连接\ :ref:`glossary_RNN`\ 。
* 对于单层\ :ref:`glossary_RNN`\ ,输入数据为一个完整的\ :ref:`glossary_sequence`\ ,例如\ :code:`[4, 5, 2, 0, 9, 8, 1, 4]`\ 。
* 对于\ :ref:`glossary_双层RNN`\ ,输入数据为在单层\ :ref:`glossary_RNN`\ 数据里面,任意将一些数据组合成双层\ :ref:`glossary_sequence`\ ,例如\ :code:`[ [4, 5, 2], [0, 9], [8, 1, 4]]`。
:ref:`glossary_trainer_config`\ 的模型配置
------------------------------------------
我们选取单双层序列配置中的不同部分,来对比分析两者语义相同的原因。
- 单层
序列
:过了一个很简单的recurrent_group。每一个时间步,当前的输入y和上一个时间步的输出rnn_state做了一个全链接。
- 单层
\ :ref:`glossary_rnn`\
:过了一个很简单的recurrent_group。每一个时间步,当前的输入y和上一个时间步的输出rnn_state做了一个全链接。
.. literalinclude:: ../../../paddle/gserver/tests/sequence_rnn.conf
:language: python
:lines: 36-48
-
双层序列
,外层memory是一个元素:
-
\ :ref:`glossary_双层RNN`\
,外层memory是一个元素:
- 内层inner_step的recurrent_group和单层序列的几乎一样。除了boot_layer=outer_mem,表示将外层的outer_mem作为内层memory的初始状态。外层outer_step中,outer_mem是一个子句的最后一个向量,即整个双层group是将前一个子句的最后一个向量,作为下一个子句memory的初始状态。
- 从输入数据上看,单双层序列的句子是一样的,只是双层序列将其又做了子序列划分。因此双层序列的配置中,必须将前一个子句的最后一个元素,作为boot_layer传给下一个子句的memory,才能保证和单层序列的配置中“每
一
个时间步都用了上一个时间步的输出结果”一致。
- 从输入数据上看,单双层序列的句子是一样的,只是双层序列将其又做了子序列划分。因此双层序列的配置中,必须将前一个子句的最后一个元素,作为boot_layer传给下一个子句的memory,才能保证和单层序列的配置中“每个时间步都用了上一个时间步的输出结果”一致。
.. literalinclude:: ../../../paddle/gserver/tests/sequence_nest_rnn.conf
:language: python
:lines: 39-66
.. warning::
PaddlePaddle目前只支持在每
一个时间步中,Memory的sequence
长度一致的情况。
PaddlePaddle目前只支持在每
个时间步中,Memory的\ :ref:`glossary_sequence`\
长度一致的情况。
示例3:双层RNN,输入不等长
==========================
...
...
@@ -127,31 +131,39 @@
<style> .red {color:red} </style>
**输入不等长** 是指recurrent_group的多个输入序列,在每个\ :ref:`glossary_timestep`\ 的子序列长度可以不相等。但\ :ref:`glossary_双层RNN`\ 目前需要整体的输出,与某一个输入的序列信息是一致的。使用\ :red:`targetInlink`\ 可以指定和输出序列信息一致。
**输入不等长** 是指recurrent_group的多个输入序列,在每个\ :ref:`glossary_timestep`\ 的子序列长度可以不相等。但序列输出时,需要指定与某一个输入的序列信息是一致的。使用\ :red:`targetInlink`\ 可以指定哪一个输入和输出序列信息一致,默认指定第一个输入。
示例3的配置分别为\ `单层不等长RNN <https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/gserver/tests/sequence_rnn_multi_unequalength_inputs.conf>`_\ 和\ `双层不等长RNN <https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/gserver/tests/sequence_nest_rnn_multi_unequalength_inputs.conf>`_\ 。
本例参考配置分别为\ `单层不等长RNN <https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/gserver/tests/sequence_rnn_multi_unequalength_inputs.conf>`_\ 和\ `双层不等长RNN <https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/gserver/tests/sequence_nest_rnn_multi_unequalength_inputs.conf>`_\
。
示例3对于单层\ :ref:`glossary_RNN`\ 和\ :ref:`glossary_双层RNN`\ 数据完全相同
。
本例中对于单层\ :ref:`glossary_RNN`\ 和\ :ref:`glossary_双层RNN`\ 数据完全相同,对于单层\ :ref:`glossary_RNN`\ 的数据一共有两个样本,他们分别是\ :code:`[1, 2, 4, 5, 2], [5, 4, 1, 3, 1]`\ 和\ :code:`[0, 2, 2, 5, 0, 1, 2], [1, 5, 4, 2, 3, 6, 1]`\ 。对于每一个单层\ :ref:`glossary_RNN`\ 的数据,均有两组特征。在单层数据的基础上,\ :ref:`glossary_双层RNN`\ 数据随意加了一些隔断,例如将第一条数据转化为\ :code:`[[0, 2], [2, 5], [0, 1, 2]],[[1, 5], [4], [2, 3, 6, 1]]`\ 。但是需要注意的是Paddle目前只支持序列数目一样的多输入\ :ref:`glossary_双层RNN`\ 。即两个特征,均有三个子序列。每个子序列长度可以不一致,但是子序列的数目必须一样。
* 对于单层\ :ref:`glossary_RNN`\ 的数据一共有两个样本,他们分别是\ :code:`[1, 2, 4, 5, 2], [5, 4, 1, 3, 1]`\ 和\ :code:`[0, 2, 2, 5, 0, 1, 2], [1, 5, 4, 2, 3, 6, 1]`\ 。对于每一个单层\ :ref:`glossary_RNN`\ 的数据,均有两组特征。
* 在单层数据的基础上,\ :ref:`glossary_双层RNN`\ 数据随意加了一些隔断,例如将第一条数据转化为\ :code:`[[0, 2], [2, 5], [0, 1, 2]],[[1, 5], [4], [2, 3, 6, 1]]`\ 。
* 需要注意的是Paddle目前只支持子序列数目一样的多输入\ :ref:`glossary_双层RNN`\ 。例如本里中的两个特征,均有三个子序列。每个子序列长度可以不一致,但是子序列的数目必须一样。
:ref:`glossary_trainer_config`\ 的模型配置
------------------------------------------
本例中的配置,使用了单层\ :ref:`glossary_RNN`\ 和\ :ref:`glossary_双层RNN`\ 使用一个\ :code:`recurrent_group`\ 将两个序列同时过完全连接的\ :ref:`glossary_RNN`\ 。对于单层\ :ref:`glossary_RNN`\ 的code如下。
和示例2中的配置累死,示例3的配置使用了单层\ :ref:`glossary_RNN`\ 和\ :ref:`glossary_双层RNN`\ ,实现两个完全等价的全连接\ :ref:`glossary_RNN`\ 。
* 单层\ :ref:`glossary_RNN`\ \:
.. literalinclude:: ../../../paddle/gserver/tests/sequence_rnn_multi_unequalength_inputs.py
:language: python
:lines: 42-59
:linenos:
而双层序列的代码如下。
* :ref:`glossary_双层RNN`\ \:
.. literalinclude:: ../../../paddle/gserver/tests/sequence_nest_rnn_multi_unequalength_inputs.py
:language: python
:lines: 41-80
:linenos:
在上面代码中,单层和双层序列的使用和示例2中的示例类似,区别是同时处理了两个输入。而对于双层序列,两个输入的子序列长度也并不相同。但是,我们使用了\ :code:`targetInlink`\ 参数设置了外层\ :code:`recurrent_group`\ 的输出格式。所以外层输出的序列形状,和\ :code:`emb2`的序列形状一致。
在上面代码中,单层和双层序列的使用和示例2中的示例类似,区别是同时处理了两个输入。而对于双层序列,两个输入的子序列长度也并不相同。但是,我们使用了\ :code:`targetInlink`\ 参数设置了外层\ :code:`recurrent_group`\ 的输出格式。所以外层输出的序列形状,和\ :code:`emb2`
\
的序列形状一致。
示例4:beam_search的生成
========================
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录