Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Paddle
提交
e0c8cd8a
P
Paddle
项目概览
PaddlePaddle
/
Paddle
1 年多 前同步成功
通知
2302
Star
20931
Fork
5422
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1423
列表
看板
标记
里程碑
合并请求
543
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1,423
Issue
1,423
列表
看板
标记
里程碑
合并请求
543
合并请求
543
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
e0c8cd8a
编写于
10月 02, 2017
作者:
Q
qiaolongfei
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'develop' of
https://github.com/PaddlePaddle/Paddle
into add_compile_time_infershape
上级
d550380e
e4d20110
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
109 addition
and
132 deletion
+109
-132
paddle/framework/block_desc.h
paddle/framework/block_desc.h
+3
-3
paddle/framework/op_info.h
paddle/framework/op_info.h
+3
-5
paddle/framework/program_desc.h
paddle/framework/program_desc.h
+3
-3
paddle/framework/scope.h
paddle/framework/scope.h
+3
-5
paddle/framework/tensor_array.h
paddle/framework/tensor_array.h
+0
-8
paddle/operators/recurrent_op.cc
paddle/operators/recurrent_op.cc
+35
-39
paddle/operators/recurrent_op.h
paddle/operators/recurrent_op.h
+4
-6
paddle/operators/rnn/recurrent_op_utils.cc
paddle/operators/rnn/recurrent_op_utils.cc
+31
-40
paddle/operators/rnn/recurrent_op_utils.h
paddle/operators/rnn/recurrent_op_utils.h
+3
-3
paddle/operators/sum_op.cc
paddle/operators/sum_op.cc
+3
-2
paddle/platform/macros.h
paddle/platform/macros.h
+6
-4
python/paddle/v2/framework/tests/test_recurrent_op.py
python/paddle/v2/framework/tests/test_recurrent_op.py
+15
-14
未找到文件。
paddle/framework/block_desc.h
浏览文件 @
e0c8cd8a
...
@@ -19,6 +19,7 @@ limitations under the License. */
...
@@ -19,6 +19,7 @@ limitations under the License. */
#include <vector>
#include <vector>
#include "paddle/framework/op_desc.h"
#include "paddle/framework/op_desc.h"
#include "paddle/framework/var_desc.h"
#include "paddle/framework/var_desc.h"
#include "paddle/platform/macros.h"
namespace
paddle
{
namespace
paddle
{
namespace
framework
{
namespace
framework
{
...
@@ -34,9 +35,6 @@ class BlockDescBind {
...
@@ -34,9 +35,6 @@ class BlockDescBind {
BlockDescBind
(
ProgramDescBind
*
prog
,
BlockDesc
*
desc
)
BlockDescBind
(
ProgramDescBind
*
prog
,
BlockDesc
*
desc
)
:
prog_
(
prog
),
desc_
(
desc
),
need_update_
(
false
)
{}
:
prog_
(
prog
),
desc_
(
desc
),
need_update_
(
false
)
{}
BlockDescBind
(
const
BlockDescBind
&
o
)
=
delete
;
BlockDescBind
&
operator
=
(
const
BlockDescBind
&
o
)
=
delete
;
int32_t
ID
()
const
{
return
desc_
->
idx
();
}
int32_t
ID
()
const
{
return
desc_
->
idx
();
}
int32_t
Parent
()
const
{
return
desc_
->
parent_idx
();
}
int32_t
Parent
()
const
{
return
desc_
->
parent_idx
();
}
...
@@ -68,6 +66,8 @@ class BlockDescBind {
...
@@ -68,6 +66,8 @@ class BlockDescBind {
std
::
deque
<
std
::
unique_ptr
<
OpDescBind
>>
ops_
;
std
::
deque
<
std
::
unique_ptr
<
OpDescBind
>>
ops_
;
std
::
unordered_map
<
std
::
string
,
std
::
unique_ptr
<
VarDescBind
>>
vars_
;
std
::
unordered_map
<
std
::
string
,
std
::
unique_ptr
<
VarDescBind
>>
vars_
;
DISABLE_COPY_AND_ASSIGN
(
BlockDescBind
);
};
};
}
// namespace framework
}
// namespace framework
}
// namespace paddle
}
// namespace paddle
paddle/framework/op_info.h
浏览文件 @
e0c8cd8a
...
@@ -20,6 +20,7 @@
...
@@ -20,6 +20,7 @@
#include "paddle/framework/attribute.h"
#include "paddle/framework/attribute.h"
#include "paddle/framework/op_desc.h"
#include "paddle/framework/op_desc.h"
#include "paddle/framework/type_defs.h"
#include "paddle/framework/type_defs.h"
#include "paddle/platform/macros.h"
namespace
paddle
{
namespace
paddle
{
namespace
framework
{
namespace
framework
{
...
@@ -67,11 +68,6 @@ class OpInfoMap {
...
@@ -67,11 +68,6 @@ class OpInfoMap {
public:
public:
static
OpInfoMap
&
Instance
();
static
OpInfoMap
&
Instance
();
OpInfoMap
(
const
OpInfoMap
&
o
)
=
delete
;
OpInfoMap
(
OpInfoMap
&&
o
)
=
delete
;
OpInfoMap
&
operator
=
(
const
OpInfoMap
&
o
)
=
delete
;
OpInfoMap
&
operator
=
(
OpInfoMap
&&
o
)
=
delete
;
bool
Has
(
const
std
::
string
&
op_type
)
const
{
bool
Has
(
const
std
::
string
&
op_type
)
const
{
return
map_
.
find
(
op_type
)
!=
map_
.
end
();
return
map_
.
find
(
op_type
)
!=
map_
.
end
();
}
}
...
@@ -107,6 +103,8 @@ class OpInfoMap {
...
@@ -107,6 +103,8 @@ class OpInfoMap {
private:
private:
OpInfoMap
()
=
default
;
OpInfoMap
()
=
default
;
std
::
unordered_map
<
std
::
string
,
const
OpInfo
>
map_
;
std
::
unordered_map
<
std
::
string
,
const
OpInfo
>
map_
;
DISABLE_COPY_AND_ASSIGN
(
OpInfoMap
);
};
};
}
// namespace framework
}
// namespace framework
...
...
paddle/framework/program_desc.h
浏览文件 @
e0c8cd8a
...
@@ -16,6 +16,7 @@ limitations under the License. */
...
@@ -16,6 +16,7 @@ limitations under the License. */
#include <vector>
#include <vector>
#include "paddle/framework/framework.pb.h"
#include "paddle/framework/framework.pb.h"
#include "paddle/platform/macros.h"
namespace
paddle
{
namespace
paddle
{
namespace
framework
{
namespace
framework
{
...
@@ -26,9 +27,6 @@ class ProgramDescBind {
...
@@ -26,9 +27,6 @@ class ProgramDescBind {
public:
public:
static
ProgramDescBind
&
Instance
(
ProgramDesc
*
prog
);
static
ProgramDescBind
&
Instance
(
ProgramDesc
*
prog
);
ProgramDescBind
(
const
ProgramDescBind
&
o
)
=
delete
;
ProgramDescBind
&
operator
=
(
const
ProgramDescBind
&
o
)
=
delete
;
BlockDescBind
*
AppendBlock
(
const
BlockDescBind
&
parent
);
BlockDescBind
*
AppendBlock
(
const
BlockDescBind
&
parent
);
BlockDescBind
*
Block
(
size_t
idx
)
{
return
blocks_
[
idx
].
get
();
}
BlockDescBind
*
Block
(
size_t
idx
)
{
return
blocks_
[
idx
].
get
();
}
...
@@ -46,6 +44,8 @@ class ProgramDescBind {
...
@@ -46,6 +44,8 @@ class ProgramDescBind {
ProgramDesc
*
prog_
;
ProgramDesc
*
prog_
;
std
::
vector
<
std
::
unique_ptr
<
BlockDescBind
>>
blocks_
;
std
::
vector
<
std
::
unique_ptr
<
BlockDescBind
>>
blocks_
;
DISABLE_COPY_AND_ASSIGN
(
ProgramDescBind
);
};
};
}
// namespace framework
}
// namespace framework
}
// namespace paddle
}
// namespace paddle
paddle/framework/scope.h
浏览文件 @
e0c8cd8a
...
@@ -19,6 +19,7 @@ limitations under the License. */
...
@@ -19,6 +19,7 @@ limitations under the License. */
#include <unordered_map>
#include <unordered_map>
#include "paddle/framework/variable.h"
#include "paddle/framework/variable.h"
#include "paddle/platform/macros.h"
namespace
paddle
{
namespace
paddle
{
namespace
framework
{
namespace
framework
{
...
@@ -38,11 +39,6 @@ class Scope {
...
@@ -38,11 +39,6 @@ class Scope {
Scope
()
{}
Scope
()
{}
~
Scope
();
~
Scope
();
// Disable Copy, Assign, Move.
Scope
(
const
Scope
&
other
)
=
delete
;
Scope
&
operator
=
(
const
Scope
&
other
)
=
delete
;
Scope
(
Scope
&&
other
)
=
delete
;
/// Create a sub-scope. Returns a reference other than a pointer so
/// Create a sub-scope. Returns a reference other than a pointer so
/// to prevent from manual deletion.
/// to prevent from manual deletion.
/// Mark it to const because that new kid scope cannot change parent scope.
/// Mark it to const because that new kid scope cannot change parent scope.
...
@@ -73,6 +69,8 @@ class Scope {
...
@@ -73,6 +69,8 @@ class Scope {
std
::
unordered_map
<
std
::
string
,
Variable
*>
vars_
;
std
::
unordered_map
<
std
::
string
,
Variable
*>
vars_
;
mutable
std
::
list
<
Scope
*>
kids_
;
mutable
std
::
list
<
Scope
*>
kids_
;
Scope
const
*
parent_
{
nullptr
};
Scope
const
*
parent_
{
nullptr
};
DISABLE_COPY_AND_ASSIGN
(
Scope
);
};
};
}
// namespace framework
}
// namespace framework
...
...
paddle/framework/tensor_array.h
浏览文件 @
e0c8cd8a
...
@@ -47,13 +47,6 @@ class TensorArray {
...
@@ -47,13 +47,6 @@ class TensorArray {
// max number of values allowed to store.
// max number of values allowed to store.
const
size_t
MAX_SIZE
{
100000
};
const
size_t
MAX_SIZE
{
100000
};
/*
* Inputs:
* - value_shared: share memory between tensors.
*/
explicit
TensorArray
(
bool
values_shared
=
true
)
:
values_shared_
(
values_shared
)
{}
/*
/*
* Read the value at location `index` in the `TensorArray`.
* Read the value at location `index` in the `TensorArray`.
*/
*/
...
@@ -111,7 +104,6 @@ class TensorArray {
...
@@ -111,7 +104,6 @@ class TensorArray {
private:
private:
mutable
std
::
vector
<
LoDTensor
>
values_
;
mutable
std
::
vector
<
LoDTensor
>
values_
;
bool
values_shared_
;
};
// class TensorArray
};
// class TensorArray
}
// namespace framework
}
// namespace framework
...
...
paddle/operators/recurrent_op.cc
浏览文件 @
e0c8cd8a
...
@@ -30,36 +30,39 @@ using LoDTensor = framework::LoDTensor;
...
@@ -30,36 +30,39 @@ using LoDTensor = framework::LoDTensor;
void
RecurrentAlgorithm
::
Run
(
const
Scope
&
scope
,
void
RecurrentAlgorithm
::
Run
(
const
Scope
&
scope
,
const
platform
::
DeviceContext
&
dev_ctx
)
const
{
const
platform
::
DeviceContext
&
dev_ctx
)
const
{
auto
step_scopes
=
GetStepScopes
(
scope
);
auto
*
input0
=
scope
.
FindVar
(
arg_
->
inlinks
[
0
]
);
rnn
::
SegmentInputs
(
step_scopes
,
arg_
->
inlinks
,
seq_len_
,
PADDLE_ENFORCE_NOT_NULL
(
input0
);
false
/*infer_shape_mode*/
)
;
size_t
seq_len
=
input0
->
GetMutable
<
LoDTensor
>
()
->
dims
()[
0
]
;
InitMemories
(
step_scopes
[
0
],
false
/*infer_shape_mode*/
);
PADDLE_ENFORCE_GT
(
seq_len
,
0
);
for
(
size_t
step_id
=
0
;
step_id
<
seq_len_
;
step_id
++
)
{
CreateScopes
(
scope
,
seq_len
);
// create output alias variables
auto
&
step_scopes
=
GetStepScopes
(
scope
);
rnn
::
SegmentInputs
(
step_scopes
,
arg_
->
inlinks
,
seq_len
);
InitMemories
(
step_scopes
[
0
]);
for
(
size_t
step_id
=
0
;
step_id
<
seq_len
;
step_id
++
)
{
if
(
step_id
>
0
)
{
if
(
step_id
>
0
)
{
rnn
::
LinkMemories
(
step_scopes
,
arg_
->
memories
,
step_id
,
-
1
,
rnn
::
LinkMemories
(
step_scopes
,
arg_
->
memories
,
step_id
,
-
1
);
false
/*infer_shape_mode*/
);
}
}
(
*
stepnet_
)
->
Run
(
*
step_scopes
[
step_id
],
dev_ctx
);
(
*
stepnet_
)
->
Run
(
*
step_scopes
[
step_id
],
dev_ctx
);
}
}
rnn
::
ConcatOutputs
(
step_scopes
,
arg_
->
outlinks
,
seq_len_
,
rnn
::
ConcatOutputs
(
step_scopes
,
arg_
->
outlinks
,
seq_len
);
false
/*infer_shape_mode*/
);
}
}
void
RecurrentAlgorithm
::
CreateScopes
(
const
Scope
&
scope
)
const
{
void
RecurrentAlgorithm
::
CreateScopes
(
const
Scope
&
scope
,
size_t
seq_len
)
const
{
// TODO(superjom) Only two scopes are needed for inference, this case will be
// TODO(superjom) Only two scopes are needed for inference, this case will be
// supported later.
// supported later.
auto
step_scopes_var
=
scope
.
FindVar
(
arg_
->
step_scopes
);
auto
*
step_scopes_var
=
scope
.
FindVar
(
arg_
->
step_scopes
);
PADDLE_ENFORCE
(
step_scopes_var
!=
nullptr
,
""
);
PADDLE_ENFORCE
(
step_scopes_var
!=
nullptr
,
""
);
auto
step_scopes
=
step_scopes_var
->
GetMutable
<
std
::
vector
<
Scope
*>>
();
auto
*
step_scopes
=
step_scopes_var
->
GetMutable
<
std
::
vector
<
Scope
*>>
();
// Now all variables in scope must be created outside of op.
// Now all variables in scope must be created outside of op.
PADDLE_ENFORCE_NOT_NULL
(
stepnet_
);
PADDLE_ENFORCE_NOT_NULL
(
stepnet_
);
PADDLE_ENFORCE
(
!
(
*
stepnet_
)
->
Outputs
().
empty
(),
"stepnet_ op has no outputs"
);
PADDLE_ENFORCE
(
!
(
*
stepnet_
)
->
Outputs
().
empty
(),
"stepnet_ op has no outputs"
);
if
(
seq_len
_
>
step_scopes
->
size
())
{
if
(
seq_len
>
step_scopes
->
size
())
{
for
(
size_t
i
=
step_scopes
->
size
();
i
<
seq_len
_
;
++
i
)
{
for
(
size_t
i
=
step_scopes
->
size
();
i
<
seq_len
;
++
i
)
{
auto
&
step_scope
=
scope
.
NewScope
();
auto
&
step_scope
=
scope
.
NewScope
();
// create step net's temp inputs
// create step net's temp inputs
...
@@ -82,8 +85,7 @@ void RecurrentAlgorithm::CreateScopes(const Scope& scope) const {
...
@@ -82,8 +85,7 @@ void RecurrentAlgorithm::CreateScopes(const Scope& scope) const {
}
}
}
}
void
RecurrentAlgorithm
::
InitMemories
(
Scope
*
step_scope
,
void
RecurrentAlgorithm
::
InitMemories
(
Scope
*
step_scope
)
const
{
bool
infer_shape_mode
)
const
{
for
(
auto
&
attr
:
arg_
->
memories
)
{
for
(
auto
&
attr
:
arg_
->
memories
)
{
auto
*
pre_mem
=
step_scope
->
NewVar
(
attr
.
pre_var
)
->
GetMutable
<
LoDTensor
>
();
auto
*
pre_mem
=
step_scope
->
NewVar
(
attr
.
pre_var
)
->
GetMutable
<
LoDTensor
>
();
PADDLE_ENFORCE
(
step_scope
->
FindVar
(
attr
.
boot_var
)
!=
nullptr
,
PADDLE_ENFORCE
(
step_scope
->
FindVar
(
attr
.
boot_var
)
!=
nullptr
,
...
@@ -91,12 +93,9 @@ void RecurrentAlgorithm::InitMemories(Scope* step_scope,
...
@@ -91,12 +93,9 @@ void RecurrentAlgorithm::InitMemories(Scope* step_scope,
attr
.
boot_var
);
attr
.
boot_var
);
auto
*
boot_mem
=
auto
*
boot_mem
=
step_scope
->
FindVar
(
attr
.
boot_var
)
->
GetMutable
<
LoDTensor
>
();
step_scope
->
FindVar
(
attr
.
boot_var
)
->
GetMutable
<
LoDTensor
>
();
if
(
infer_shape_mode
)
{
pre_mem
->
Resize
(
boot_mem
->
dims
());
pre_mem
->
Resize
(
boot_mem
->
dims
());
PADDLE_ENFORCE_EQ
(
pre_mem
->
dims
().
size
(),
2
);
PADDLE_ENFORCE_EQ
(
pre_mem
->
dims
().
size
(),
2
);
pre_mem
->
ShareDataWith
<
float
>
(
*
boot_mem
);
}
else
{
pre_mem
->
ShareDataWith
<
float
>
(
*
boot_mem
);
}
}
}
}
}
...
@@ -146,23 +145,23 @@ class RecurrentAlgorithmProtoAndCheckerMaker
...
@@ -146,23 +145,23 @@ class RecurrentAlgorithmProtoAndCheckerMaker
void
RecurrentGradientAlgorithm
::
Run
(
void
RecurrentGradientAlgorithm
::
Run
(
const
Scope
&
scope
,
const
platform
::
DeviceContext
&
dev_ctx
)
const
{
const
Scope
&
scope
,
const
platform
::
DeviceContext
&
dev_ctx
)
const
{
auto
step_scopes
=
GetStepScopes
(
scope
);
auto
*
input0
=
scope
.
FindVar
(
arg_
->
inlinks
[
0
]);
rnn
::
SegmentInputs
(
step_scopes
,
arg_
->
inlinks
,
seq_len_
,
PADDLE_ENFORCE_NOT_NULL
(
input0
);
false
/*infer_shape_mode*/
);
size_t
seq_len
=
input0
->
GetMutable
<
LoDTensor
>
()
->
dims
()[
0
];
for
(
int
step_id
=
seq_len_
-
1
;
step_id
>=
0
;
--
step_id
)
{
auto
&
step_scopes
=
GetStepScopes
(
scope
);
if
(
static_cast
<
size_t
>
(
step_id
)
!=
seq_len_
-
1
)
{
rnn
::
SegmentInputs
(
step_scopes
,
arg_
->
inlinks
,
seq_len
);
rnn
::
LinkMemories
(
step_scopes
,
arg_
->
memories
,
step_id
,
1
,
for
(
int
step_id
=
seq_len
-
1
;
step_id
>=
0
;
--
step_id
)
{
false
/*infer_shape_mode*/
);
if
(
step_id
!=
seq_len
-
1
)
{
rnn
::
LinkMemories
(
step_scopes
,
arg_
->
memories
,
step_id
,
1
);
}
}
(
*
stepnet_
)
->
Run
(
*
step_scopes
[
step_id
],
dev_ctx
);
(
*
stepnet_
)
->
Run
(
*
step_scopes
[
step_id
],
dev_ctx
);
}
}
LinkBootMemoryGradients
(
step_scopes
[
0
],
false
);
rnn
::
ConcatOutputs
(
step_scopes
,
arg_
->
outlinks
,
seq_len
);
rnn
::
ConcatOutputs
(
step_scopes
,
arg_
->
outlinks
,
seq_len_
,
LinkBootMemoryGradients
(
step_scopes
[
0
]);
false
/*infer_shape_mode*/
);
}
}
void
RecurrentGradientAlgorithm
::
LinkBootMemoryGradients
(
void
RecurrentGradientAlgorithm
::
LinkBootMemoryGradients
(
Scope
*
step_scope
,
bool
infer_shape_mode
)
const
{
Scope
*
step_scope
)
const
{
for
(
auto
&
attr
:
arg_
->
memories
)
{
for
(
auto
&
attr
:
arg_
->
memories
)
{
PADDLE_ENFORCE
(
step_scope
->
FindVar
(
attr
.
var
)
!=
nullptr
,
PADDLE_ENFORCE
(
step_scope
->
FindVar
(
attr
.
var
)
!=
nullptr
,
"memory variable [%s] does not exists"
,
attr
.
var
);
"memory variable [%s] does not exists"
,
attr
.
var
);
...
@@ -171,11 +170,8 @@ void RecurrentGradientAlgorithm::LinkBootMemoryGradients(
...
@@ -171,11 +170,8 @@ void RecurrentGradientAlgorithm::LinkBootMemoryGradients(
auto
*
mem_grad
=
step_scope
->
NewVar
(
attr
.
var
)
->
GetMutable
<
LoDTensor
>
();
auto
*
mem_grad
=
step_scope
->
NewVar
(
attr
.
var
)
->
GetMutable
<
LoDTensor
>
();
auto
*
boot_mem_grad
=
auto
*
boot_mem_grad
=
step_scope
->
NewVar
(
attr
.
boot_var
)
->
GetMutable
<
LoDTensor
>
();
step_scope
->
NewVar
(
attr
.
boot_var
)
->
GetMutable
<
LoDTensor
>
();
if
(
infer_shape_mode
)
{
boot_mem_grad
->
Resize
(
mem_grad
->
dims
());
boot_mem_grad
->
Resize
(
mem_grad
->
dims
());
boot_mem_grad
->
ShareDataWith
<
float
>
(
*
mem_grad
);
}
else
{
boot_mem_grad
->
ShareDataWith
<
float
>
(
*
mem_grad
);
}
}
}
}
}
...
...
paddle/operators/recurrent_op.h
浏览文件 @
e0c8cd8a
...
@@ -48,7 +48,7 @@ class RecurrentAlgorithm {
...
@@ -48,7 +48,7 @@ class RecurrentAlgorithm {
* NOTE the scopes are reused in both the forward and backward, so just
* NOTE the scopes are reused in both the forward and backward, so just
* create once and expand its size if more steps need.
* create once and expand its size if more steps need.
*/
*/
void
CreateScopes
(
const
framework
::
Scope
&
scope
)
const
;
void
CreateScopes
(
const
framework
::
Scope
&
scope
,
size_t
seq_len
)
const
;
const
std
::
vector
<
framework
::
Scope
*>&
GetStepScopes
(
const
std
::
vector
<
framework
::
Scope
*>&
GetStepScopes
(
const
framework
::
Scope
&
scope
)
const
{
const
framework
::
Scope
&
scope
)
const
{
...
@@ -56,12 +56,11 @@ class RecurrentAlgorithm {
...
@@ -56,12 +56,11 @@ class RecurrentAlgorithm {
->
GetMutable
<
std
::
vector
<
framework
::
Scope
*>>
();
->
GetMutable
<
std
::
vector
<
framework
::
Scope
*>>
();
}
}
void
InitMemories
(
framework
::
Scope
*
step_scopes
,
bool
infer_shape_mode
)
const
;
void
InitMemories
(
framework
::
Scope
*
step_scopes
)
const
;
private:
private:
std
::
unique_ptr
<
framework
::
OperatorBase
>*
stepnet_
;
std
::
unique_ptr
<
framework
::
OperatorBase
>*
stepnet_
;
rnn
::
Argument
*
arg_
;
rnn
::
Argument
*
arg_
;
mutable
size_t
seq_len_
;
};
};
class
RecurrentGradientAlgorithm
{
class
RecurrentGradientAlgorithm
{
...
@@ -86,8 +85,7 @@ class RecurrentGradientAlgorithm {
...
@@ -86,8 +85,7 @@ class RecurrentGradientAlgorithm {
void
Run
(
const
framework
::
Scope
&
scope
,
void
Run
(
const
framework
::
Scope
&
scope
,
const
platform
::
DeviceContext
&
dev_ctx
)
const
;
const
platform
::
DeviceContext
&
dev_ctx
)
const
;
void
LinkBootMemoryGradients
(
framework
::
Scope
*
step_scopes
,
void
LinkBootMemoryGradients
(
framework
::
Scope
*
step_scopes
)
const
;
bool
infer_shape_mode
)
const
;
protected:
protected:
inline
const
std
::
vector
<
framework
::
Scope
*>&
GetStepScopes
(
inline
const
std
::
vector
<
framework
::
Scope
*>&
GetStepScopes
(
...
@@ -98,7 +96,6 @@ class RecurrentGradientAlgorithm {
...
@@ -98,7 +96,6 @@ class RecurrentGradientAlgorithm {
private:
private:
rnn
::
Argument
*
arg_
;
rnn
::
Argument
*
arg_
;
mutable
size_t
seq_len_
;
std
::
unique_ptr
<
framework
::
OperatorBase
>*
stepnet_
;
std
::
unique_ptr
<
framework
::
OperatorBase
>*
stepnet_
;
};
};
...
@@ -123,6 +120,7 @@ class RecurrentOp : public framework::OperatorBase {
...
@@ -123,6 +120,7 @@ class RecurrentOp : public framework::OperatorBase {
void
set_stepnet
(
std
::
unique_ptr
<
OperatorBase
>
net
)
{
void
set_stepnet
(
std
::
unique_ptr
<
OperatorBase
>
net
)
{
stepnet_
=
std
::
move
(
net
);
stepnet_
=
std
::
move
(
net
);
}
}
const
OperatorBase
&
stepnet
()
const
{
return
*
stepnet_
;
}
const
OperatorBase
&
stepnet
()
const
{
return
*
stepnet_
;
}
static
const
rnn
::
ArgumentName
kArgName
;
static
const
rnn
::
ArgumentName
kArgName
;
...
...
paddle/operators/rnn/recurrent_op_utils.cc
浏览文件 @
e0c8cd8a
...
@@ -25,7 +25,7 @@ using LoDTensor = framework::LoDTensor;
...
@@ -25,7 +25,7 @@ using LoDTensor = framework::LoDTensor;
void
SegmentInputs
(
const
std
::
vector
<
Scope
*>&
step_scopes
,
void
SegmentInputs
(
const
std
::
vector
<
Scope
*>&
step_scopes
,
const
std
::
vector
<
std
::
string
>&
inlinks
,
const
std
::
vector
<
std
::
string
>&
inlinks
,
const
size_t
seq_len
,
bool
infer_shape_mode
)
{
const
size_t
seq_len
)
{
PADDLE_ENFORCE
(
!
inlinks
.
empty
(),
"no in links are provided."
);
PADDLE_ENFORCE
(
!
inlinks
.
empty
(),
"no in links are provided."
);
for
(
size_t
i
=
0
;
i
<
inlinks
.
size
();
++
i
)
{
for
(
size_t
i
=
0
;
i
<
inlinks
.
size
();
++
i
)
{
// global inputs
// global inputs
...
@@ -41,11 +41,9 @@ void SegmentInputs(const std::vector<Scope*>& step_scopes,
...
@@ -41,11 +41,9 @@ void SegmentInputs(const std::vector<Scope*>& step_scopes,
for
(
size_t
j
=
0
;
j
<
seq_len
;
j
++
)
{
for
(
size_t
j
=
0
;
j
<
seq_len
;
j
++
)
{
Tensor
*
step_input
=
Tensor
*
step_input
=
step_scopes
[
j
]
->
NewVar
(
inlinks
[
i
])
->
GetMutable
<
Tensor
>
();
step_scopes
[
j
]
->
NewVar
(
inlinks
[
i
])
->
GetMutable
<
Tensor
>
();
if
(
!
infer_shape_mode
)
{
// The input of operators of each step is Tensor here.
// The input of operators of each step is Tensor here.
// Maybe need to modify Slice function.
// Maybe need to modify Slice function.
*
step_input
=
input
->
Slice
<
float
>
(
j
,
j
+
1
);
*
step_input
=
input
->
Slice
<
float
>
(
j
,
j
+
1
);
}
step_input
->
Resize
(
step_dims
);
step_input
->
Resize
(
step_dims
);
}
}
}
}
...
@@ -53,39 +51,35 @@ void SegmentInputs(const std::vector<Scope*>& step_scopes,
...
@@ -53,39 +51,35 @@ void SegmentInputs(const std::vector<Scope*>& step_scopes,
void
ConcatOutputs
(
const
std
::
vector
<
Scope
*>&
step_scopes
,
void
ConcatOutputs
(
const
std
::
vector
<
Scope
*>&
step_scopes
,
const
std
::
vector
<
std
::
string
>&
outlinks
,
const
std
::
vector
<
std
::
string
>&
outlinks
,
const
size_t
seq_len
,
bool
infer_shape_mode
)
{
const
size_t
seq_len
)
{
for
(
size_t
i
=
0
;
i
<
outlinks
.
size
();
i
++
)
{
for
(
size_t
i
=
0
;
i
<
outlinks
.
size
();
i
++
)
{
auto
output_var
=
step_scopes
[
0
]
->
parent
().
FindVar
(
outlinks
[
i
]);
auto
*
output_var
=
step_scopes
[
0
]
->
parent
().
FindVar
(
outlinks
[
i
]);
PADDLE_ENFORCE_NOT_NULL
(
output_var
,
"output link [%s] is not in scope."
,
PADDLE_ENFORCE_NOT_NULL
(
output_var
,
"output link [%s] is not in scope."
,
outlinks
[
i
]);
outlinks
[
i
]);
LoDTensor
*
output
=
output_var
->
GetMutable
<
LoDTensor
>
();
LoDTensor
*
output
=
output_var
->
GetMutable
<
LoDTensor
>
();
if
(
infer_shape_mode
)
{
auto
*
step_scope_var
=
step_scopes
[
0
]
->
FindVar
(
outlinks
[
i
]);
auto
step_scope_var
=
step_scopes
[
0
]
->
FindVar
(
outlinks
[
i
]);
PADDLE_ENFORCE_NOT_NULL
(
step_scope_var
,
"%s not in scope"
,
outlinks
[
i
]);
PADDLE_ENFORCE_NOT_NULL
(
step_scope_var
,
"%s not in scope"
,
outlinks
[
i
]);
f
::
DDim
step_dims
=
f
::
DDim
step_dims
=
step_scope_var
->
template
GetMutable
<
LoDTensor
>()
->
dims
();
step_scope_var
->
template
GetMutable
<
LoDTensor
>()
->
dims
();
std
::
vector
<
int64_t
>
dims_vec
=
vectorize
(
step_dims
);
std
::
vector
<
int64_t
>
dims_vec
=
vectorize
(
step_dims
);
dims_vec
.
insert
(
dims_vec
.
begin
(),
seq_len
);
dims_vec
.
insert
(
dims_vec
.
begin
(),
seq_len
);
output
->
Resize
(
f
::
make_ddim
(
dims_vec
));
output
->
Resize
(
f
::
make_ddim
(
dims_vec
));
output
->
mutable_data
<
float
>
(
platform
::
CPUPlace
());
}
else
{
for
(
size_t
j
=
0
;
j
<
seq_len
;
j
++
)
{
output
->
mutable_data
<
float
>
(
platform
::
CPUPlace
());
LoDTensor
*
step_output
=
for
(
size_t
j
=
0
;
j
<
seq_len
;
j
++
)
{
step_scopes
[
j
]
->
FindVar
(
outlinks
[
i
])
->
GetMutable
<
LoDTensor
>
();
LoDTensor
*
step_output
=
// TODO(luotao02) data type and platform::DeviceContext() should set
step_scopes
[
j
]
->
FindVar
(
outlinks
[
i
])
->
GetMutable
<
LoDTensor
>
();
// correctly
// TODO(luotao02) data type and platform::DeviceContext() should set
(
output
->
Slice
<
float
>
(
j
,
j
+
1
))
// correctly
.
CopyFrom
<
float
>
(
*
step_output
,
platform
::
CPUPlace
());
(
output
->
Slice
<
float
>
(
j
,
j
+
1
))
.
CopyFrom
<
float
>
(
*
step_output
,
platform
::
CPUPlace
());
}
}
}
}
}
}
}
void
LinkMemories
(
const
std
::
vector
<
Scope
*>&
scopes
,
void
LinkMemories
(
const
std
::
vector
<
Scope
*>&
scopes
,
const
std
::
vector
<
rnn
::
MemoryAttr
>&
memories
,
const
std
::
vector
<
rnn
::
MemoryAttr
>&
memories
,
const
size_t
step_id
,
const
int
offset
,
const
size_t
step_id
,
const
int
offset
)
{
bool
infer_shape_mode
)
{
PADDLE_ENFORCE_LT
(
step_id
,
scopes
.
size
(),
PADDLE_ENFORCE_LT
(
step_id
,
scopes
.
size
(),
"step [%d] is out of range of step scopes' size [%d]"
,
"step [%d] is out of range of step scopes' size [%d]"
,
step_id
,
scopes
.
size
());
step_id
,
scopes
.
size
());
...
@@ -95,16 +89,13 @@ void LinkMemories(const std::vector<Scope*>& scopes,
...
@@ -95,16 +89,13 @@ void LinkMemories(const std::vector<Scope*>& scopes,
step_id
+
offset
,
scopes
.
size
(),
step_id
+
offset
,
scopes
.
size
(),
"offset [%d] is out of range, it must be less than (%d - %d)"
,
offset
,
"offset [%d] is out of range, it must be less than (%d - %d)"
,
offset
,
scopes
.
size
(),
step_id
);
scopes
.
size
(),
step_id
);
auto
scope
=
scopes
[
step_id
];
auto
*
scope
=
scopes
[
step_id
];
auto
linked_scope
=
scopes
[
step_id
+
offset
];
auto
*
linked_scope
=
scopes
[
step_id
+
offset
];
for
(
auto
&
attr
:
memories
)
{
for
(
auto
&
attr
:
memories
)
{
auto
mem
=
scope
->
FindVar
(
attr
.
pre_var
)
->
GetMutable
<
LoDTensor
>
();
auto
*
mem
=
scope
->
FindVar
(
attr
.
pre_var
)
->
GetMutable
<
LoDTensor
>
();
auto
linked_mem
=
linked_scope
->
FindVar
(
attr
.
var
)
->
GetMutable
<
LoDTensor
>
();
auto
*
linked_mem
=
linked_scope
->
FindVar
(
attr
.
var
)
->
GetMutable
<
LoDTensor
>
();
if
(
infer_shape_mode
)
{
mem
->
Resize
(
linked_mem
->
dims
());
mem
->
Resize
(
linked_mem
->
dims
());
mem
->
ShareDataWith
<
float
>
(
*
linked_mem
);
}
else
{
mem
->
ShareDataWith
<
float
>
(
*
linked_mem
);
}
}
}
}
}
...
@@ -115,11 +106,11 @@ void InitArgument(const ArgumentName& name, Argument* arg,
...
@@ -115,11 +106,11 @@ void InitArgument(const ArgumentName& name, Argument* arg,
arg
->
inlinks
=
op
.
Inputs
(
name
.
inlinks
);
arg
->
inlinks
=
op
.
Inputs
(
name
.
inlinks
);
arg
->
outlinks
=
op
.
Outputs
(
name
.
outlinks
);
arg
->
outlinks
=
op
.
Outputs
(
name
.
outlinks
);
auto
boot_memories
=
auto
&
boot_memories
=
is_grad
?
op
.
Outputs
(
name
.
boot_memories
)
:
op
.
Inputs
(
name
.
boot_memories
);
is_grad
?
op
.
Outputs
(
name
.
boot_memories
)
:
op
.
Inputs
(
name
.
boot_memories
);
// attributes
// attributes
auto
memories
=
op
.
Attr
<
std
::
vector
<
std
::
string
>>
(
name
.
memories
);
auto
&
memories
=
op
.
Attr
<
std
::
vector
<
std
::
string
>>
(
name
.
memories
);
auto
pre_memories
=
op
.
Attr
<
std
::
vector
<
std
::
string
>>
(
name
.
pre_memories
);
auto
&
pre_memories
=
op
.
Attr
<
std
::
vector
<
std
::
string
>>
(
name
.
pre_memories
);
PADDLE_ENFORCE
(
memories
.
size
()
==
boot_memories
.
size
(),
PADDLE_ENFORCE
(
memories
.
size
()
==
boot_memories
.
size
(),
"the size of memories, boot_memories don't match:%d,%d"
,
"the size of memories, boot_memories don't match:%d,%d"
,
...
...
paddle/operators/rnn/recurrent_op_utils.h
浏览文件 @
e0c8cd8a
...
@@ -64,18 +64,18 @@ struct ArgumentName {
...
@@ -64,18 +64,18 @@ struct ArgumentName {
*/
*/
void
SegmentInputs
(
const
std
::
vector
<
Scope
*>&
step_scopes
,
void
SegmentInputs
(
const
std
::
vector
<
Scope
*>&
step_scopes
,
const
std
::
vector
<
std
::
string
>&
inlinks
,
const
std
::
vector
<
std
::
string
>&
inlinks
,
const
size_t
seq_len
,
bool
infer_shape_mode
);
const
size_t
seq_len
);
/**
/**
* Process outputs of step nets and merge to variables.
* Process outputs of step nets and merge to variables.
*/
*/
void
ConcatOutputs
(
const
std
::
vector
<
Scope
*>&
step_scopes
,
void
ConcatOutputs
(
const
std
::
vector
<
Scope
*>&
step_scopes
,
const
std
::
vector
<
std
::
string
>&
outlinks
,
const
std
::
vector
<
std
::
string
>&
outlinks
,
const
size_t
seq_len
,
bool
infer_shape_mode
);
const
size_t
seq_len
);
void
LinkMemories
(
const
std
::
vector
<
Scope
*>&
step_scopes
,
void
LinkMemories
(
const
std
::
vector
<
Scope
*>&
step_scopes
,
const
std
::
vector
<
MemoryAttr
>&
memories
,
const
size_t
step_id
,
const
std
::
vector
<
MemoryAttr
>&
memories
,
const
size_t
step_id
,
const
int
offset
,
bool
infer_shape_mode
);
const
int
offset
);
void
InitArgument
(
const
ArgumentName
&
name
,
Argument
*
arg
,
void
InitArgument
(
const
ArgumentName
&
name
,
Argument
*
arg
,
const
framework
::
OperatorBase
&
op
,
bool
is_grad
=
false
);
const
framework
::
OperatorBase
&
op
,
bool
is_grad
=
false
);
...
...
paddle/operators/sum_op.cc
浏览文件 @
e0c8cd8a
...
@@ -22,14 +22,15 @@ class SumOp : public framework::OperatorWithKernel {
...
@@ -22,14 +22,15 @@ class SumOp : public framework::OperatorWithKernel {
protected:
protected:
void
InferShape
(
framework
::
InferShapeContextBase
*
ctx
)
const
override
{
void
InferShape
(
framework
::
InferShapeContextBase
*
ctx
)
const
override
{
PADDLE_ENFORCE
(
ctx
->
HasInputs
(
"X"
),
"Inputs(X) should not be null"
);
auto
x_dims
=
ctx
->
GetInputsDim
(
"X"
);
auto
x_dims
=
ctx
->
GetInputsDim
(
"X"
);
PADDLE_ENFORCE
(
!
x_dims
.
empty
(),
"Input(X) of SumOp should not be null."
);
PADDLE_ENFORCE
(
ctx
->
HasOutput
(
"Out"
),
PADDLE_ENFORCE
(
ctx
->
HasOutput
(
"Out"
),
"Output(Out) of SumOp should not be null."
);
"Output(Out) of SumOp should not be null."
);
auto
in_dim
=
x_dims
[
0
];
size_t
N
=
x_dims
.
size
();
size_t
N
=
x_dims
.
size
();
PADDLE_ENFORCE_GT
(
N
,
1
,
"Input tensors count should > 1."
);
PADDLE_ENFORCE_GT
(
N
,
1
,
"Input tensors count should > 1."
);
auto
in_dim
=
x_dims
[
0
];
for
(
size_t
i
=
1
;
i
<
N
;
i
++
)
{
for
(
size_t
i
=
1
;
i
<
N
;
i
++
)
{
auto
dim
=
x_dims
[
i
];
auto
dim
=
x_dims
[
i
];
PADDLE_ENFORCE
(
in_dim
==
dim
,
"Input tensors must have same shape"
);
PADDLE_ENFORCE
(
in_dim
==
dim
,
"Input tensors must have same shape"
);
...
...
paddle/platform/macros.h
浏览文件 @
e0c8cd8a
...
@@ -16,8 +16,10 @@ limitations under the License. */
...
@@ -16,8 +16,10 @@ limitations under the License. */
// Disable the copy and assignment operator for a class.
// Disable the copy and assignment operator for a class.
#ifndef DISABLE_COPY_AND_ASSIGN
#ifndef DISABLE_COPY_AND_ASSIGN
#define DISABLE_COPY_AND_ASSIGN(classname) \
#define DISABLE_COPY_AND_ASSIGN(classname) \
private: \
private: \
classname(const classname&) = delete; \
classname(const classname&) = delete; \
classname& operator=(const classname&) = delete
classname(const classname&&) = delete; \
classname& operator=(const classname&) = delete; \
classname& operator=(const classname&&) = delete
#endif
#endif
python/paddle/v2/framework/tests/test_recurrent_op.py
浏览文件 @
e0c8cd8a
...
@@ -16,14 +16,17 @@ class PySimpleRNN(object):
...
@@ -16,14 +16,17 @@ class PySimpleRNN(object):
'''
'''
def
__init__
(
self
,
input_dim
=
30
,
batch_size
=
50
,
weight_dim
=
15
,
sent_len
=
11
):
def
__init__
(
self
,
input_dim
=
30
,
batch_size
=
50
,
weight_dim
=
15
,
sent_len
=
11
):
self
.
x
=
np
.
random
.
normal
(
size
=
(
sent_len
,
batch_size
,
input_dim
))
self
.
x
=
np
.
random
.
normal
(
size
=
(
sent_len
,
batch_size
,
self
.
W
=
np
.
random
.
normal
(
size
=
(
input_dim
,
input_dim
))
input_dim
)).
astype
(
"float32"
)
self
.
U
=
np
.
random
.
normal
(
size
=
(
input_dim
,
input_dim
))
self
.
W
=
np
.
random
.
normal
(
size
=
(
input_dim
,
input_dim
)).
astype
(
"float32"
)
self
.
h_boot
=
np
.
random
.
normal
(
size
=
(
batch_size
,
input_dim
))
self
.
U
=
np
.
random
.
normal
(
size
=
(
input_dim
,
input_dim
)).
astype
(
"float32"
)
self
.
h_boot
=
np
.
random
.
normal
(
size
=
(
batch_size
,
input_dim
)).
astype
(
"float32"
)
# memories
# memories
self
.
mems
=
[
self
.
mems
=
[
np
.
zeros
(
shape
=
(
batch_size
,
input_dim
))
for
i
in
range
(
sent_len
)
np
.
zeros
(
shape
=
(
batch_size
,
input_dim
)).
astype
(
"float32"
)
for
i
in
range
(
sent_len
)
]
]
def
forward
(
self
):
def
forward
(
self
):
...
@@ -36,7 +39,7 @@ class PySimpleRNN(object):
...
@@ -36,7 +39,7 @@ class PySimpleRNN(object):
return
[
self
.
x
[
i
]
for
i
in
range
(
self
.
x
.
shape
[
0
])]
return
[
self
.
x
[
i
]
for
i
in
range
(
self
.
x
.
shape
[
0
])]
def
concat_outputs
(
self
):
def
concat_outputs
(
self
):
return
np
.
array
(
self
.
mems
)
return
np
.
array
(
self
.
mems
)
.
astype
(
"float32"
)
def
step
(
self
,
step_id
,
x
):
def
step
(
self
,
step_id
,
x
):
'''
'''
...
@@ -47,8 +50,8 @@ class PySimpleRNN(object):
...
@@ -47,8 +50,8 @@ class PySimpleRNN(object):
pre_mem
=
self
.
mems
[
step_id
-
1
]
pre_mem
=
self
.
mems
[
step_id
-
1
]
else
:
else
:
pre_mem
=
self
.
h_boot
pre_mem
=
self
.
h_boot
xW
=
np
.
matmul
(
x
,
self
.
W
)
xW
=
np
.
matmul
(
x
,
self
.
W
)
.
astype
(
"float32"
)
hU
=
np
.
matmul
(
pre_mem
,
self
.
U
)
hU
=
np
.
matmul
(
pre_mem
,
self
.
U
)
.
astype
(
"float32"
)
sum
=
xW
+
hU
sum
=
xW
+
hU
self
.
mems
[
step_id
]
=
py_sigmoid
(
sum
)
self
.
mems
[
step_id
]
=
py_sigmoid
(
sum
)
...
@@ -102,7 +105,8 @@ class RecurrentOpTest(unittest.TestCase):
...
@@ -102,7 +105,8 @@ class RecurrentOpTest(unittest.TestCase):
self
.
create_step_net
()
self
.
create_step_net
()
ctx
=
core
.
DeviceContext
.
create
(
core
.
CPUPlace
())
ctx
=
core
.
DeviceContext
.
create
(
core
.
CPUPlace
())
self
.
rnnop
.
run
(
self
.
scope
,
ctx
)
self
.
rnnop
.
run
(
self
.
scope
,
ctx
)
return
np
.
array
(
self
.
scope
.
find_var
(
"h@mem"
).
get_tensor
())
return
np
.
array
(
self
.
scope
.
find_var
(
"h@mem"
).
get_tensor
()).
astype
(
"float32"
)
def
create_global_variables
(
self
):
def
create_global_variables
(
self
):
# create inlink
# create inlink
...
@@ -142,7 +146,7 @@ class RecurrentOpTest(unittest.TestCase):
...
@@ -142,7 +146,7 @@ class RecurrentOpTest(unittest.TestCase):
stepnet
=
core
.
Net
.
create
()
stepnet
=
core
.
Net
.
create
()
x_fc_op
=
Operator
(
"mul"
,
X
=
"x"
,
Y
=
"W"
,
Out
=
"Wx"
)
x_fc_op
=
Operator
(
"mul"
,
X
=
"x"
,
Y
=
"W"
,
Out
=
"Wx"
)
h_fc_op
=
Operator
(
"mul"
,
X
=
"h@pre"
,
Y
=
"U"
,
Out
=
"Uh"
)
h_fc_op
=
Operator
(
"mul"
,
X
=
"h@pre"
,
Y
=
"U"
,
Out
=
"Uh"
)
sum_op
=
Operator
(
"
add"
,
X
=
"Wx"
,
Y
=
"Uh"
,
Out
=
"sum"
)
sum_op
=
Operator
(
"
sum"
,
X
=
[
"Wx"
,
"Uh"
]
,
Out
=
"sum"
)
sig_op
=
Operator
(
"sigmoid"
,
X
=
"sum"
,
Y
=
"h@mem"
)
sig_op
=
Operator
(
"sigmoid"
,
X
=
"sum"
,
Y
=
"h@mem"
)
for
op
in
[
x_fc_op
,
h_fc_op
,
sum_op
,
sig_op
]:
for
op
in
[
x_fc_op
,
h_fc_op
,
sum_op
,
sig_op
]:
...
@@ -179,7 +183,7 @@ class RecurrentGradientOpTest(unittest.TestCase):
...
@@ -179,7 +183,7 @@ class RecurrentGradientOpTest(unittest.TestCase):
stepnet
=
core
.
Net
.
create
()
stepnet
=
core
.
Net
.
create
()
x_fc_op
=
Operator
(
"mul"
,
X
=
"x@alias"
,
Y
=
"W"
,
Out
=
"Wx"
)
x_fc_op
=
Operator
(
"mul"
,
X
=
"x@alias"
,
Y
=
"W"
,
Out
=
"Wx"
)
h_fc_op
=
Operator
(
"mul"
,
X
=
"h@pre"
,
Y
=
"U"
,
Out
=
"Uh"
)
h_fc_op
=
Operator
(
"mul"
,
X
=
"h@pre"
,
Y
=
"U"
,
Out
=
"Uh"
)
sum_op
=
Operator
(
"
add"
,
X
=
"Wx"
,
Y
=
"Uh"
,
Out
=
"sum"
)
sum_op
=
Operator
(
"
sum"
,
X
=
[
"Wx"
,
"Uh"
]
,
Out
=
"sum"
)
sig_op
=
Operator
(
"sigmoid"
,
X
=
"sum"
,
Y
=
"h@alias"
)
sig_op
=
Operator
(
"sigmoid"
,
X
=
"sum"
,
Y
=
"h@alias"
)
for
op
in
[
x_fc_op
,
h_fc_op
,
sum_op
,
sig_op
]:
for
op
in
[
x_fc_op
,
h_fc_op
,
sum_op
,
sig_op
]:
...
@@ -197,7 +201,4 @@ class RecurrentGradientOpTest(unittest.TestCase):
...
@@ -197,7 +201,4 @@ class RecurrentGradientOpTest(unittest.TestCase):
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
exit
(
0
)
# FIXME(yuyang18): InferShape has been removed, this unittest may error
unittest
.
main
()
unittest
.
main
()
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录