Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions doc_cn/algorithm/rnn/glossary_rnn.dot
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
digraph G{
subgraph cluster_timestep0 {
label="recurrent timestep i-1"
bgcolor=lightgray
node [style=filled,color=white]
fc0_0 [label="fc 0"]
fc0_1 [label="fc 1"]
fc0_2 [label="fc 2"]

fc0_0 -> fc0_1
fc0_1 -> fc0_2
}

subgraph cluster_timestep1 {
label="recurrent timestep i"
node [style=filled];
fc1_0 [label="fc 0"]
fc1_1 [label="fc 1"]
fc1_2 [label="fc 2"]
color=blue

fc1_0 -> fc1_1
fc1_1 -> fc1_2
}

subgraph cluster_timestep2 {
label="recurrent timestep i+1"
bgcolor=lightgray
node [style=filled,color=white]
fc2_0 [label="fc 0"]
fc2_1 [label="fc 1"]
fc2_2 [label="fc 2"]

fc2_0 -> fc2_1
fc2_1 -> fc2_2
}


fc0_1 -> fc1_1 [style="dotted" constraint=false]
fc1_1 -> fc2_1 [style="dotted" constraint=false]

}
48 changes: 48 additions & 0 deletions doc_cn/algorithm/rnn/glossary_rnn_with_memory.dot
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
digraph G{
subgraph cluster_timestep0 {
label="recurrent timestep i-1"
bgcolor=lightgray
node [style=filled,color=white]
fc0_0 [label="fc 0"]
fc0_1 [label="fc 1"]
fc0_2 [label="fc 2"]
m0 [label="memory"]
fc0_0 -> fc0_1
fc0_1 -> fc0_2
fc0_1 -> m0
m0 -> fc0_1
}

subgraph cluster_timestep1 {
label="recurrent timestep i"
node [style=filled];
fc1_0 [label="fc 0"]
fc1_1 [label="fc 1"]
fc1_2 [label="fc 2"]
m1 [label="memory"]
color=blue
fc1_0 -> fc1_1
fc1_1 -> fc1_2
fc1_1 -> m1
m1 -> fc1_1
}

subgraph cluster_timestep2 {
label="recurrent timestep i+1"
bgcolor=lightgray
node [style=filled,color=white]
fc2_0 [label="fc 0"]
fc2_1 [label="fc 1"]
fc2_2 [label="fc 2"]
m2 [label="memory"]
fc2_0 -> fc2_1
fc2_1 -> fc2_2
fc2_1 -> m2
m2 -> fc2_1
}


m0 -> m1 [style="dotted" constraint=false]
m1 -> m2 [style="dotted" constraint=false]

}
403 changes: 0 additions & 403 deletions doc_cn/algorithm/rnn/hierarchical-rnn.md

This file was deleted.

7 changes: 7 additions & 0 deletions doc_cn/algorithm/rnn/hrnn_demo.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.. _algo_hrnn_demo:

#################
双层RNN的使用示例
#################

TBD
218 changes: 218 additions & 0 deletions doc_cn/algorithm/rnn/hrnn_rnn_api_compare.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
.. _algo_hrnn_rnn_api_compare:

#####################
单双层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>`_\ 。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 本文以PaddlePaddle的\ :ref:glossary_双层RNN\ 单元测试为示例,用多对效果完全相同的、分别使用单双层RNN作为网络配置的模型...
  2. 文章中示例所使用的单元测试->本文示例所使用的单元测试。因为这段话都用本文,所以可以统一

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.


示例1:双层RNN,子序列间无Memory
================================

在\ :ref:`glossary_双层RNN`\ 中的经典情况是将内层的每一个\ :ref:`glossary_sequence`\ 数据,分别进行序列操作。并且内层的序列操作之间是独立没有依赖的,即不需要使用\ :ref:`glossary_Memory`\ 的。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

双层RNN中的经典情况是:将内层的每一个\ :ref:glossary_sequence\ 数据,分别进行序列操作;并且内层的序列操作之间独立无依赖,即不需要使用\ :ref:glossary_Memory\。


在本问题中,单层\ :ref:`glossary_RNN`\ 和\ :ref:`glossary_双层RNN`\ 的网络配置,都是将每一句分好词后的句子,使用LSTM作为encoder,压缩成一个向量。区别是\ :ref:`glossary_RNN`\ 使用两层序列模型,将多句话看成一个整体,同时使用encoder压缩,二者语意上完全一致。这组语意相同的示例配置如下
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

在本问题中->本示例中

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.


* 单层\ :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>`_


