Refine code, found a bad design

avx_docs
Yu Yang 9 years ago
parent a146fcf8ad
commit 4fcf01a849

@ -107,23 +107,29 @@
在该配置中,名称为\ :code:`rnn_state`\ 的全连接层暂存到了\ :ref:`glossary_Memory`\ 中。这个\ :ref:`glossary_Memory`\ 变量\ :code:`mem`\ 中可以保存到上一个\ :ref:`glossary_timestep`\ 中的全连接层的输出。从而实现一个全连接的\ :ref:`glossary_RNN`\ 。
以数据\ :code:`[4, 5, 2, 0, 9, 8, 1, 4]`\ 举例,单层\ :ref:`glossary_RNN`\ 的网络图如下\:
.. graphviz:: simple_full_recurrent.dot
而对于\ :ref:`glossary_双层RNN`\ 来说,等价的网络配置如下\:
.. literalinclude:: ../../../paddle/gserver/tests/sequence_nest_rnn.conf
:language: python
:lines: 39-66
:linenos:
:emphasize-lines: 4-6
- 双层序列外层memory是一个元素
- 内层inner_step的recurrent_group和单层序列的几乎一样。除了boot_layer=outer_mem表示将外层的outer_mem作为内层memory的初始状态。外层outer_step中outer_mem是一个子句的最后一个向量即整个双层group是将前一个子句的最后一个向量作为下一个子句memory的初始状态。
- 从输入数据上看单双层序列的句子是一样的只是双层序列将其又做了子序列划分。因此双层序列的配置中必须将前一个子句的最后一个元素作为boot_layer传给下一个子句的memory才能保证和单层序列的配置中“每一个时间步都用了上一个时间步的输出结果”一致。
- 在该配置中,外层的\ :code:`outer_mem`\ 和内层的\ :code:`inner_mem`\ 两个变量配合,实现了和单层\ :ref:`glossary_RNN`\ 等价的全连接\ :ref:`glossary_RNN`\ 。
- 外层\ :code:`outer_step`\ 中的\ :code:`outer_mem`\ 会将神经网络中每个子序列的最后一个结果记录下来。即将第18行的\ :code:`last`\ 变量记录下来。
- 内层\ :code:`inner_step`\ 中的\ :code:`inner_mem`\ 会将神经网络中子序列中的每一个元素的结果记录下来。即将第7行的\ :code:`out`\ 变量记录下来。
- 内层的\ :code:`inner_mem`\ 初始值是\ :code:`outer_mem`(:code:`boot_layer`)。于是前一个子序列的最后结果,是新的子序列的初试结果。即完成了简单的全连接\ :code:`glossary_RNN`\ 。
本例中的\ :ref:`glossary_双层RNN`\ ,以数据\ :code:`[ [4, 5, 2], [0, 9], [8, 1, 4]]`\ 举例,配置图如下\:
- 双层序列外层memory是单层序列
.. graphviz:: simple_full_hierarchical_recurrent.dot
- 由于外层每个时间步返回的是一个子句这些子句的长度往往不等长。因此当外层有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**”的错误。
这里有一点注意事项Paddle目前实现的\ :ref:`glossary_双层RNN`\ 不完全支持内层\ :ref:`glossary_RNN`\ 的\ :ref:`glossary_Memory`\ 引用外层\ :ref:`glossary_RNN`\ 的某一层序列输入。即\ :code:`inner_mem`的\ :code:`boot_layer`\ 需要是非序列类型的,或者可以是序列类型,但是每个时间步下,序列长度是一致的。从序列类型转换为非序列类型,可以使用\ :code:`pooling_layer`, :code:`last_seq`, :code:`first_seq`\ 等操作进行转换。
示例3双进双出输入不等长
===========================

@ -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;
}

@ -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;
}
Loading…
Cancel
Save