Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wmsofts
Paddle
提交
b9843abb
P
Paddle
项目概览
wmsofts
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
b9843abb
编写于
6月 13, 2018
作者:
Y
yuyang18
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Polish comsum, DynamicRNN
上级
54002c3b
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
144 addition
and
2 deletion
+144
-2
paddle/fluid/operators/cumsum_op.cc
paddle/fluid/operators/cumsum_op.cc
+2
-2
python/paddle/fluid/layers/control_flow.py
python/paddle/fluid/layers/control_flow.py
+142
-0
未找到文件。
paddle/fluid/operators/cumsum_op.cc
浏览文件 @
b9843abb
...
...
@@ -30,8 +30,8 @@ class CumOp : public framework::OperatorWithKernel {
class
CumsumOpMaker
:
public
framework
::
OpProtoAndCheckerMaker
{
public:
void
Make
()
override
{
AddInput
(
"X"
,
"Input of
C
umsum operator"
);
AddOutput
(
"Out"
,
"Output of
C
umsum operator"
);
AddInput
(
"X"
,
"Input of
c
umsum operator"
);
AddOutput
(
"Out"
,
"Output of
c
umsum operator"
);
AddAttr
<
int
>
(
"axis"
,
"The dimenstion to accumulate along. -1 means the last "
"dimenstion [default -1]."
)
...
...
python/paddle/fluid/layers/control_flow.py
浏览文件 @
b9843abb
...
...
@@ -20,6 +20,7 @@ from ..framework import Program, Variable, Operator
from
..layer_helper
import
LayerHelper
,
unique_name
from
..initializer
import
force_init_on_cpu
from
ops
import
logical_and
,
logical_not
,
logical_or
import
numpy
__all__
=
[
'split_lod_tensor'
,
...
...
@@ -1314,6 +1315,39 @@ class IfElse(object):
class
DynamicRNN
(
object
):
"""
Dynamic RNN.
This RNN can process a batch of sequence data. The length of each sample
sequence can be different. This API automatically process them in batch.
The input lod must be set. Please reference `lod_tensor`
>>> import paddle.fluid as fluid
>>> data = fluid.layers.data(name='sentence', dtype='int64', lod_level=1)
>>> embedding = fluid.layers.embedding(input=data, size=[65535, 32],
>>> is_sparse=True)
>>>
>>> drnn = fluid.layers.DynamicRNN()
>>> with drnn.block():
>>> word = drnn.step_input(embedding)
>>> prev = drnn.memory(shape=[200])
>>> hidden = fluid.layers.fc(input=[word, prev], size=200, act='relu')
>>> drnn.update_memory(prev, hidden) # set prev to hidden
>>> drnn.output(hidden)
>>>
>>> # last is the last time step of rnn. It is the encoding result.
>>> last = fluid.layers.sequence_last_step(drnn())
The dynamic RNN will unfold sequence into timesteps. Users need to define
how to process each time step during the :code:`with` block.
The `memory` is used staging data cross time step. The initial value of
memory can be zero or another variable.
The dynamic RNN can mark multiple variables as its output. Use `drnn()` to
get the output sequence.
"""
BEFORE_RNN
=
0
IN_RNN
=
1
AFTER_RNN
=
2
...
...
@@ -1336,6 +1370,15 @@ class DynamicRNN(object):
self
.
mem_link
=
[]
def
step_input
(
self
,
x
):
"""
Mark a sequence as a dynamic RNN input.
Args:
x(Variable): The input sequence.
Returns:
The current timestep in the input sequence.
"""
self
.
_assert_in_rnn_block_
(
"step_input"
)
if
not
isinstance
(
x
,
Variable
):
raise
TypeError
(
...
...
@@ -1379,6 +1422,15 @@ class DynamicRNN(object):
return
array_read
(
array
=
input_array
,
i
=
self
.
step_idx
)
def
static_input
(
self
,
x
):
"""
Mark a variable as a RNN input. The input will not be scattered into
time steps.
Args:
x(Variable): The input variable.
Returns:
The input variable that can access in RNN.
"""
self
.
_assert_in_rnn_block_
(
"static_input"
)
if
not
isinstance
(
x
,
Variable
):
raise
TypeError
(
...
...
@@ -1400,6 +1452,10 @@ class DynamicRNN(object):
@
contextlib
.
contextmanager
def
block
(
self
):
"""
The block for user to define operators in RNN. See the class docstring
for more details.
"""
if
self
.
status
!=
DynamicRNN
.
BEFORE_RNN
:
raise
ValueError
(
"rnn.block() can only be invoke once"
)
self
.
step_idx
=
fill_constant
(
...
...
@@ -1426,6 +1482,9 @@ class DynamicRNN(object):
x
=
each_array
,
table
=
self
.
lod_rank_table
))
def
__call__
(
self
,
*
args
,
**
kwargs
):
"""
Get the output of RNN. This API should only be invoked after RNN.block()
"""
if
self
.
status
!=
DynamicRNN
.
AFTER_RNN
:
raise
ValueError
((
"Output of the dynamic RNN can only be visited "
"outside the rnn block."
))
...
...
@@ -1440,6 +1499,70 @@ class DynamicRNN(object):
value
=
0.0
,
need_reorder
=
False
,
dtype
=
'float32'
):
"""
Create a memory variable.
If the :code:`init` is not None, :code:`memory` will be initialized by
this variable. The :code:`need_reorder` is used to reorder the memory as
the input variable. It should be set to true when the initialized memory
depends on the input sample.
For example,
>>> import paddle.fluid as fluid
>>> sentence = fluid.layers.data(
>>> name='sentence', dtype='float32', shape=[32])
>>> boot_memory = fluid.layers.data(
>>> name='boot', dtype='float32', shape=[10])
>>>
>>> drnn = fluid.layers.DynamicRNN()
>>> with drnn.block():
>>> word = drnn.step_input(sentence)
>>> memory = drnn.memory(init=boot_memory, need_reorder=True)
>>> hidden = fluid.layers.fc(
>>> input=[word, memory], size=10, act='tanh')
>>> drnn.update_memory(ex_mem=memory, new_mem=hidden)
>>> drnn.output(hidden)
>>> rnn_output = drnn()
Otherwise, if :code:`shape`, :code:`value`, :code:`dtype` are set, the
:code:`memory` will be initialized by this :code:`value`.
For example,
>>> import paddle.fluid as fluid
>>> sentence = fluid.layers.data(
>>> name='sentence', dtype='float32', shape=[32])
>>>
>>> drnn = fluid.layers.DynamicRNN()
>>> with drnn.block():
>>> word = drnn.step_input(sentence)
>>> memory = drnn.memory(shape=[10], dtype='float32', value=0)
>>> hidden = fluid.layers.fc(
>>> input=[word, memory], size=10, act='tanh')
>>> drnn.update_memory(ex_mem=memory, new_mem=hidden)
>>> drnn.output(hidden)
>>> rnn_output = drnn()
Args:
init(Variable|None): The initialized variable.
shape(list|tuple): The memory shape. NOTE the shape does not contain
batch_size.
value(float): the initalized value.
need_reorder(bool): True if the initialized memory depends on the
input sample.
dtype(str|numpy.dtype): The data type of the initialized memory.
Returns:
the memory variable.
"""
self
.
_assert_in_rnn_block_
(
'memory'
)
if
init
is
not
None
:
if
not
isinstance
(
init
,
Variable
):
...
...
@@ -1507,6 +1630,16 @@ class DynamicRNN(object):
return
self
.
memory
(
init
=
init
)
def
update_memory
(
self
,
ex_mem
,
new_mem
):
"""
Update the memory from ex_mem to new_mem. NOTE that the shape and data
type of :code:`ex_mem` and :code:`new_mem` must be same.
Args:
ex_mem(Variable): the memory variable.
new_mem(Variable): the plain variable generated in RNN block.
Returns:
None
"""
self
.
_assert_in_rnn_block_
(
'update_memory'
)
if
not
isinstance
(
ex_mem
,
Variable
):
raise
TypeError
(
"The input arg `ex_mem` of update_memory() must "
...
...
@@ -1524,6 +1657,15 @@ class DynamicRNN(object):
self
.
mem_link
.
append
((
new_mem
,
mem_array
))
def
output
(
self
,
*
outputs
):
"""
mark the RNN output variables.
Args:
outputs: The output variables.
Returns:
None
"""
self
.
_assert_in_rnn_block_
(
'output'
)
parent_block
=
self
.
_parent_block_
()
for
each
in
outputs
:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录