读取双层序列数据
----------------

首先,本示例中使用的原始数据如下\:

- 本里中的原始数据一共有10个样本。每个样本由两部分组成,一个label(此处都为2)和一个已经分词后的句子。这个数据也被单层\ :ref:`glossary_RNN`\ 网络直接使用。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

本例中的

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.


.. literalinclude:: ../../../paddle/gserver/tests/Sequence/tour_train_wdseg
:language: text


- 双层序列数据一共有4个样本。 每个样本间用空行分开,整体数据和原始数据完全一样。而对于双层序列的LSTM来说,第一条数据同时encode两条数据成两个向量。这四条数据同时处理的句子为\ :code:`[2, 3, 2, 3]`\ 。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 但于双层序列的LSTM来说,第一个样本同时encode两条数据成两个向量?
  2. 这四条数据同时处理的句子为\ :code:[2, 3, 2, 3]\ 。这句话是什么意思呢?


.. literalinclude:: ../../../paddle/gserver/tests/Sequence/tour_train_wdseg.nest
:language: text

其次,对于两种不同的输入数据类型,不同\ :ref:`glossary_DataProvider`\ 对比如下(`sequenceGen.py <https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/gserver/tests/sequenceGen.py>`_)\:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

链接现在连得是develop分支,但文档不一定固定在develop分支。别的分支会和这儿有区别,所以可以不放么

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不可以


.. literalinclude:: ../../../paddle/gserver/tests/sequenceGen.py
:language: python
:lines: 21-39
:linenos:

- 这是普通的单层\ :ref:`glossary_sequence`\ 的\ :ref:`glossary_DataProvider`\ 代码,其说明如下:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

普通的单层时间序列的dataprovider共返回两个数据,分别是words和label(即上述代码的最后一行)。具体说明如下:

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这一块还是拆开说比较清楚。


* :ref:`glossary_DataProvider`\ 共返回两个数据,分别是words和label。即上述代码中的第19行。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这一行移到43行了,因为46行和47行是它的两个小点。下同

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这一块还是拆开说比较清楚。

- words是原始数据中的每一句话,所对应的词表index数组。它是integer_value_sequence类型的,即整数数组。words即为这个数据中的单层\ :ref:`glossary_sequence`\ 。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

words是原始数据中的每一句话所对应的词表索引数组。它是integer_value_sequence类型的,即单层时间序列。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

integer_value_sequence => 整数数组 => 单层时间序列

这三者是有逻辑推进的。

因为,不是所有的单层时间序列,都是整数数组。

- label是原始数据中对于每一句话的分类标签,它是integer_value类型的。

.. literalinclude:: ../../../paddle/gserver/tests/sequenceGen.py
:language: python
:lines: 42-71
:linenos:

- 这是对于同样的数据,本示例中双层\ :ref:`glossary_sequence`\ 的\ :ref:`glossary_DataProvider`\ 代码,其说明如下:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

对于同样的数据,双层时间序列的dataprovider代码返回的是两组数据,分别是sentences和labels,即双层序列的原始数据中每一组内的所有句子和对应的标签。具体说明如下:


- :ref:`glossary_DataProvider`\ 共返回两组数据,分别是sentences和labels。即在双层序列的原始数据中,每一组内的所有句子和labels
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

56行移到了54行中了

- sentences是双层\ :ref:`glossary_sequence`\ 的数据。他内部包括了每组数据中的所有句子,又使用句子中每一个单词的词表index表示每一个句子,故为双层\ :ref:`glossary_sequence`\ 。类型为 integer_value_sub_sequence 。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

由于它内部包含了每组数据中的所有句子,且每个句子表示为对应的词表索引数组,因此它是integer_value_sub_sequence 类型的,即双层时间序列。

- labels是每组内每一个句子的标签,故而是一个单层\ :ref:`glossary_sequence`\ 。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

labels是每组内每个句子的标签,因此是单层时间序列。



:ref:`glossary_trainer_config`\ 的模型配置
------------------------------------------

首先,我们看一下单层\ :ref:`glossary_RNN`\ 的配置。代码中9-15行即为单层RNN序列的使用代码。这里使用了PaddlePaddle预定义好的\ :ref:`glossary_RNN`\ 处理函数。在这个函数中,\ :ref:`glossary_RNN`\ 对于每一个\ :ref:`glossary_timestep`\ 通过了一个LSTM网络。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

