Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Crayon鑫
Paddle
提交
e0323804
P
Paddle
项目概览
Crayon鑫
/
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看板
提交
e0323804
编写于
10月 14, 2016
作者:
T
Travis CI
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Deploy to GitHub Pages:
cebdb667
上级
37435efc
变更
14
展开全部
隐藏空白更改
内联
并排
Showing
14 changed file
with
1312 addition
and
4 deletion
+1312
-4
doc/_sources/ui/api/trainer_config_helpers/layers.txt
doc/_sources/ui/api/trainer_config_helpers/layers.txt
+6
-0
doc/searchindex.js
doc/searchindex.js
+1
-1
doc/ui/api/trainer_config_helpers/layers.html
doc/ui/api/trainer_config_helpers/layers.html
+44
-0
doc/ui/api/trainer_config_helpers/layers_index.html
doc/ui/api/trainer_config_helpers/layers_index.html
+1
-0
doc_cn/_sources/algorithm/rnn/hierarchical-layer.txt
doc_cn/_sources/algorithm/rnn/hierarchical-layer.txt
+66
-0
doc_cn/_sources/algorithm/rnn/hierarchical-rnn.txt
doc_cn/_sources/algorithm/rnn/hierarchical-rnn.txt
+267
-0
doc_cn/_sources/algorithm/rnn/rnn-tutorial.txt
doc_cn/_sources/algorithm/rnn/rnn-tutorial.txt
+96
-0
doc_cn/_sources/index.txt
doc_cn/_sources/index.txt
+4
-1
doc_cn/algorithm/rnn/hierarchical-layer.html
doc_cn/algorithm/rnn/hierarchical-layer.html
+196
-0
doc_cn/algorithm/rnn/hierarchical-rnn.html
doc_cn/algorithm/rnn/hierarchical-rnn.html
+404
-0
doc_cn/algorithm/rnn/rnn-tutorial.html
doc_cn/algorithm/rnn/rnn-tutorial.html
+222
-0
doc_cn/index.html
doc_cn/index.html
+4
-1
doc_cn/objects.inv
doc_cn/objects.inv
+0
-0
doc_cn/searchindex.js
doc_cn/searchindex.js
+1
-1
未找到文件。
doc/_sources/ui/api/trainer_config_helpers/layers.txt
浏览文件 @
e0323804
...
...
@@ -130,6 +130,12 @@ gru_step_layer
Recurrent Layer Group
=====================
memory
------
.. automodule:: paddle.trainer_config_helpers.layers
:members: memory
:noindex:
recurrent_group
---------------
.. automodule:: paddle.trainer_config_helpers.layers
...
...
doc/searchindex.js
浏览文件 @
e0323804
此差异已折叠。
点击以展开。
doc/ui/api/trainer_config_helpers/layers.html
浏览文件 @
e0323804
...
...
@@ -901,6 +901,49 @@ will get a warning.</li>
</div>
<div
class=
"section"
id=
"recurrent-layer-group"
>
<h1>
Recurrent Layer Group
<a
class=
"headerlink"
href=
"#recurrent-layer-group"
title=
"Permalink to this headline"
>
¶
</a></h1>
<div
class=
"section"
id=
"memory"
>
<h2>
memory
<a
class=
"headerlink"
href=
"#memory"
title=
"Permalink to this headline"
>
¶
</a></h2>
<dl
class=
"function"
>
<dt>
<code
class=
"descclassname"
>
paddle.trainer_config_helpers.layers.
</code><code
class=
"descname"
>
memory
</code><span
class=
"sig-paren"
>
(
</span><em>
name
</em>
,
<em>
size
</em>
,
<em>
is_seq=False
</em>
,
<em>
boot_layer=None
</em>
,
<em>
boot_bias=None
</em>
,
<em>
boot_bias_active_type=None
</em>
,
<em>
boot_with_const_id=None
</em><span
class=
"sig-paren"
>
)
</span></dt>
<dd><p>
The memory layers is a layer cross each time step. Reference this output
as previous time step layer
<code
class=
"code docutils literal"
><span
class=
"pre"
>
name
</span></code>
‘
s output.
</p>
<p>
The default memory is zero in first time step, previous time step
’
s
output in the rest time steps.
</p>
<p>
If boot_bias, the first time step value is this bias and
with activation.
</p>
<p>
If boot_with_const_id, then the first time stop is a IndexSlot, the
Arguments.ids()[0] is this
<code
class=
"code docutils literal"
><span
class=
"pre"
>
cost_id
</span></code>
.
</p>
<p>
If boot_layer is not null, the memory is just the boot_layer
’
s output.
Set
<code
class=
"code docutils literal"
><span
class=
"pre"
>
is_seq
</span></code>
is true boot layer is sequence.
</p>
<p>
The same name layer in recurrent group will set memory on each time
step.
</p>
<table
class=
"docutils field-list"
frame=
"void"
rules=
"none"
>
<col
class=
"field-name"
/>
<col
class=
"field-body"
/>
<tbody
valign=
"top"
>
<tr
class=
"field-odd field"
><th
class=
"field-name"
>
Parameters:
</th><td
class=
"field-body"
><ul
class=
"first simple"
>
<li><strong>
name
</strong>
(
<em>
basestring
</em>
)
–
memory
’
s name.
</li>
<li><strong>
size
</strong>
(
<em>
int
</em>
)
–
size of memory.
</li>
<li><strong>
is_seq
</strong>
(
<em>
bool
</em>
)
–
is sequence for boot_layer
</li>
<li><strong>
boot_layer
</strong>
(
<em>
LayerOutput|None
</em>
)
–
boot layer of memory.
</li>
<li><strong>
boot_bias
</strong>
(
<em>
ParameterAttribute|None
</em>
)
–
boot layer
’
s bias
</li>
<li><strong>
boot_bias_active_type
</strong>
(
<em>
BaseActivation
</em>
)
–
boot layer
’
s active type.
</li>
<li><strong>
boot_with_const_id
</strong>
(
<em>
int
</em>
)
–
boot layer
’
s id.
</li>
</ul>
</td>
</tr>
<tr
class=
"field-even field"
><th
class=
"field-name"
>
Returns:
</th><td
class=
"field-body"
><p
class=
"first"
>
LayerOutput object which is a memory.
</p>
</td>
</tr>
<tr
class=
"field-odd field"
><th
class=
"field-name"
>
Return type:
</th><td
class=
"field-body"
><p
class=
"first last"
>
LayerOutput
</p>
</td>
</tr>
</tbody>
</table>
</dd></dl>
</div>
<div
class=
"section"
id=
"recurrent-group"
>
<h2>
recurrent_group
<a
class=
"headerlink"
href=
"#recurrent-group"
title=
"Permalink to this headline"
>
¶
</a></h2>
<dl
class=
"function"
>
...
...
@@ -2647,6 +2690,7 @@ It is used by recurrent layer group.</p>
</ul>
</li>
<li><a
class=
"reference internal"
href=
"#recurrent-layer-group"
>
Recurrent Layer Group
</a><ul>
<li><a
class=
"reference internal"
href=
"#memory"
>
memory
</a></li>
<li><a
class=
"reference internal"
href=
"#recurrent-group"
>
recurrent_group
</a></li>
<li><a
class=
"reference internal"
href=
"#beam-search"
>
beam_search
</a></li>
<li><a
class=
"reference internal"
href=
"#get-output-layer"
>
get_output_layer
</a></li>
...
...
doc/ui/api/trainer_config_helpers/layers_index.html
浏览文件 @
e0323804
...
...
@@ -114,6 +114,7 @@ var _hmt = _hmt || [];
</ul>
</li>
<li
class=
"toctree-l1"
><a
class=
"reference internal"
href=
"layers.html#recurrent-layer-group"
>
Recurrent Layer Group
</a><ul>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"layers.html#memory"
>
memory
</a></li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"layers.html#recurrent-group"
>
recurrent_group
</a></li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"layers.html#beam-search"
>
beam_search
</a></li>
<li
class=
"toctree-l2"
><a
class=
"reference internal"
href=
"layers.html#get-output-layer"
>
get_output_layer
</a></li>
...
...
doc_cn/_sources/algorithm/rnn/hierarchical-layer.txt
0 → 100644
浏览文件 @
e0323804
# 支持双层序列作为输入的Layer
## 概述
在自然语言处理任务中,序列是一种常见的数据类型。一个独立的词语,可以看作是一个非序列输入,或者,我们称之为一个0层的序列;由词语构成的句子,是一个单层序列;若干个句子构成一个段落,是一个双层的序列。
双层序列是一个嵌套的序列,它的每一个元素,又是一个单层的序列。这是一种非常灵活的数据组织方式,帮助我们构造一些复杂的输入信息。
我们可以按照如下层次定义非序列,单层序列,以及双层序列。
+ 0层序列:一个独立的元素,类型可以是PaddlePaddle支持的任意输入数据类型
+ 单层序列:排成一列的多个元素,每个元素是一个0层序列,元素之间的顺序是重要的输入信息
+ 双层序列:排成一列的多个元素,每个元素是一个单层序列,称之为双层序列的一个子序列(subseq),subseq的每个元素是一个0层序列
在 PaddlePaddle中,下面这些Layer能够接受双层序列作为输入,完成相应的计算。
## pooling_layer
pooling_layer的使用示例如下,详细见<a href = "../../../doc/ui/api/trainer_config_helpers/layers.html#pooling-layer">配置API</a>。
```python
seq_pool = pooling_layer(input=layer,
pooling_type=AvgPooling(),
agg_level=AggregateLevel.EACH_SEQUENCE)
```
- `pooling_type` 目前支持两种,分别是:MaxPooling()和AvgPooling()。
- `agg_level=AggregateLevel.TIMESTEP`时(默认值):
- 作用:双层序列经过运算变成一个0层序列,或单层序列经过运算变成一个0层序列
- 输入:一个双层序列,或一个单层序列
- 输出:一个0层序列,即整个输入序列(单层或双层)的平均值(或最大值)
- `agg_level=AggregateLevel.EACH_SEQUENCE`时:
- 作用:一个双层序列经过运算变成一个单层序列
- 输入:必须是一个双层序列
- 输出:一个单层序列,序列的每个元素是原来双层序列每个subseq元素的平均值(或最大值)
## last_seq 和 first_seq
last_seq的使用示例如下(first_seq类似),详细见<a href = "../../../doc/ui/api/trainer_config_helpers/layers.html#last-seq">配置API</a>。
```python
last = last_seq(input=layer,
agg_level=AggregateLevel.EACH_SEQUENCE)
```
- `agg_level=AggregateLevel.TIMESTEP`时(默认值):
- 作用:一个双层序列经过运算变成一个0层序列,或一个单层序列经过运算变成一个0层序列
- 输入:一个双层序列或一个单层序列
- 输出:一个0层序列,即整个输入序列(双层或者单层)最后一个,或第一个元素。
- `agg_level=AggregateLevel.EACH_SEQUENCE`时:
- 作用:一个双层序列经过运算变成一个单层序列
- 输入:必须是一个双层序列
- 输出:一个单层序列,其中每个元素是双层序列中每个subseq最后一个(或第一个)元素。
## expand_layer
expand_layer的使用示例如下,详细见<a href = "../../../doc/ui/api/trainer_config_helpers/layers.html#expand-layer">配置API</a>。
```python
expand = expand_layer(input=layer1,
expand_as=layer2,
expand_level=ExpandLevel.FROM_TIMESTEP)
```
- `expand_level=ExpandLevel.FROM_TIMESTEP`时(默认值):
- 作用:一个0层序列经过运算扩展成一个单层序列,或者一个双层序列
- 输入:layer1必须是一个0层序列,是待扩展的数据;layer2可以是一个单层序列,或者是一个双层序列,提供扩展的长度信息
- 输出:一个单层序列,或一个双层序列,输出序列的类型(双层序列,或单层序列)和序列中含有元素的数目同 layer2一致。若输出是单层序列,单层序列的每个元素(0层序列),都是对layer1元素的拷贝;若输出是双层序列,双层序列每个subseq中每个元素(0层序列),都是对layer1元素的拷贝
- `expand_level=ExpandLevel.FROM_SEQUENCE`时:
- 作用:一个单层序列经过运算扩展成一个双层序列
- 输入:layer1必须是一个单层序列,是待扩展的数据;layer2必须是一个双层序列,提供扩展的长度信息
- 输出:一个双层序列,序列中含有元素的数目同layer2一致。要求单层序列含有元素的数目(0层序列),和双层序列含有subseq 的数目一致。单层序列第i个元素(0层序列),被扩展为一个单层序列,构成了输出双层序列的第i个subseq。
\ No newline at end of file
doc_cn/_sources/algorithm/rnn/hierarchical-rnn.txt
0 → 100644
浏览文件 @
e0323804
# 双层RNN配置与示例
我们在`paddle/gserver/tests/test_RecurrentGradientMachine`单测中,通过多组语义相同的单双层RNN配置,讲解如何使用双层RNN。
## 示例1:双进双出,subseq间无memory
配置:单层RNN(`sequence_layer_group`)和双层RNN(`sequence_nest_layer_group`),语义完全相同。
### 读取双层序列的方法
首先,我们看一下单双层序列的不同数据组织形式(您也可以采用别的组织形式):
- 单层序列的数据(`Sequence/tour_train_wdseg`)如下,一共有10个样本。每个样本由两部分组成,一个label(此处都为2)和一个已经分词后的句子。
```text
2 酒店 有 很 舒适 的 床垫 子 , 床上用品 也 应该 是 一人 一 换 , 感觉 很 利落 对 卫生 很 放心 呀 。
2 很 温馨 , 也 挺 干净 的 * 地段 不错 , 出来 就 有 全家 , 离 地铁站 也 近 , 交通 很方便 * 就是 都 不 给 刷牙 的 杯子 啊 , 就 第一天 给 了 一次性杯子 *
2 位置 方便 , 强烈推荐 , 十一 出去玩 的 时候 选 的 , 对面 就是 华润万家 , 周围 吃饭 的 也 不少 。
2 交通便利 , 吃 很 便利 , 乾 浄 、 安静 , 商务 房 有 电脑 、 上网 快 , 价格 可以 , 就 早餐 不 好吃 。 整体 是 不错 的 。 適 合 出差 來 住 。
2 本来 准备 住 两 晚 , 第 2 天 一早 居然 停电 , 且 无 通知 , 只有 口头 道歉 。 总体来说 性价比 尚可 , 房间 较 新 , 还是 推荐 .
2 这个 酒店 去过 很多 次 了 , 选择 的 主要原因 是 离 客户 最 便宜 相对 又 近 的 酒店
2 挺好 的 汉庭 , 前台 服务 很 热情 , 卫生 很 整洁 , 房间 安静 , 水温 适中 , 挺好 !
2 HowardJohnson 的 品质 , 服务 相当 好 的 一 家 五星级 。 房间 不错 、 泳池 不错 、 楼层 安排 很 合理 。 还有 就是 地理位置 , 简直 一 流 。 就 在 天一阁 、 月湖 旁边 , 离 天一广场 也 不远 。 下次 来 宁波 还会 住 。
2 酒店 很干净 , 很安静 , 很 温馨 , 服务员 服务 好 , 各方面 都 不错 *
2 挺好 的 , 就是 没 窗户 , 不过 对 得 起 这 价格
```
- 双层序列的数据(`Sequence/tour_train_wdseg.nest`)如下,一共有4个样本。样本间用空行分开,代表不同的双层序列,序列数据和上面的完全一样。每个样本的子句数分别为2,3,2,3。
```text
2 酒店 有 很 舒适 的 床垫 子 , 床上用品 也 应该 是 一人 一 换 , 感觉 很 利落 对 卫生 很 放心 呀 。
2 很 温馨 , 也 挺 干净 的 * 地段 不错 , 出来 就 有 全家 , 离 地铁站 也 近 , 交通 很方便 * 就是 都 不 给 刷牙 的 杯子 啊 , 就 第一天 给 了 一次性杯子 *
2 位置 方便 , 强烈推荐 , 十一 出去玩 的 时候 选 的 , 对面 就是 华润万家 , 周围 吃饭 的 也 不少 。
2 交通便利 , 吃 很 便利 , 乾 浄 、 安静 , 商务 房 有 电脑 、 上网 快 , 价格 可以 , 就 早餐 不 好吃 。 整体 是 不错 的 。 適 合 出差 來 住 。
2 本来 准备 住 两 晚 , 第 2 天 一早 居然 停电 , 且 无 通知 , 只有 口头 道歉 。 总体来说 性价比 尚可 , 房间 较 新 , 还是 推荐 .
2 这个 酒店 去过 很多 次 了 , 选择 的 主要原因 是 离 客户 最 便宜 相对 又 近 的 酒店
2 挺好 的 汉庭 , 前台 服务 很 热情 , 卫生 很 整洁 , 房间 安静 , 水温 适中 , 挺好 !
2 HowardJohnson 的 品质 , 服务 相当 好 的 一 家 五星级 。 房间 不错 、 泳池 不错 、 楼层 安排 很 合理 。 还有 就是 地理位置 , 简直 一 流 。 就 在 天一阁 、 月湖 旁边 , 离 天一广场 也 不远 。 下次 来 宁波 还会 住 。
2 酒店 很干净 , 很安静 , 很 温馨 , 服务员 服务 好 , 各方面 都 不错 *
2 挺好 的 , 就是 没 窗户 , 不过 对 得 起 这 价格
```
其次,我们看一下单双层序列的不同dataprovider(见`sequenceGen.py`):
- 单层序列的dataprovider如下:
- word_slot是integer_value_sequence类型,代表单层序列。
- label是integer_value类型,代表一个向量。
```python
def hook(settings, dict_file, **kwargs):
settings.word_dict = dict_file
settings.input_types = [integer_value_sequence(len(settings.word_dict)),
integer_value(3)]
@provider(init_hook=hook)
def process(settings, file_name):
with open(file_name, 'r') as fdata:
for line in fdata:
label, comment = line.strip().split('\t')
label = int(''.join(label.split()))
words = comment.split()
word_slot = [settings.word_dict[w] for w in words if w in settings.word_dict]
yield word_slot, label
```
- 双层序列的dataprovider如下:
- word_slot是integer_value_sub_sequence类型,代表双层序列。
- label是integer_value_sequence类型,代表单层序列,即一个子句一个label。注意:也可以为integer_value类型,代表一个向量,即一个句子一个label。通常根据任务需求进行不同设置。
- 关于dataprovider中input_types的详细用法,参见PyDataProvider2。
```python
def hook2(settings, dict_file, **kwargs):
settings.word_dict = dict_file
settings.input_types = [integer_value_sub_sequence(len(settings.word_dict)),
integer_value_sequence(3)]
@provider(init_hook=hook2)
def process2(settings, file_name):
with open(file_name) as fdata:
label_list = []
word_slot_list = []
for line in fdata:
if (len(line)) > 1:
label,comment = line.strip().split('\t')
label = int(''.join(label.split()))
words = comment.split()
word_slot = [settings.word_dict[w] for w in words if w in settings.word_dict]
label_list.append(label)
word_slot_list.append(word_slot)
else:
yield word_slot_list, label_list
label_list = []
word_slot_list = []
```
### 模型中的配置
首先,我们看一下单层序列的配置(见`sequence_layer_group.conf`)。注意:batchsize=5表示一次过5句单层序列,因此2个batch就可以完成1个pass。
```python
settings(batch_size=5)
data = data_layer(name="word", size=dict_dim)
emb = embedding_layer(input=data, size=word_dim)
# (lstm_input + lstm) is equal to lstmemory
with mixed_layer(size=hidden_dim*4) as lstm_input:
lstm_input += full_matrix_projection(input=emb)
lstm = lstmemory_group(input=lstm_input,
size=hidden_dim,
act=TanhActivation(),
gate_act=SigmoidActivation(),
state_act=TanhActivation(),
lstm_layer_attr=ExtraLayerAttribute(error_clipping_threshold=50))
lstm_last = last_seq(input=lstm)
with mixed_layer(size=label_dim,
act=SoftmaxActivation(),
bias_attr=True) as output:
output += full_matrix_projection(input=lstm_last)
outputs(classification_cost(input=output, label=data_layer(name="label", size=1)))
```
其次,我们看一下语义相同的双层序列配置(见`sequence_nest_layer_group.conf`),并对其详细分析:
- batchsize=2表示一次过2句双层序列。但从上面的数据格式可知,2句双层序列和5句单层序列的数据完全一样。
- data_layer和embedding_layer不关心数据是否是序列格式,因此两个配置在这两层上的输出是一样的。
- lstmemory:
- 单层序列过了一个mixed_layer和lstmemory_group。
- 双层序列在同样的mixed_layer和lstmemory_group外,直接加了一层group。由于这个外层group里面没有memory,表示subseq间不存在联系,即起到的作用仅仅是把双层seq拆成单层,因此双层序列过完lstmemory的输出和单层的一样。
- last_seq:
- 单层序列直接取了最后一个元素
- 双层序列首先(last_seq层)取了每个subseq的最后一个元素,将其拼接成一个新的单层序列;接着(expand_layer层)将其扩展成一个新的双层序列,其中第i个subseq中的所有向量均为输入的单层序列中的第i个向量;最后(average_layer层)取了每个subseq的平均值。
- 分析得出:第一个last_seq后,每个subseq的最后一个元素就等于单层序列的最后一个元素,而expand_layer和average_layer后,依然保持每个subseq最后一个元素的值不变(这两层仅是为了展示它们的用法,实际中并不需要)。因此单双层序列的输出是一样旳。
```python
settings(batch_size=2)
data = data_layer(name="word", size=dict_dim)
emb_group = embedding_layer(input=data, size=word_dim)
# (lstm_input + lstm) is equal to lstmemory
def lstm_group(lstm_group_input):
with mixed_layer(size=hidden_dim*4) as group_input:
group_input += full_matrix_projection(input=lstm_group_input)
lstm_output = lstmemory_group(input=group_input,
name="lstm_group",
size=hidden_dim,
act=TanhActivation(),
gate_act=SigmoidActivation(),
state_act=TanhActivation(),
lstm_layer_attr=ExtraLayerAttribute(error_clipping_threshold=50))
return lstm_output
lstm_nest_group = recurrent_group(input=SubsequenceInput(emb_group),
step=lstm_group,
name="lstm_nest_group")
# hasSubseq ->(seqlastins) seq
lstm_last = last_seq(input=lstm_nest_group, agg_level=AggregateLevel.EACH_SEQUENCE)
# seq ->(expand) hasSubseq
lstm_expand = expand_layer(input=lstm_last, expand_as=emb_group, expand_level=ExpandLevel.FROM_SEQUENCE)
# hasSubseq ->(average) seq
lstm_average = pooling_layer(input=lstm_expand,
pooling_type=AvgPooling(),
agg_level=AggregateLevel.EACH_SEQUENCE)
with mixed_layer(size=label_dim,
act=SoftmaxActivation(),
bias_attr=True) as output:
output += full_matrix_projection(input=lstm_average)
outputs(classification_cost(input=output, label=data_layer(name="label", size=1)))
```
## 示例2:双进双出,subseq间有memory
配置:单层RNN(`sequence_rnn.conf`),双层RNN(`sequence_nest_rnn.conf`和`sequence_nest_rnn_readonly_memory.conf`),语义完全相同。
### 读取双层序列的方法
我们看一下单双层序列的不同数据组织形式和dataprovider(见`rnn_data_provider.py`)
```python
data = [
[[[1, 3, 2], [4, 5, 2]], 0],
[[[0, 2], [2, 5], [0, 1, 2]], 1],
]
@provider(input_types=[integer_value_sub_sequence(10),
integer_value(3)])
def process_subseq(settings, file_name):
for d in data:
yield d
@provider(input_types=[integer_value_sequence(10),
integer_value(3)])
def process_seq(settings, file_name):
for d in data:
seq = []
```
- 单层序列:有两句,分别为[1,3,2,4,5,2]和[0,2,2,5,0,1,2]。
- 双层序列:有两句,分别为[[1,3,2],[4,5,2]](2个子句)和[[0,2],[2,5],[0,1,2]](3个子句)。
- 单双层序列的label都分别是0和1
### 模型中的配置
我们选取单双层序列配置中的不同部分,来对比分析两者语义相同的原因。
- 单层序列:过了一个很简单的recurrent_group。每一个时间步,当前的输入y和上一个时间步的输出rnn_state做了一个全链接。
```python
def step(y):
mem = memory(name="rnn_state", size=hidden_dim)
return fc_layer(input=[y, mem],
size=hidden_dim,
act=TanhActivation(),
bias_attr=True,
name="rnn_state")
out = recurrent_group(step=step, input=emb)
```
- 双层序列,外层memory是一个元素:
- 内层inner_step的recurrent_group和单层序列的几乎一样。除了boot_layer=outer_mem,表示将外层的outer_mem作为内层memory的初始状态。外层outer_step中,outer_mem是一个子句的最后一个向量,即整个双层group是将前一个子句的最后一个向量,作为下一个子句memory的初始状态。
- 从输入数据上看,单双层序列的句子是一样的,只是双层序列将其又做了子序列划分。因此双层序列的配置中,必须将前一个子句的最后一个元素,作为boot_layer传给下一个子句的memory,才能保证和单层序列的配置中“每一个时间步都用了上一个时间步的输出结果”一致。
```python
def outer_step(x):
outer_mem = memory(name="outer_rnn_state", size=hidden_dim)
def inner_step(y):
inner_mem = memory(name="inner_rnn_state",
size=hidden_dim,
boot_layer=outer_mem)
return fc_layer(input=[y, inner_mem],
size=hidden_dim,
act=TanhActivation(),
bias_attr=True,
name="inner_rnn_state")
inner_rnn_output = recurrent_group(
step=inner_step,
input=x)
last = last_seq(input=inner_rnn_output, name="outer_rnn_state")
return inner_rnn_output
out = recurrent_group(step=outer_step, input=SubsequenceInput(emb))
```
- 双层序列,外层memory是单层序列:
- 由于外层每个时间步返回的是一个子句,这些子句的长度往往不等长。因此当外层有is_seq=True的memory时,内层是**无法直接使用**它的,即内层memory的boot_layer不能链接外层的这个memory。
- 如果内层memory想**间接使用**这个外层memory,只能通过`pooling_layer`、`last_seq`或`first_seq`这三个layer将它先变成一个元素。但这种情况下,外层memory必须有boot_layer,否则在第0个时间步时,由于外层memory没有任何seq信息,因此上述三个layer的前向会报出“**Check failed: input.sequenceStartPositions**”的错误。
## 示例3:双进双出,输入不等长
TBD
## 示例4:beam_search的生成
TBD
\ No newline at end of file
doc_cn/_sources/algorithm/rnn/rnn-tutorial.txt
0 → 100644
浏览文件 @
e0323804
# Recurrent Group教程
## 概述
序列数据是自然语言处理任务面对的一种主要输入数据类型。
一句话是由词语构成的序列,多句话进一步构成了段落。因此,段落可以看作是一个嵌套的双层的序列,这个序列的每个元素又是一个序列。
双层序列是PaddlePaddle支持的一种非常灵活的数据组织方式,帮助我们更好地描述段落、多轮对话等更为复杂的语言数据。基于双层序列输入,我们可以设计搭建一个灵活的、层次化的RNN,分别从词语和句子级别编码输入数据,同时也能够引入更加复杂的记忆机制,更好地完成一些复杂的语言理解任务。
在PaddlePaddle中,`recurrent_group`是一种任意复杂的RNN单元,用户只需定义RNN在一个时间步内完成的计算,PaddlePaddle负责完成信息和误差在时间序列上的传播。
更进一步,`recurrent_group`同样可以扩展到双层序列的处理上。通过两个嵌套的`recurrent_group`分别定义子句级别和词语级别上需要完成的运算,最终实现一个层次化的复杂RNN。
目前,在PaddlePaddle中,能够对双向序列进行处理的有`recurrent_group`和部分Layer,具体可参考文档:<a href = "hierarchical-layer.html">支持双层序列作为输入的Layer</a>。
## 相关概念
### 基本原理
`recurrent_group` 是PaddlePaddle支持的一种任意复杂的RNN单元。使用者只需要关注于设计RNN在一个时间步之内完成的计算,PaddlePaddle负责完成信息和梯度在时间序列上的传播。
PaddlePaddle中,`recurrent_group`的一个简单调用如下:
``` python
recurrent_group(step, input, reverse)
```
- step:一个可调用的函数,定义一个时间步之内RNN单元完成的计算
- input:输入,必须是一个单层序列,或者一个双层序列
- reverse:是否以逆序处理输入序列
使用`recurrent_group`的核心是设计step函数的计算逻辑。step函数内部可以自由组合PaddlePaddle支持的各种layer,完成任意的运算逻辑。`recurrent_group` 的输入(即input)会成为step函数的输入,由于step 函数只关注于RNN一个时间步之内的计算,在这里`recurrent_group`替我们完成了原始输入数据的拆分。
### 输入
`recurrent_group`处理的输入序列主要分为以下三种类型:
- **数据输入**:一个双层序列进入`recurrent_group`会被拆解为一个单层序列,一个单层序列进入`recurrent_group`会被拆解为非序列,然后交给step函数,这一过程对用户是完全透明的。可以有以下两种:1)通过data_layer拿到的用户输入;2)其它layer的输出。
- **只读Memory输入**:`StaticInput` 定义了一个只读的Memory,由`StaticInput`指定的输入不会被`recurrent_group`拆解,`recurrent_group` 循环展开的每个时间步总是能够引用所有输入,可以是一个非序列,或者一个单层序列。
- **序列生成任务的输入**:`GeneratedInput`只用于在序列生成任务中指定输入数据。
### 输入示例
序列生成任务大多遵循encoder-decoer架构,encoder和decoder可以是能够处理序列的任意神经网络单元,而RNN是最流行的选择。
给定encoder输出和当前词,decoder每次预测产生下一个最可能的词语。在这种结构中,decoder接受两个输入:
- 要生成的目标序列:是decoder的数据输入,也是decoder循环展开的依据,`recurrent_group`会对这类输入进行拆解。
- encoder输出,可以是一个非序列,或者一个单层序列:是一个unbounded memory,decoder循环展开的每一个时间步会引用全部结果,不应该被拆解,这种类型的输入必须通过`StaticInput`指定。关于Unbounded Memory的更多讨论请参考论文 [Neural Turning Machine](https://arxiv.org/abs/1410.5401)。
在序列生成任务中,decoder RNN总是引用上一时刻预测出的词的词向量,作为当前时刻输入。`GeneratedInput`自动完成这一过程。
### 输出
`step`函数必须返回一个或多个Layer的输出,这个Layer的输出会作为整个`recurrent_group` 最终的输出结果。在输出的过程中,`recurrent_group` 会将每个时间步的输出拼接,这个过程对用户也是透明的。
### memory
memory只能在`recurrent_group`中定义和使用。memory不能独立存在,必须指向一个PaddlePaddle定义的Layer。引用memory得到这layer上一时刻输出,因此,可以将memory理解为一个时延操作。
可以显示地指定一个layer的输出用于初始化memory。不指定时,memory默认初始化为0。
## 双层RNN介绍
`recurrent_group`帮助我们完成对输入序列的拆分,对输出的合并,以及计算逻辑在序列上的循环展开。
利用这种特性,两个嵌套的`recurrent_group`能够处理双层序列,实现词语和句子两个级别的双层RNN结构。
- 单层(word-level)RNN:每个状态(state)对应一个词(word)。
- 双层(sequence-level)RNN:一个双层RNN由多个单层RNN组成,每个单层RNN(即双层RNN的每个状态)对应一个子句(subseq)。
为了描述方便,下文以NLP任务为例,将含有子句(subseq)的段落定义为一个双层序列,将含有词语的句子定义为一个单层序列,那么0层序列即为一个词语。
## 双层RNN的使用
### 训练流程的使用方法
使用 `recurrent_group`需要遵循以下约定:
- **单进单出**:输入和输出都是单层序列。
- 如果有多个输入,不同输入序列含有的词语数必须严格相等。
- 输出一个单层序列,输出序列的词语数和输入序列一致。
- memory:在step函数中定义 memory指向一个layer,通过引用memory得到这个layer上一个时刻输出,形成recurrent 连接。memory的is_seq参数必须为false。如果没有定义memory,每个时间步之内的运算是独立的。
- boot_layer:memory的初始状态,默认初始状为0,memory的is_seq参数必须为false。
- **双进双出**:输入和输出都是双层序列。
- 如果有多个输入序列,不同输入含有的子句(subseq)数必须严格相等,但子句含有的词语数可以不相等。
- 输出一个双层序列,子句(subseq)数、子句的单词数和指定的一个输入序列一致,默认为第一个输入。
- memory:在step函数中定义memory,指向一个layer,通过引用memory得到这个layer上一个时刻的输出,形成recurrent连接。定义在外层`recurrent_group` step函数中的memory,能够记录上一个subseq 的状态,可以是一个单层序列(只作为read-only memory),也可以是一个词语。如果没有定义memory,那么 subseq 之间的运算是独立的。
- boot_layer:memory 初始状态,可以是一个单层序列(只作为read-only memory)或一个向量。默认不设置,即初始状态为0。
- **双进单出**:目前还未支持,会报错"In hierachical RNN, all out links should be from sequences now"。
### 生成流程的使用方法
使用`beam_search`需要遵循以下约定:
- 单层RNN:从一个word生成下一个word。
- 双层RNN:即把单层RNN生成后的subseq给拼接成一个新的双层seq。从语义上看,也不存在一个subseq直接生成下一个subseq的情况。
\ No newline at end of file
doc_cn/_sources/index.txt
浏览文件 @
e0323804
...
...
@@ -16,4 +16,7 @@ PaddlePaddle文档
算法教程
--------
* `RNN配置 <../doc/algorithm/rnn/rnn.html>`_
* `Recurrent Group教程 <algorithm/rnn/rnn-tutorial.html>`_
* `单层RNN示例 <../doc/algorithm/rnn/rnn.html>`_
* `双层RNN示例 <algorithm/rnn/hierarchical-rnn.html>`_
* `支持双层序列作为输入的Layer <algorithm/rnn/hierarchical-layer.html>`_
doc_cn/algorithm/rnn/hierarchical-layer.html
0 → 100644
浏览文件 @
e0323804
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
xmlns=
"http://www.w3.org/1999/xhtml"
>
<head>
<meta
http-equiv=
"Content-Type"
content=
"text/html; charset=utf-8"
/>
<title>
支持双层序列作为输入的Layer
—
PaddlePaddle documentation
</title>
<link
rel=
"stylesheet"
href=
"../../_static/classic.css"
type=
"text/css"
/>
<link
rel=
"stylesheet"
href=
"../../_static/pygments.css"
type=
"text/css"
/>
<script
type=
"text/javascript"
>
var
DOCUMENTATION_OPTIONS
=
{
URL_ROOT
:
'
../../
'
,
VERSION
:
''
,
COLLAPSE_INDEX
:
false
,
FILE_SUFFIX
:
'
.html
'
,
HAS_SOURCE
:
true
};
</script>
<script
type=
"text/javascript"
src=
"../../_static/jquery.js"
></script>
<script
type=
"text/javascript"
src=
"../../_static/underscore.js"
></script>
<script
type=
"text/javascript"
src=
"../../_static/doctools.js"
></script>
<script
type=
"text/javascript"
src=
"https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
></script>
<link
rel=
"index"
title=
"Index"
href=
"../../genindex.html"
/>
<link
rel=
"search"
title=
"Search"
href=
"../../search.html"
/>
<link
rel=
"top"
title=
"PaddlePaddle documentation"
href=
"../../index.html"
/>
<script>
var
_hmt
=
_hmt
||
[];
(
function
()
{
var
hm
=
document
.
createElement
(
"
script
"
);
hm
.
src
=
"
//hm.baidu.com/hm.js?b9a314ab40d04d805655aab1deee08ba
"
;
var
s
=
document
.
getElementsByTagName
(
"
script
"
)[
0
];
s
.
parentNode
.
insertBefore
(
hm
,
s
);
})();
</script>
</head>
<body
role=
"document"
>
<div
class=
"related"
role=
"navigation"
aria-label=
"related navigation"
>
<h3>
Navigation
</h3>
<ul>
<li
class=
"right"
style=
"margin-right: 10px"
>
<a
href=
"../../genindex.html"
title=
"General Index"
accesskey=
"I"
>
index
</a></li>
<li
class=
"nav-item nav-item-0"
><a
href=
"../../index.html"
>
PaddlePaddle documentation
</a>
»
</li>
</ul>
</div>
<div
class=
"document"
>
<div
class=
"documentwrapper"
>
<div
class=
"bodywrapper"
>
<div
class=
"body"
role=
"main"
>
<div
class=
"section"
id=
"layer"
>
<span
id=
"layer"
></span><h1>
支持双层序列作为输入的Layer
<a
class=
"headerlink"
href=
"#layer"
title=
"Permalink to this headline"
>
¶
</a></h1>
<div
class=
"section"
id=
""
>
<span
id=
"id1"
></span><h2>
概述
<a
class=
"headerlink"
href=
"#"
title=
"Permalink to this headline"
>
¶
</a></h2>
<p>
在自然语言处理任务中,序列是一种常见的数据类型。一个独立的词语,可以看作是一个非序列输入,或者,我们称之为一个0层的序列;由词语构成的句子,是一个单层序列;若干个句子构成一个段落,是一个双层的序列。
</p>
<p>
双层序列是一个嵌套的序列,它的每一个元素,又是一个单层的序列。这是一种非常灵活的数据组织方式,帮助我们构造一些复杂的输入信息。
</p>
<p>
我们可以按照如下层次定义非序列,单层序列,以及双层序列。
</p>
<ul
class=
"simple"
>
<li>
0层序列:一个独立的元素,类型可以是PaddlePaddle支持的任意输入数据类型
</li>
<li>
单层序列:排成一列的多个元素,每个元素是一个0层序列,元素之间的顺序是重要的输入信息
</li>
<li>
双层序列:排成一列的多个元素,每个元素是一个单层序列,称之为双层序列的一个子序列(subseq),subseq的每个元素是一个0层序列
</li>
</ul>
<p>
在 PaddlePaddle中,下面这些Layer能够接受双层序列作为输入,完成相应的计算。
</p>
</div>
<div
class=
"section"
id=
"pooling-layer"
>
<span
id=
"pooling-layer"
></span><h2>
pooling_layer
<a
class=
"headerlink"
href=
"#pooling-layer"
title=
"Permalink to this headline"
>
¶
</a></h2>
<p>
pooling_layer的使用示例如下,详细见
<a
href =
"../../../doc/ui/api/trainer_config_helpers/layers.html#pooling-layer"
>
配置API
</a>
。
</p>
<div
class=
"highlight-python"
><div
class=
"highlight"
><pre><span></span><span
class=
"n"
>
seq_pool
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
pooling_layer
</span><span
class=
"p"
>
(
</span><span
class=
"nb"
>
input
</span><span
class=
"o"
>
=
</span><span
class=
"n"
>
layer
</span><span
class=
"p"
>
,
</span>
<span
class=
"n"
>
pooling_type
</span><span
class=
"o"
>
=
</span><span
class=
"n"
>
AvgPooling
</span><span
class=
"p"
>
(),
</span>
<span
class=
"n"
>
agg_level
</span><span
class=
"o"
>
=
</span><span
class=
"n"
>
AggregateLevel
</span><span
class=
"o"
>
.
</span><span
class=
"n"
>
EACH_SEQUENCE
</span><span
class=
"p"
>
)
</span>
</pre></div>
</div>
<ul
class=
"simple"
>
<li><code
class=
"docutils literal"
><span
class=
"pre"
>
pooling_type
</span></code>
目前支持两种,分别是:MaxPooling()和AvgPooling()。
</li>
<li><code
class=
"docutils literal"
><span
class=
"pre"
>
agg_level=AggregateLevel.TIMESTEP
</span></code>
时(默认值):
<ul>
<li>
作用:双层序列经过运算变成一个0层序列,或单层序列经过运算变成一个0层序列
</li>
<li>
输入:一个双层序列,或一个单层序列
</li>
<li>
输出:一个0层序列,即整个输入序列(单层或双层)的平均值(或最大值)
</li>
</ul>
</li>
<li><code
class=
"docutils literal"
><span
class=
"pre"
>
agg_level=AggregateLevel.EACH_SEQUENCE
</span></code>
时:
<ul>
<li>
作用:一个双层序列经过运算变成一个单层序列
</li>
<li>
输入:必须是一个双层序列
</li>
<li>
输出:一个单层序列,序列的每个元素是原来双层序列每个subseq元素的平均值(或最大值)
</li>
</ul>
</li>
</ul>
</div>
<div
class=
"section"
id=
"last-seq-first-seq"
>
<span
id=
"last-seq-first-seq"
></span><h2>
last_seq 和 first_seq
<a
class=
"headerlink"
href=
"#last-seq-first-seq"
title=
"Permalink to this headline"
>
¶
</a></h2>
<p>
last_seq的使用示例如下(first_seq类似),详细见
<a
href =
"../../../doc/ui/api/trainer_config_helpers/layers.html#last-seq"
>
配置API
</a>
。
</p>
<div
class=
"highlight-python"
><div
class=
"highlight"
><pre><span></span><span
class=
"n"
>
last
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
last_seq
</span><span
class=
"p"
>
(
</span><span
class=
"nb"
>
input
</span><span
class=
"o"
>
=
</span><span
class=
"n"
>
layer
</span><span
class=
"p"
>
,
</span>
<span
class=
"n"
>
agg_level
</span><span
class=
"o"
>
=
</span><span
class=
"n"
>
AggregateLevel
</span><span
class=
"o"
>
.
</span><span
class=
"n"
>
EACH_SEQUENCE
</span><span
class=
"p"
>
)
</span>
</pre></div>
</div>
<ul
class=
"simple"
>
<li><code
class=
"docutils literal"
><span
class=
"pre"
>
agg_level=AggregateLevel.TIMESTEP
</span></code>
时(默认值):
<ul>
<li>
作用:一个双层序列经过运算变成一个0层序列,或一个单层序列经过运算变成一个0层序列
</li>
<li>
输入:一个双层序列或一个单层序列
</li>
<li>
输出:一个0层序列,即整个输入序列(双层或者单层)最后一个,或第一个元素。
</li>
</ul>
</li>
<li><code
class=
"docutils literal"
><span
class=
"pre"
>
agg_level=AggregateLevel.EACH_SEQUENCE
</span></code>
时:
<ul>
<li>
作用:一个双层序列经过运算变成一个单层序列
</li>
<li>
输入:必须是一个双层序列
</li>
<li>
输出:一个单层序列,其中每个元素是双层序列中每个subseq最后一个(或第一个)元素。
</li>
</ul>
</li>
</ul>
</div>
<div
class=
"section"
id=
"expand-layer"
>
<span
id=
"expand-layer"
></span><h2>
expand_layer
<a
class=
"headerlink"
href=
"#expand-layer"
title=
"Permalink to this headline"
>
¶
</a></h2>
<p>
expand_layer的使用示例如下,详细见
<a
href =
"../../../doc/ui/api/trainer_config_helpers/layers.html#expand-layer"
>
配置API
</a>
。
</p>
<div
class=
"highlight-python"
><div
class=
"highlight"
><pre><span></span><span
class=
"n"
>
expand
</span>
<span
class=
"o"
>
=
</span>
<span
class=
"n"
>
expand_layer
</span><span
class=
"p"
>
(
</span><span
class=
"nb"
>
input
</span><span
class=
"o"
>
=
</span><span
class=
"n"
>
layer1
</span><span
class=
"p"
>
,
</span>
<span
class=
"n"
>
expand_as
</span><span
class=
"o"
>
=
</span><span
class=
"n"
>
layer2
</span><span
class=
"p"
>
,
</span>
<span
class=
"n"
>
expand_level
</span><span
class=
"o"
>
=
</span><span
class=
"n"
>
ExpandLevel
</span><span
class=
"o"
>
.
</span><span
class=
"n"
>
FROM_TIMESTEP
</span><span
class=
"p"
>
)
</span>
</pre></div>
</div>
<ul
class=
"simple"
>
<li><code
class=
"docutils literal"
><span
class=
"pre"
>
expand_level=ExpandLevel.FROM_TIMESTEP
</span></code>
时(默认值):
<ul>
<li>
作用:一个0层序列经过运算扩展成一个单层序列,或者一个双层序列
</li>
<li>
输入:layer1必须是一个0层序列,是待扩展的数据;layer2可以是一个单层序列,或者是一个双层序列,提供扩展的长度信息
</li>
<li>
输出:一个单层序列,或一个双层序列,输出序列的类型(双层序列,或单层序列)和序列中含有元素的数目同 layer2一致。若输出是单层序列,单层序列的每个元素(0层序列),都是对layer1元素的拷贝;若输出是双层序列,双层序列每个subseq中每个元素(0层序列),都是对layer1元素的拷贝
</li>
</ul>
</li>
<li><code
class=
"docutils literal"
><span
class=
"pre"
>
expand_level=ExpandLevel.FROM_SEQUENCE
</span></code>
时:
<ul>
<li>
作用:一个单层序列经过运算扩展成一个双层序列
</li>
<li>
输入:layer1必须是一个单层序列,是待扩展的数据;layer2必须是一个双层序列,提供扩展的长度信息
</li>
<li>
输出:一个双层序列,序列中含有元素的数目同layer2一致。要求单层序列含有元素的数目(0层序列),和双层序列含有subseq 的数目一致。单层序列第i个元素(0层序列),被扩展为一个单层序列,构成了输出双层序列的第i个subseq。
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div
class=
"sphinxsidebar"
role=
"navigation"
aria-label=
"main navigation"
>
<div
class=
"sphinxsidebarwrapper"
>
<h3><a
href=
"../../index.html"
>
Table Of Contents
</a></h3>
<ul>
<li><a
class=
"reference internal"
href=
"#"
>
支持双层序列作为输入的Layer
</a><ul>
<li><a
class=
"reference internal"
href=
"#"
>
概述
</a></li>
<li><a
class=
"reference internal"
href=
"#pooling-layer"
>
pooling_layer
</a></li>
<li><a
class=
"reference internal"
href=
"#last-seq-first-seq"
>
last_seq 和 first_seq
</a></li>
<li><a
class=
"reference internal"
href=
"#expand-layer"
>
expand_layer
</a></li>
</ul>
</li>
</ul>
<div
role=
"note"
aria-label=
"source link"
>
<h3>
This Page
</h3>
<ul
class=
"this-page-menu"
>
<li><a
href=
"../../_sources/algorithm/rnn/hierarchical-layer.txt"
rel=
"nofollow"
>
Show Source
</a></li>
</ul>
</div>
<div
id=
"searchbox"
style=
"display: none"
role=
"search"
>
<h3>
Quick search
</h3>
<form
class=
"search"
action=
"../../search.html"
method=
"get"
>
<div><input
type=
"text"
name=
"q"
/></div>
<div><input
type=
"submit"
value=
"Go"
/></div>
<input
type=
"hidden"
name=
"check_keywords"
value=
"yes"
/>
<input
type=
"hidden"
name=
"area"
value=
"default"
/>
</form>
</div>
<script
type=
"text/javascript"
>
$
(
'
#searchbox
'
).
show
(
0
);
</script>
</div>
</div>
<div
class=
"clearer"
></div>
</div>
<div
class=
"related"
role=
"navigation"
aria-label=
"related navigation"
>
<h3>
Navigation
</h3>
<ul>
<li
class=
"right"
style=
"margin-right: 10px"
>
<a
href=
"../../genindex.html"
title=
"General Index"
>
index
</a></li>
<li
class=
"nav-item nav-item-0"
><a
href=
"../../index.html"
>
PaddlePaddle documentation
</a>
»
</li>
</ul>
</div>
<div
class=
"footer"
role=
"contentinfo"
>
©
Copyright 2016, PaddlePaddle developers.
Created using
<a
href=
"http://sphinx-doc.org/"
>
Sphinx
</a>
1.4.8.
</div>
</body>
</html>
\ No newline at end of file
doc_cn/algorithm/rnn/hierarchical-rnn.html
0 → 100644
浏览文件 @
e0323804
此差异已折叠。
点击以展开。
doc_cn/algorithm/rnn/rnn-tutorial.html
0 → 100644
浏览文件 @
e0323804
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
xmlns=
"http://www.w3.org/1999/xhtml"
>
<head>
<meta
http-equiv=
"Content-Type"
content=
"text/html; charset=utf-8"
/>
<title>
Recurrent Group教程
—
PaddlePaddle documentation
</title>
<link
rel=
"stylesheet"
href=
"../../_static/classic.css"
type=
"text/css"
/>
<link
rel=
"stylesheet"
href=
"../../_static/pygments.css"
type=
"text/css"
/>
<script
type=
"text/javascript"
>
var
DOCUMENTATION_OPTIONS
=
{
URL_ROOT
:
'
../../
'
,
VERSION
:
''
,
COLLAPSE_INDEX
:
false
,
FILE_SUFFIX
:
'
.html
'
,
HAS_SOURCE
:
true
};
</script>
<script
type=
"text/javascript"
src=
"../../_static/jquery.js"
></script>
<script
type=
"text/javascript"
src=
"../../_static/underscore.js"
></script>
<script
type=
"text/javascript"
src=
"../../_static/doctools.js"
></script>
<script
type=
"text/javascript"
src=
"https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
></script>
<link
rel=
"index"
title=
"Index"
href=
"../../genindex.html"
/>
<link
rel=
"search"
title=
"Search"
href=
"../../search.html"
/>
<link
rel=
"top"
title=
"PaddlePaddle documentation"
href=
"../../index.html"
/>
<script>
var
_hmt
=
_hmt
||
[];
(
function
()
{
var
hm
=
document
.
createElement
(
"
script
"
);
hm
.
src
=
"
//hm.baidu.com/hm.js?b9a314ab40d04d805655aab1deee08ba
"
;
var
s
=
document
.
getElementsByTagName
(
"
script
"
)[
0
];
s
.
parentNode
.
insertBefore
(
hm
,
s
);
})();
</script>
</head>
<body
role=
"document"
>
<div
class=
"related"
role=
"navigation"
aria-label=
"related navigation"
>
<h3>
Navigation
</h3>
<ul>
<li
class=
"right"
style=
"margin-right: 10px"
>
<a
href=
"../../genindex.html"
title=
"General Index"
accesskey=
"I"
>
index
</a></li>
<li
class=
"nav-item nav-item-0"
><a
href=
"../../index.html"
>
PaddlePaddle documentation
</a>
»
</li>
</ul>
</div>
<div
class=
"document"
>
<div
class=
"documentwrapper"
>
<div
class=
"bodywrapper"
>
<div
class=
"body"
role=
"main"
>
<div
class=
"section"
id=
"recurrent-group"
>
<span
id=
"recurrent-group"
></span><h1>
Recurrent Group教程
<a
class=
"headerlink"
href=
"#recurrent-group"
title=
"Permalink to this headline"
>
¶
</a></h1>
<div
class=
"section"
id=
""
>
<span
id=
"id1"
></span><h2>
概述
<a
class=
"headerlink"
href=
"#"
title=
"Permalink to this headline"
>
¶
</a></h2>
<p>
序列数据是自然语言处理任务面对的一种主要输入数据类型。
</p>
<p>
一句话是由词语构成的序列,多句话进一步构成了段落。因此,段落可以看作是一个嵌套的双层的序列,这个序列的每个元素又是一个序列。
</p>
<p>
双层序列是PaddlePaddle支持的一种非常灵活的数据组织方式,帮助我们更好地描述段落、多轮对话等更为复杂的语言数据。基于双层序列输入,我们可以设计搭建一个灵活的、层次化的RNN,分别从词语和句子级别编码输入数据,同时也能够引入更加复杂的记忆机制,更好地完成一些复杂的语言理解任务。
</p>
<p>
在PaddlePaddle中,
<code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
是一种任意复杂的RNN单元,用户只需定义RNN在一个时间步内完成的计算,PaddlePaddle负责完成信息和误差在时间序列上的传播。
</p>
<p>
更进一步,
<code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
同样可以扩展到双层序列的处理上。通过两个嵌套的
<code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
分别定义子句级别和词语级别上需要完成的运算,最终实现一个层次化的复杂RNN。
</p>
<p>
目前,在PaddlePaddle中,能够对双向序列进行处理的有
<code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
和部分Layer,具体可参考文档:
<a
href =
"hierarchical-layer.html"
>
支持双层序列作为输入的Layer
</a>
。
</p>
</div>
<div
class=
"section"
id=
""
>
<span
id=
"id2"
></span><h2>
相关概念
<a
class=
"headerlink"
href=
"#"
title=
"Permalink to this headline"
>
¶
</a></h2>
<div
class=
"section"
id=
""
>
<span
id=
"id3"
></span><h3>
基本原理
<a
class=
"headerlink"
href=
"#"
title=
"Permalink to this headline"
>
¶
</a></h3>
<p><code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
是PaddlePaddle支持的一种任意复杂的RNN单元。使用者只需要关注于设计RNN在一个时间步之内完成的计算,PaddlePaddle负责完成信息和梯度在时间序列上的传播。
</p>
<p>
PaddlePaddle中,
<code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
的一个简单调用如下:
</p>
<div
class=
"highlight-python"
><div
class=
"highlight"
><pre><span></span><span
class=
"n"
>
recurrent_group
</span><span
class=
"p"
>
(
</span><span
class=
"n"
>
step
</span><span
class=
"p"
>
,
</span>
<span
class=
"nb"
>
input
</span><span
class=
"p"
>
,
</span>
<span
class=
"n"
>
reverse
</span><span
class=
"p"
>
)
</span>
</pre></div>
</div>
<ul
class=
"simple"
>
<li>
step:一个可调用的函数,定义一个时间步之内RNN单元完成的计算
</li>
<li>
input:输入,必须是一个单层序列,或者一个双层序列
</li>
<li>
reverse:是否以逆序处理输入序列
</li>
</ul>
<p>
使用
<code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
的核心是设计step函数的计算逻辑。step函数内部可以自由组合PaddlePaddle支持的各种layer,完成任意的运算逻辑。
<code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
的输入(即input)会成为step函数的输入,由于step 函数只关注于RNN一个时间步之内的计算,在这里
<code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
替我们完成了原始输入数据的拆分。
</p>
</div>
<div
class=
"section"
id=
""
>
<span
id=
"id4"
></span><h3>
输入
<a
class=
"headerlink"
href=
"#"
title=
"Permalink to this headline"
>
¶
</a></h3>
<p><code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
处理的输入序列主要分为以下三种类型:
</p>
<ul
class=
"simple"
>
<li><strong>
数据输入
</strong>
:一个双层序列进入
<code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
会被拆解为一个单层序列,一个单层序列进入
<code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
会被拆解为非序列,然后交给step函数,这一过程对用户是完全透明的。可以有以下两种:1)通过data_layer拿到的用户输入;2)其它layer的输出。
</li>
<li><strong>
只读Memory输入
</strong>
:
<code
class=
"docutils literal"
><span
class=
"pre"
>
StaticInput
</span></code>
定义了一个只读的Memory,由
<code
class=
"docutils literal"
><span
class=
"pre"
>
StaticInput
</span></code>
指定的输入不会被
<code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
拆解,
<code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
循环展开的每个时间步总是能够引用所有输入,可以是一个非序列,或者一个单层序列。
</li>
<li><strong>
序列生成任务的输入
</strong>
:
<code
class=
"docutils literal"
><span
class=
"pre"
>
GeneratedInput
</span></code>
只用于在序列生成任务中指定输入数据。
</li>
</ul>
</div>
<div
class=
"section"
id=
""
>
<span
id=
"id5"
></span><h3>
输入示例
<a
class=
"headerlink"
href=
"#"
title=
"Permalink to this headline"
>
¶
</a></h3>
<p>
序列生成任务大多遵循encoder-decoer架构,encoder和decoder可以是能够处理序列的任意神经网络单元,而RNN是最流行的选择。
</p>
<p>
给定encoder输出和当前词,decoder每次预测产生下一个最可能的词语。在这种结构中,decoder接受两个输入:
</p>
<ul
class=
"simple"
>
<li>
要生成的目标序列:是decoder的数据输入,也是decoder循环展开的依据,
<code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
会对这类输入进行拆解。
</li>
<li>
encoder输出,可以是一个非序列,或者一个单层序列:是一个unbounded memory,decoder循环展开的每一个时间步会引用全部结果,不应该被拆解,这种类型的输入必须通过
<code
class=
"docutils literal"
><span
class=
"pre"
>
StaticInput
</span></code>
指定。关于Unbounded Memory的更多讨论请参考论文
<a
class=
"reference external"
href=
"https://arxiv.org/abs/1410.5401"
>
Neural Turning Machine
</a>
。
</li>
</ul>
<p>
在序列生成任务中,decoder RNN总是引用上一时刻预测出的词的词向量,作为当前时刻输入。
<code
class=
"docutils literal"
><span
class=
"pre"
>
GeneratedInput
</span></code>
自动完成这一过程。
</p>
</div>
<div
class=
"section"
id=
""
>
<span
id=
"id6"
></span><h3>
输出
<a
class=
"headerlink"
href=
"#"
title=
"Permalink to this headline"
>
¶
</a></h3>
<p><code
class=
"docutils literal"
><span
class=
"pre"
>
step
</span></code>
函数必须返回一个或多个Layer的输出,这个Layer的输出会作为整个
<code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
最终的输出结果。在输出的过程中,
<code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
会将每个时间步的输出拼接,这个过程对用户也是透明的。
</p>
</div>
<div
class=
"section"
id=
"memory"
>
<span
id=
"memory"
></span><h3>
memory
<a
class=
"headerlink"
href=
"#memory"
title=
"Permalink to this headline"
>
¶
</a></h3>
<p>
memory只能在
<code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
中定义和使用。memory不能独立存在,必须指向一个PaddlePaddle定义的Layer。引用memory得到这layer上一时刻输出,因此,可以将memory理解为一个时延操作。
</p>
<p>
可以显示地指定一个layer的输出用于初始化memory。不指定时,memory默认初始化为0。
</p>
</div>
</div>
<div
class=
"section"
id=
"rnn"
>
<span
id=
"rnn"
></span><h2>
双层RNN介绍
<a
class=
"headerlink"
href=
"#rnn"
title=
"Permalink to this headline"
>
¶
</a></h2>
<p><code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
帮助我们完成对输入序列的拆分,对输出的合并,以及计算逻辑在序列上的循环展开。
</p>
<p>
利用这种特性,两个嵌套的
<code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
能够处理双层序列,实现词语和句子两个级别的双层RNN结构。
</p>
<ul
class=
"simple"
>
<li>
单层(word-level)RNN:每个状态(state)对应一个词(word)。
</li>
<li>
双层(sequence-level)RNN:一个双层RNN由多个单层RNN组成,每个单层RNN(即双层RNN的每个状态)对应一个子句(subseq)。
</li>
</ul>
<p>
为了描述方便,下文以NLP任务为例,将含有子句(subseq)的段落定义为一个双层序列,将含有词语的句子定义为一个单层序列,那么0层序列即为一个词语。
</p>
</div>
<div
class=
"section"
id=
"rnn"
>
<span
id=
"id7"
></span><h2>
双层RNN的使用
<a
class=
"headerlink"
href=
"#rnn"
title=
"Permalink to this headline"
>
¶
</a></h2>
<div
class=
"section"
id=
""
>
<span
id=
"id8"
></span><h3>
训练流程的使用方法
<a
class=
"headerlink"
href=
"#"
title=
"Permalink to this headline"
>
¶
</a></h3>
<p>
使用
<code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
需要遵循以下约定:
</p>
<ul
class=
"simple"
>
<li><strong>
单进单出
</strong>
:输入和输出都是单层序列。
<ul>
<li>
如果有多个输入,不同输入序列含有的词语数必须严格相等。
</li>
<li>
输出一个单层序列,输出序列的词语数和输入序列一致。
</li>
<li>
memory:在step函数中定义 memory指向一个layer,通过引用memory得到这个layer上一个时刻输出,形成recurrent 连接。memory的is_seq参数必须为false。如果没有定义memory,每个时间步之内的运算是独立的。
</li>
<li>
boot_layer:memory的初始状态,默认初始状为0,memory的is_seq参数必须为false。
</li>
</ul>
</li>
<li><strong>
双进双出
</strong>
:输入和输出都是双层序列。
<ul>
<li>
如果有多个输入序列,不同输入含有的子句(subseq)数必须严格相等,但子句含有的词语数可以不相等。
</li>
<li>
输出一个双层序列,子句(subseq)数、子句的单词数和指定的一个输入序列一致,默认为第一个输入。
</li>
<li>
memory:在step函数中定义memory,指向一个layer,通过引用memory得到这个layer上一个时刻的输出,形成recurrent连接。定义在外层
<code
class=
"docutils literal"
><span
class=
"pre"
>
recurrent_group
</span></code>
step函数中的memory,能够记录上一个subseq 的状态,可以是一个单层序列(只作为read-only memory),也可以是一个词语。如果没有定义memory,那么 subseq 之间的运算是独立的。
</li>
<li>
boot_layer:memory 初始状态,可以是一个单层序列(只作为read-only memory)或一个向量。默认不设置,即初始状态为0。
</li>
</ul>
</li>
<li><strong>
双进单出
</strong>
:目前还未支持,会报错
”
In hierachical RNN, all out links should be from sequences now
”
。
</li>
</ul>
</div>
<div
class=
"section"
id=
""
>
<span
id=
"id9"
></span><h3>
生成流程的使用方法
<a
class=
"headerlink"
href=
"#"
title=
"Permalink to this headline"
>
¶
</a></h3>
<p>
使用
<code
class=
"docutils literal"
><span
class=
"pre"
>
beam_search
</span></code>
需要遵循以下约定:
</p>
<ul
class=
"simple"
>
<li>
单层RNN:从一个word生成下一个word。
</li>
<li>
双层RNN:即把单层RNN生成后的subseq给拼接成一个新的双层seq。从语义上看,也不存在一个subseq直接生成下一个subseq的情况。
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div
class=
"sphinxsidebar"
role=
"navigation"
aria-label=
"main navigation"
>
<div
class=
"sphinxsidebarwrapper"
>
<h3><a
href=
"../../index.html"
>
Table Of Contents
</a></h3>
<ul>
<li><a
class=
"reference internal"
href=
"#"
>
Recurrent Group教程
</a><ul>
<li><a
class=
"reference internal"
href=
"#"
>
概述
</a></li>
<li><a
class=
"reference internal"
href=
"#"
>
相关概念
</a><ul>
<li><a
class=
"reference internal"
href=
"#"
>
基本原理
</a></li>
<li><a
class=
"reference internal"
href=
"#"
>
输入
</a></li>
<li><a
class=
"reference internal"
href=
"#"
>
输入示例
</a></li>
<li><a
class=
"reference internal"
href=
"#"
>
输出
</a></li>
<li><a
class=
"reference internal"
href=
"#memory"
>
memory
</a></li>
</ul>
</li>
<li><a
class=
"reference internal"
href=
"#rnn"
>
双层RNN介绍
</a></li>
<li><a
class=
"reference internal"
href=
"#rnn"
>
双层RNN的使用
</a><ul>
<li><a
class=
"reference internal"
href=
"#"
>
训练流程的使用方法
</a></li>
<li><a
class=
"reference internal"
href=
"#"
>
生成流程的使用方法
</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<div
role=
"note"
aria-label=
"source link"
>
<h3>
This Page
</h3>
<ul
class=
"this-page-menu"
>
<li><a
href=
"../../_sources/algorithm/rnn/rnn-tutorial.txt"
rel=
"nofollow"
>
Show Source
</a></li>
</ul>
</div>
<div
id=
"searchbox"
style=
"display: none"
role=
"search"
>
<h3>
Quick search
</h3>
<form
class=
"search"
action=
"../../search.html"
method=
"get"
>
<div><input
type=
"text"
name=
"q"
/></div>
<div><input
type=
"submit"
value=
"Go"
/></div>
<input
type=
"hidden"
name=
"check_keywords"
value=
"yes"
/>
<input
type=
"hidden"
name=
"area"
value=
"default"
/>
</form>
</div>
<script
type=
"text/javascript"
>
$
(
'
#searchbox
'
).
show
(
0
);
</script>
</div>
</div>
<div
class=
"clearer"
></div>
</div>
<div
class=
"related"
role=
"navigation"
aria-label=
"related navigation"
>
<h3>
Navigation
</h3>
<ul>
<li
class=
"right"
style=
"margin-right: 10px"
>
<a
href=
"../../genindex.html"
title=
"General Index"
>
index
</a></li>
<li
class=
"nav-item nav-item-0"
><a
href=
"../../index.html"
>
PaddlePaddle documentation
</a>
»
</li>
</ul>
</div>
<div
class=
"footer"
role=
"contentinfo"
>
©
Copyright 2016, PaddlePaddle developers.
Created using
<a
href=
"http://sphinx-doc.org/"
>
Sphinx
</a>
1.4.8.
</div>
</body>
</html>
\ No newline at end of file
doc_cn/index.html
浏览文件 @
e0323804
...
...
@@ -78,7 +78,10 @@ var _hmt = _hmt || [];
<div
class=
"section"
id=
"id9"
>
<h2>
算法教程
<a
class=
"headerlink"
href=
"#id9"
title=
"Permalink to this headline"
>
¶
</a></h2>
<ul
class=
"simple"
>
<li><a
class=
"reference external"
href=
"../doc/algorithm/rnn/rnn.html"
>
RNN配置
</a></li>
<li><a
class=
"reference external"
href=
"algorithm/rnn/rnn-tutorial.html"
>
Recurrent Group教程
</a></li>
<li><a
class=
"reference external"
href=
"../doc/algorithm/rnn/rnn.html"
>
单层RNN示例
</a></li>
<li><a
class=
"reference external"
href=
"algorithm/rnn/hierarchical-rnn.html"
>
双层RNN示例
</a></li>
<li><a
class=
"reference external"
href=
"algorithm/rnn/hierarchical-layer.html"
>
支持双层序列作为输入的Layer
</a></li>
</ul>
</div>
</div>
...
...
doc_cn/objects.inv
浏览文件 @
e0323804
无法预览此类型文件
doc_cn/searchindex.js
浏览文件 @
e0323804
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录