代码中高亮部分即为单层RNN序列的使用代码。


.. literalinclude:: ../../../paddle/gserver/tests/sequence_layer_group.conf
:language: python
:lines: 38-63
:linenos:
:emphasize-lines: 9-15


其次,我们看一下语义相同的\ :ref:`glossary_双层RNN`\ 的网络配置。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

73行,句号改成冒号


* PaddlePaddle中的许多layer并不在意输入是否是\ :ref:`glossary_sequence`\ ,例如\ :code:`embedding_layer`\ 。在这些layer中,所有的操作都是针对每一个\ :ref:`glossary_timestep`\ 来进行的。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PaddlePaddle中的很多layer并不在意输入是否是时间序列 ,例如 embedding_layer 等。这些layer的操作都是对所有时间步统一进行的。

embedding_layer 这种写法,可以在markdown中正确显示,但\ :code:embedding_layer\写法就不行。建议可以换掉。下同

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

没必要换掉,我们用的就是rst,rst里面支持的inline code写法是 :code:


* 在该配置中,7-26行将双层\ :ref:`glossary_sequence`\ 数据,先变换成单层\ :ref:`glossary_sequence`\ 数据,在对每一个单层\ :ref:`glossary_sequence`\ 进行处理。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

该配置的高亮部分,将双层时间序列数据先变换成单层,再对每一个单层时间序列进行处理。


* 使用\ :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`\ 。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

只需要使用LSTM压缩成的最后一个向量,所以对 recurrent_group 进行了 last_seq操作;但和单层RNN不同,我们是对每一个子序列取最后一个元素,因此设置agg_level=AggregateLevel.EACH_SEQUENCE


* 至此,\ :code:`lstm_last`\ 便和单层\ :ref:`glossary_RNN`\ 的配置中的\ :code:`lstm_last`\ 具有相同的结果了。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

至此,lstm_last 便和单层RNN配置中的 lstm_last 具有相同的结果了。


.. literalinclude:: ../../../paddle/gserver/tests/sequence_nest_layer_group.conf
:language: python
:lines: 38-64
:linenos:
:emphasize-lines: 7-26

示例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]]`。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

示例2中,通过分别使用单层RNN和双层RNN,实现了两个完全等价的全连接RNN。

  • 对于单层RNN,输入数据为一个完整的时间序列,例如[4, 5, 2, 0, 9, 8, 1, 4]。
  • 对于双层RNN,将单层RNN的数据,按顺序组合成任意长度的双层时间序列,例如[ [4, 5, 2], [0, 9], [8, 1, 4]]。


:ref:`glossary_trainer_config`\ 的模型配置
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:ref:glossary_trainer_config\,词汇表中没有这个

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

在use_concept.rst中

------------------------------------------

我们选取单双层序列配置中的不同部分,来对比分析两者语义相同的原因。

- 单层序列:过了一个很简单的recurrent_group。每一个时间步,当前的输入y和上一个时间步的输出rnn_state做了一个全链接。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

单层RNN:过了一个很简单的recurrent_group。每一个时间步内,当前的输入y和上一个时间步的输出rnn_state做了一个全连接。


.. literalinclude:: ../../../paddle/gserver/tests/sequence_rnn.conf
:language: python
:lines: 36-48

- 双层序列,外层memory是一个元素:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

双层RNN


- 内层inner_step的recurrent_group和单层序列的几乎一样。除了boot_layer=outer_mem,表示将外层的outer_mem作为内层memory的初始状态。外层outer_step中,outer_mem是一个子句的最后一个向量,即整个双层group是将前一个子句的最后一个向量,作为下一个子句memory的初始状态。
- 从输入数据上看,单双层序列的句子是一样的,只是双层序列将其又做了子序列划分。因此双层序列的配置中,必须将前一个子句的最后一个元素,作为boot_layer传给下一个子句的memory,才能保证和单层序列的配置中“每一个时间步都用了上一个时间步的输出结果”一致。

.. literalinclude:: ../../../paddle/gserver/tests/sequence_nest_rnn.conf
:language: python
:lines: 39-66

.. warning::
PaddlePaddle目前只支持在每一个时间步中,Memory的sequence长度一致的情况。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PaddlePaddle目前只支持在每个时间步中,memory的序列长度都一致的情况。


示例3:双层RNN,输入不等长
==========================

.. role:: red

.. raw:: html

<style> .red {color:red} </style>

**输入不等长** 是指recurrent_group的多个输入序列,在每个\ :ref:`glossary_timestep`\ 的子序列长度可以不相等。但\ :ref:`glossary_双层RNN`\ 目前需要整体的输出,与某一个输入的序列信息是一致的。使用\ :red:`targetInlink`\ 可以指定和输出序列信息一致。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

但输出序列时,需要指定与哪一个输入的序列信息是一致的。\ :red:targetInlink\ 关键词用来指定哪一个输入,默认指定第1个输入。

因为单层也可以不等长,所以“但\ :ref:glossary_双层RNN\ 目前需要整体的输出,与某一个输入的序列信息是一致的。”没考虑单层的情景。


本例参考配置分别为\ `单层不等长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>`_\ 。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

示例3的参考。。。


本例中对于单层\ :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`\ 。即两个特征,均有三个子序列。每个子序列长度可以不一致,但是子序列的数目必须一样。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

示例3中,单层RNN和双层RNN数据完全相同:

  • 单层RNN的数据一共有两个样本,分别是[1, 2, 4, 5, 2], [5, 4, 1, 3, 1]和[0, 2, 2, 5, 0, 1, 2], [1, 5, 4, 2, 3, 6, 1]。即每一个样本均有两个特征。
  • 双层RNN的数据,是在单层数据的基础上随意加了一些隔断。例如将第二条样本转化为[[0, 2], [2, 5], [0, 1, 2]],[[1, 5], [4], [2, 3, 6, 1]]。即每个特征又包含了三个子序列。
  • 注意:对多输入双层RNN的不同序列来说,每个子序列长度可以不一致,但是子序列的数目必须一样。



:ref:`glossary_trainer_config`\ 的模型配置
------------------------------------------

本例中的配置,使用了单层\ :ref:`glossary_RNN`\ 和\ :ref:`glossary_双层RNN`\ 使用一个\ :code:`recurrent_group`\ 将两个序列同时过完全连接的\ :ref:`glossary_RNN`\ 。对于单层\ :ref:`glossary_RNN`\ 的code如下。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同示例二类似,示例三也是通过分别使用单层RNN和双层RNN,实现两个完全等价的全连接RNN。

  • 单层RNN
    ....
  • 双层RNN
    ....

描述格式同示例二的列表相同。将154行分开放到两个列表中。:code:emb2后面要加一个空格,未显示正确


.. literalinclude:: ../../../paddle/gserver/tests/sequence_rnn_multi_unequalength_inputs.py
:language: python
:lines: 42-59
:linenos:

而双层序列的代码如下。

.. 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`的序列形状一致。

示例4:beam_search的生成
========================

TBD


词汇表
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

词汇表等下一个PR,统一再修改。

======

.. _glossary_memory:

Memory
------

Memory是PaddlePaddle实现 :ref:`glossary_RNN` 时候使用的一个概念。 :ref:`glossary_RNN` 即时间递归神经网络,通常要求时间步之间具有一些依赖性,即当前时间步下的神经网络依赖前一个时间步神经网络中某一个神经元输出。如下图所示。

.. graphviz:: glossary_rnn.dot

上图中虚线的连接,即是跨越时间步的网络连接。PaddlePaddle在实现 :ref:`glossary_RNN` 的时候,将这种跨越时间步的连接用一个特殊的神经网络单元实现。这个神经网络单元就叫Memory。Memory可以缓存上一个时刻某一个神经元的输出,然后在下一个时间步输入给另一个神经元。使用Memory的 :ref:`glossary_RNN` 实现便如下图所示。

.. graphviz:: glossary_rnn_with_memory.dot

使用这种方式,PaddlePaddle可以比较简单的判断哪些输出是应该跨越时间步的,哪些不是。

.. _glossary_timestep:

时间步
------

参考 :ref:`glossary_sequence` 。


.. _glossary_sequence:

时间序列
--------

时间序列(time series)是指一系列的特征数据。这些特征数据之间的顺序是有意义的。即特征的数组,而不是特征的集合。而这每一个数组元素,或者每一个系列里的特征数据,即为一个时间步(time step)。值得注意的是,时间序列、时间步的概念,并不真正的和『时间』有关。只要一系列特征数据中的『顺序』是有意义的,即为时间序列的输入。

举例说明,例如文本分类中,我们通常将一句话理解成一个时间序列。比如一句话中的每一个单词,会变成词表中的位置。而这一句话就可以表示成这些位置的数组。例如 :code:`[9, 2, 3, 5, 3]` 。

关于时间序列(time series)的更详细准确的定义,可以参考 `维基百科页面 Time series <https://en.wikipedia.org/wiki/Time_series>`_ 或者 `维基百科中文页面 时间序列 <https://zh.wikipedia.org/wiki/%E6%99%82%E9%96%93%E5%BA%8F%E5%88%97>`_ 。

另外,Paddle中经常会将时间序列成为 :code:`Sequence` 。他们在Paddle的文档和API中是一个概念。

.. _glossary_RNN:

RNN
---

RNN 在PaddlePaddle的文档中,一般表示 :code:`Recurrent neural network`,即时间递归神经网络。详细介绍可以参考 `维基百科页面 Recurrent neural network <https://en.wikipedia.org/wiki/Recurrent_neural_network>`_ 或者 `中文维基百科页面 <https://zh.wikipedia.org/wiki/%E9%80%92%E5%BD%92%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C>`_ 中关于时间递归神经网络的介绍。

RNN 一般在PaddlePaddle中,指对于一个 :ref:`glossary_sequence` 输入数据,每一个时间步之间的神经网络具有一定的相关性。例如,某一个神经元的一个输入为上一个时间步网络中某一个神经元的输出。或者,从每一个时间步来看,神经网络的网络结构中具有有向环结构。

.. _glossary_双层RNN:

双层RNN
-------

双层RNN顾名思义,即 :ref:`glossary_RNN` 之间有一次嵌套关系。输入数据整体上是一个时间序列,而对于每一个内层特征数据而言,也是一个时间序列。即二维数组,或者数组的数组这个概念。 而双层RNN是可以处理这种输入数据的网络结构。

例如,对于段落的文本分类,即将一段话进行分类。我们将一段话看成句子的数组,每个句子又是单词的数组。这便是一种双层RNN的输入数据。而将这个段落的每一句话用lstm编码成一个向量,再对每一句话的编码向量用lstm编码成一个段落的向量。再对这个段落向量进行分类,即为这个双层RNN的网络结构。

30 changes: 30 additions & 0 deletions doc_cn/algorithm/rnn/simple_full_hierarchical_recurrent.dot
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
digraph G {
rankdir=LR;

subgraph cluster_t0 {
a [label="4"]
b [label="5"]
c [label="2"]
}

subgraph cluster_t1 {
d [label="0"]
e [label="9"]
}

subgraph cluster_t2 {
f [label="8"]
g [label="1"]
h [label="4"]
}

a -> b;
b -> c;
c -> d [constraint=false];

d -> e;
e -> f [constraint=false];

f -> g;
g -> h;
}
19 changes: 19 additions & 0 deletions doc_cn/algorithm/rnn/simple_full_recurrent.dot
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
digraph G {
rankdir=LR;
a [label="4"]
b [label="5"]
c [label="2"]
d [label="0"]
e [label="9"]
f [label="8"]
g [label="1"]
h [label="4"]

a -> b;
b -> c;
c -> d;
d -> e;
e -> f;
f -> g;
g -> h;
}
2 changes: 2 additions & 0 deletions doc_cn/concepts/use_concepts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ PaddlePaddle进程内嵌了一个 :code:`python` 解释器。 这个 :code:`pyth

所以,PaddlePaddle单机训练进程,:code:`paddle train` , 对于用户的主要接口语言为 python。 主要需要用户配置的两个文件为 :code:`DataProvider` 和训练文件 :code:`TrainerConfig` 。

.. _glossary_DataProvider:

DataProvider
============
Expand All @@ -42,6 +43,7 @@ DataProvider是 :code:`paddle train` 的数据提供器。 它负责将用户的

为了方便用户使用自己的数据格式, PaddlePaddle 提供了 `PyDataProvider`_ 来处理数据。 并且在这个Provider中,PaddlePaddle的 C++ 部分接管了如何shuffle,处理 batch,GPU/CPU通信,双缓冲,异步读取等问题。 用户可以参考 `PyDataProvider`_ 的相关文档,继续深入了解 DataProvider 的使用。

.. _glossary_trainer_config:

训练文件
========
Expand Down
2 changes: 1 addition & 1 deletion doc_cn/conf.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ master_doc = 'index'
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
language = 'zh_CN'

# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
Expand Down
Loading