Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
PaddleDetection
提交
93006787
P
PaddleDetection
项目概览
PaddlePaddle
/
PaddleDetection
大约 1 年 前同步成功
通知
695
Star
11112
Fork
2696
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
184
列表
看板
标记
里程碑
合并请求
40
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleDetection
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
184
Issue
184
列表
看板
标记
里程碑
合并请求
40
合并请求
40
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
93006787
编写于
9月 13, 2016
作者:
E
emailweixu
提交者:
GitHub
9月 13, 2016
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #73 from reyoung/merge_icode
Merge Baidu Internal Changes.
上级
487dc670
c7762da3
变更
26
隐藏空白更改
内联
并排
Showing
26 changed file
with
487 addition
and
138 deletion
+487
-138
doc/build/index.rst
doc/build/index.rst
+1
-0
doc/cluster/index.rst
doc/cluster/index.rst
+1
-0
doc_cn/build_and_install/index.rst
doc_cn/build_and_install/index.rst
+4
-0
doc_cn/cluster/index.rst
doc_cn/cluster/index.rst
+11
-0
doc_cn/index.rst
doc_cn/index.rst
+1
-1
paddle/gserver/evaluators/CTCErrorEvaluator.cpp
paddle/gserver/evaluators/CTCErrorEvaluator.cpp
+2
-2
paddle/gserver/gradientmachines/RecurrentGradientMachine.cpp
paddle/gserver/gradientmachines/RecurrentGradientMachine.cpp
+175
-98
paddle/gserver/gradientmachines/RecurrentGradientMachine.h
paddle/gserver/gradientmachines/RecurrentGradientMachine.h
+34
-13
paddle/gserver/layers/CTCLayer.cpp
paddle/gserver/layers/CTCLayer.cpp
+5
-3
paddle/gserver/layers/ConvOperator.cpp
paddle/gserver/layers/ConvOperator.cpp
+1
-1
paddle/gserver/layers/CostLayer.cpp
paddle/gserver/layers/CostLayer.cpp
+3
-1
paddle/gserver/layers/SamplingIdLayer.cpp
paddle/gserver/layers/SamplingIdLayer.cpp
+3
-1
paddle/gserver/tests/LayerGradUtil.cpp
paddle/gserver/tests/LayerGradUtil.cpp
+0
-2
paddle/gserver/tests/Sequence/dummy.list
paddle/gserver/tests/Sequence/dummy.list
+1
-0
paddle/gserver/tests/rnn_data_provider.py
paddle/gserver/tests/rnn_data_provider.py
+35
-0
paddle/gserver/tests/sequenceGen.py
paddle/gserver/tests/sequenceGen.py
+0
-3
paddle/gserver/tests/sequence_nest_rnn.conf
paddle/gserver/tests/sequence_nest_rnn.conf
+75
-0
paddle/gserver/tests/sequence_rnn.conf
paddle/gserver/tests/sequence_rnn.conf
+57
-0
paddle/gserver/tests/test_RecurrentGradientMachine.cpp
paddle/gserver/tests/test_RecurrentGradientMachine.cpp
+17
-4
paddle/gserver/tests/test_RecurrentLayer.cpp
paddle/gserver/tests/test_RecurrentLayer.cpp
+0
-1
paddle/math/Matrix.cpp
paddle/math/Matrix.cpp
+2
-0
paddle/math/Vector.cpp
paddle/math/Vector.cpp
+1
-0
paddle/parameter/Argument.cpp
paddle/parameter/Argument.cpp
+15
-1
paddle/parameter/Argument.h
paddle/parameter/Argument.h
+28
-4
proto/ModelConfig.proto.m4
proto/ModelConfig.proto.m4
+3
-0
python/paddle/trainer/config_parser.py
python/paddle/trainer/config_parser.py
+12
-3
未找到文件。
doc/build/index.rst
浏览文件 @
93006787
...
...
@@ -9,6 +9,7 @@ Install PaddlePaddle
:glob:
install_*
internal/install_from_jumbo.md
Build from Source
-----------------
...
...
doc/cluster/index.rst
浏览文件 @
93006787
...
...
@@ -5,3 +5,4 @@ Cluster Train
:glob:
opensource/cluster_train.md
internal/index.md
doc_cn/build_and_install/index.rst
浏览文件 @
93006787
...
...
@@ -9,7 +9,11 @@ Note: The intallation packages are still in pre-release state and your experienc
.. toctree::
:maxdepth: 1
:glob:
源码下载(对内) <../build/internal/download_paddle_source_zh_cn.rst>
使用Jumbo安装(对内) <../build/internal/install_from_jumbo.rst>
从源码编译安装(对内) <../build/internal/build_from_source_zh_cn.rst>
install/docker_install.rst
install/ubuntu_install.rst
cmake/index.rst
doc_cn/cluster/index.rst
0 → 100644
浏览文件 @
93006787
集群训练
========
* `集群训练 <../../doc/cluster/index.html>`_
.. toctree::
:maxdepth: 2
:glob:
集群训练(对内) <internal/index.md>
doc_cn/index.rst
浏览文件 @
93006787
...
...
@@ -8,7 +8,7 @@ PaddlePaddle文档
* `用户接口 <ui/index.html>`_
* `使用示例 <demo/index.html>`_
* `模型配置 <../doc/ui/api/trainer_config_helpers/index.html>`_
* `集群训练 <
../doc/
cluster/index.html>`_
* `集群训练 <cluster/index.html>`_
开发指南
--------
...
...
paddle/gserver/evaluators/CTCErrorEvaluator.cpp
浏览文件 @
93006787
...
...
@@ -194,8 +194,8 @@ public:
virtual
real
evalImp
(
std
::
vector
<
Argument
>&
arguments
)
{
CHECK_EQ
(
arguments
.
size
(),
(
size_t
)
2
);
Argument
output
,
label
;
output
.
resizeAndCopyFrom
(
arguments
[
0
],
false
);
label
.
resizeAndCopyFrom
(
arguments
[
1
],
false
);
output
.
resizeAndCopyFrom
(
arguments
[
0
],
false
,
HPPL_STREAM_DEFAULT
);
label
.
resizeAndCopyFrom
(
arguments
[
1
],
false
,
HPPL_STREAM_DEFAULT
);
hl_stream_synchronize
(
HPPL_STREAM_DEFAULT
);
CHECK
(
label
.
sequenceStartPositions
);
CHECK
(
label
.
ids
);
...
...
paddle/gserver/gradientmachines/RecurrentGradientMachine.cpp
浏览文件 @
93006787
...
...
@@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#include "paddle/utils/Stat.h"
#include "paddle/utils/Util.h"
#include "paddle/utils/Flags.h"
...
...
@@ -291,6 +290,8 @@ void RecurrentGradientMachine::init(
if
(
subModelConfig
->
evaluator_names_size
()
>
0
)
{
evaluator_
.
reset
(
frames_
[
0
]
->
makeEvaluator
());
}
targetInfoInlinkId_
=
subModelConfig
->
target_inlinkid
();
}
void
RecurrentGradientMachine
::
resizeOrCreateFrames
(
int
numFrames
)
{
...
...
@@ -325,7 +326,7 @@ void RecurrentGradientMachine::resizeOrCreateFrames(int numFrames) {
for
(
int
i
=
frames_
.
size
();
i
<
numFrames
;
++
i
)
{
std
::
unique_ptr
<
NeuralNetwork
>
frame
(
NeuralNetwork
::
newNeuralNetwork
(
subModelName_
));
NeuralNetwork
::
newNeuralNetwork
(
subModelName_
));
frame
->
init
(
config_
,
subParamInitCb
);
for
(
auto
&
inFrameLine
:
inFrameLines_
)
{
...
...
@@ -382,6 +383,16 @@ void RecurrentGradientMachine::forward(const std::vector<Argument>& inArgs,
size_t
numSequences
=
input
.
getNumSequences
();
const
int
*
starts
=
input
.
sequenceStartPositions
->
getData
(
false
);
bool
hasSubseq
=
input
.
hasSubseq
();
// In case of !hasSubseq or targetInfoInlinkId_ == -1, all inlinks share the
// same inframe info
bool
shareInlinkInfo
=
!
hasSubseq
||
targetInfoInlinkId_
==
-
1
;
// Defaultly, share info with the first inlink
if
(
shareInlinkInfo
)
{
targetInfoInlinkId_
=
0
;
}
// check hasSubseq in both config and input are the same
CHECK_EQ
(
hasSubseq
,
inFrameLines_
[
0
].
hasSubseq
);
...
...
@@ -394,9 +405,17 @@ void RecurrentGradientMachine::forward(const std::vector<Argument>& inArgs,
CHECK_EQ
((
size_t
)
input1
.
getNumSequences
(),
numSequences
);
// check all inputs should have same hasSubseq flag
CHECK_EQ
(
input
.
hasSubseq
(),
inFrameLines_
[
0
].
hasSubseq
);
CHECK_EQ
(
input1
.
getBatchSize
(),
batchSize
);
CHECK
(
std
::
equal
(
starts
,
starts
+
numSequences
+
1
,
input1
.
sequenceStartPositions
->
getData
(
false
)));
// if shareInlinkInfo, checks:
// 1. all inlinks have same number of total tokens
// 2. all inlinks have same number of tokens for each sentence of each
// sample. If hasSubseq, one sample has multiple sentence, else, one
// sample is one sentence
if
(
shareInlinkInfo
)
{
CHECK_EQ
(
input1
.
getBatchSize
(),
batchSize
);
CHECK
(
std
::
equal
(
starts
,
starts
+
numSequences
+
1
,
input1
.
sequenceStartPositions
->
getData
(
false
)));
}
}
if
(
hasSubseq
)
{
...
...
@@ -408,19 +427,44 @@ void RecurrentGradientMachine::forward(const std::vector<Argument>& inArgs,
for
(
size_t
i
=
1
;
i
<
inFrameLines_
.
size
();
++
i
)
{
const
Argument
&
input1
=
inFrameLines_
[
i
].
inLayer
->
getOutput
();
CHECK_EQ
((
size_t
)
input1
.
getNumSubSequences
(),
numSubSequences
);
CHECK
(
std
::
equal
(
subStarts
,
subStarts
+
numSubSequences
+
1
,
input1
.
subSequenceStartPositions
->
getData
(
false
)));
if
(
shareInlinkInfo
)
{
CHECK
(
std
::
equal
(
subStarts
,
subStarts
+
numSubSequences
+
1
,
input1
.
subSequenceStartPositions
->
getData
(
false
)));
}
}
}
seqLengthAndStart_
.
clear
();
input
.
getSeqLengthAndStart
(
&
seqLengthAndStart_
,
&
maxSequenceLength_
);
info_
.
clear
();
info_
.
resize
(
inFrameLines_
.
size
());
seqLengthAndStart_
.
resize
(
inFrameLines_
.
size
());
{
AsyncGpuBlock
asyncGpuBlock
;
// if shareInlinkInfo, only calculate info of the first inlink
// else, calculate info for each inlink
if
(
shareInlinkInfo
)
{
input
.
getSeqLengthAndStart
(
&
seqLengthAndStart_
[
0
],
&
maxSequenceLength_
);
createInFrameInfo
(
0
,
input
,
passType
);
}
else
{
for
(
size_t
i
=
0
;
i
<
inFrameLines_
.
size
();
i
++
)
{
const
Argument
&
input1
=
inFrameLines_
[
i
].
inLayer
->
getOutput
();
input1
.
getSeqLengthAndStart
(
&
seqLengthAndStart_
[
i
],
&
maxSequenceLength_
);
createInFrameInfo
(
i
,
input1
,
passType
);
}
}
// inFrameLine select rows in real layer one time
for
(
size_t
i
=
0
;
i
<
inFrameLines_
.
size
();
i
++
)
{
int
curInlinkId
=
shareInlinkInfo
?
0
:
i
;
selectRowsOneTime
(
inFrameLines_
[
i
].
inLayer
,
info_
[
curInlinkId
].
allIds
,
&
(
inFrameLines_
[
i
].
outArg
),
passType
);
}
}
resizeOrCreateFrames
(
maxSequenceLength_
);
resizeBootFrame
(
numSequences
);
AsyncGpuBlock
asyncGpuBlock
;
createInFrameInfo
(
input
,
passType
);
for
(
auto
&
memoryFrameLine
:
memoryFrameLines_
)
{
if
(
memoryFrameLine
.
rootAgent
)
{
auto
scatterAgent
=
...
...
@@ -443,23 +487,29 @@ void RecurrentGradientMachine::forward(const std::vector<Argument>& inArgs,
auto
gatherAgent
=
dynamic_cast
<
GatherAgentLayer
*>
(
outFrameLine
.
agentLayer
.
get
());
CHECK_NOTNULL
(
gatherAgent
);
gatherAgent
->
copyIdAndSequenceInfo
(
input
,
info_
.
allIds
,
info_
.
idIndex
);
gatherAgent
->
copyIdAndSequenceInfo
(
input
,
info_
[
targetInfoInlinkId_
].
allIds
,
info_
[
targetInfoInlinkId_
].
idIndex
);
}
for
(
int
i
=
0
;
i
<
maxSequenceLength_
;
++
i
)
{
int
idSize
=
info_
.
idIndex
[
i
+
1
]
-
info_
.
idIndex
[
i
];
int
idSize
=
0
;
// connect in_links
for
(
auto
&
inFrameLine
:
inFrameLines_
)
{
for
(
size_t
j
=
0
;
j
<
inFrameLines_
.
size
();
++
j
)
{
// idSize denotes the sum number of tokens in each length i
idSize
=
info_
[
j
].
idIndex
[
i
+
1
]
-
info_
[
j
].
idIndex
[
i
];
InFrameLine
inFrameLine
=
inFrameLines_
[
j
];
auto
scatterAgent
=
dynamic_cast
<
ScatterAgentLayer
*>
(
inFrameLine
.
agents
[
i
].
get
());
scatterAgent
->
setRealLayerAndOutput
(
inFrameLine
.
inLayer
,
inFrameLine
.
outArg
,
info_
.
allIds
,
info_
.
idIndex
[
i
],
idSize
);
inFrameLine
.
outArg
,
info_
[
j
]
.
allIds
,
info_
[
j
]
.
idIndex
[
i
],
idSize
);
if
(
hasSubseq
)
{
int
size
=
info_
.
seqStartPosIndex
[
i
+
1
]
-
info_
.
seqStartPosIndex
[
i
];
scatterAgent
->
setSequenceStartPositions
(
info_
.
sequenceStartPositions
,
info_
.
seqStartPosIndex
[
i
],
size
);
// size: the length of subsequence
int
size
=
info_
[
j
].
seqStartPosIndex
[
i
+
1
]
-
info_
[
j
].
seqStartPosIndex
[
i
];
scatterAgent
->
setSequenceStartPositions
(
info_
[
j
].
sequenceStartPositions
,
info_
[
j
].
seqStartPosIndex
[
i
],
size
);
}
}
...
...
@@ -469,13 +519,16 @@ void RecurrentGradientMachine::forward(const std::vector<Argument>& inArgs,
dynamic_cast
<
GatherAgentLayer
*>
(
outFrameLine
.
agentLayer
.
get
());
gatherAgent
->
addRealLayer
(
outFrameLine
.
frames
[
i
]);
}
// connect memory links
// Adopt info_[0].idIndex because seq which has_subseq=True
// doesn't support Memory with !hasSubseq bootlayer;
// And inlinks that !hasSubSeq must have same inlink length.
idSize
=
info_
[
0
].
idIndex
[
i
+
1
]
-
info_
[
0
].
idIndex
[
i
];
for
(
auto
&
memoryFrameLine
:
memoryFrameLines_
)
{
NeuralNetwork
::
connect
(
memoryFrameLine
.
agents
[
i
],
i
==
0
?
memoryFrameLine
.
bootLayer
:
memoryFrameLine
.
frames
[
i
-
1
],
idSize
/*height of agent*/
);
numSeqs_
[
i
]
/*height of agent*/
);
}
}
...
...
@@ -560,62 +613,76 @@ void RecurrentGradientMachine::removeBeamSearchStatisticsCallbacks() {
* If hasSubseq, will also create scattered sequenceStartPositions infomation
* for all realLayer of inFrameLines one time.
*/
void
RecurrentGradientMachine
::
createInFrameInfo
(
const
Argument
&
input
,
void
RecurrentGradientMachine
::
createInFrameInfo
(
int
inlinks_id
,
const
Argument
&
input
,
PassType
passType
)
{
bool
hasSubseq
=
input
.
hasSubseq
();
// numSequences: # samples(sequences) in a batch
size_t
numSequences
=
input
.
getNumSequences
();
std
::
vector
<
int
>
allIds
;
info_
.
idIndex
.
clear
();
info_
.
idIndex
.
push_back
(
0
);
// first idIndex = 0
if
(
hasSubseq
)
{
// for sequenceScatterAgentLayer
numSeqs_
.
clear
();
Info
*
inlink_info
=
&
info_
[
inlinks_id
];
inlink_info
->
idIndex
.
clear
();
inlink_info
->
idIndex
.
push_back
(
0
);
// first idIndex = 0
if
(
hasSubseq
)
{
// for sequenceScatterAgentLayer
// numSubSequences : all sentences within all samples(batch)
size_t
numSubSequences
=
input
.
getNumSubSequences
();
std
::
vector
<
int
>
sequenceStartPositions
;
info_
.
seqStartPosIndex
.
clear
();
info_
.
seqStartPosIndex
.
push_back
(
0
);
// first seqStartPosIndex = 0
inlink_info
->
seqStartPosIndex
.
clear
();
inlink_info
->
seqStartPosIndex
.
push_back
(
0
);
// first seqStartPosIndex = 0
// maxSequenceLength_: max number of sentences(subseq) in allsamples
for
(
int
i
=
0
;
i
<
maxSequenceLength_
;
++
i
)
{
sequenceStartPositions
.
push_back
(
0
);
// first element = 0
for
(
size_t
j
=
0
;
j
<
numSubSequences
;
++
j
)
{
if
(
std
::
get
<
3
>
(
seqLengthAndStart_
[
j
])
==
i
)
{
int
subSeqStart
=
std
::
get
<
1
>
(
seqLengthAndStart_
[
j
]);
int
subSeqLength
=
std
::
get
<
0
>
(
seqLengthAndStart_
[
j
]);
sequenceStartPositions
.
push_back
(
0
);
// first element = 0
int
numSeqs
=
0
;
for
(
size_t
j
=
0
;
j
<
numSubSequences
;
++
j
)
{
// for each sentence
// seqLengthAndStart_[inlinks_id][j]:
// a 4-tuple including <subseqlen, subseqstart, seqid, subseqid>
if
(
std
::
get
<
3
>
(
seqLengthAndStart_
[
inlinks_id
][
j
])
==
i
)
{
++
numSeqs
;
// subseqstart: the cpuSubSequenceStartPositions of this subseq
int
subSeqStart
=
std
::
get
<
1
>
(
seqLengthAndStart_
[
inlinks_id
][
j
]);
int
subSeqLength
=
std
::
get
<
0
>
(
seqLengthAndStart_
[
inlinks_id
][
j
]);
for
(
int
k
=
subSeqStart
;
k
<
subSeqStart
+
subSeqLength
;
++
k
)
{
allIds
.
push_back
(
k
);
}
sequenceStartPositions
.
push_back
(
sequenceStartPositions
.
back
()
+
subSeqLength
);
subSeqLength
);
}
}
info_
.
idIndex
.
push_back
(
allIds
.
size
());
info_
.
seqStartPosIndex
.
push_back
(
sequenceStartPositions
.
size
());
inlink_info
->
idIndex
.
push_back
(
allIds
.
size
());
inlink_info
->
seqStartPosIndex
.
push_back
(
sequenceStartPositions
.
size
());
numSeqs_
.
push_back
(
numSeqs
);
}
// inFrameLine create sequenceStartPositions one time
CHECK_EQ
(
sequenceStartPositions
.
size
(),
maxSequenceLength_
+
numSubSequences
);
CHECK_EQ
(
in
fo_
.
seqStartPosIndex
.
size
(),
CHECK_EQ
(
in
link_info
->
seqStartPosIndex
.
size
(),
static_cast
<
size_t
>
(
maxSequenceLength_
+
1
));
createSeqPos
(
sequenceStartPositions
,
&
in
fo_
.
sequenceStartPositions
);
createSeqPos
(
sequenceStartPositions
,
&
in
link_info
->
sequenceStartPositions
);
}
else
{
// for scatterAgentLayer
for
(
int
i
=
0
;
i
<
maxSequenceLength_
;
++
i
)
{
int
numSeqs
=
0
;
for
(
size_t
j
=
0
;
j
<
numSequences
;
++
j
)
{
int
seqLength
=
std
::
get
<
0
>
(
seqLengthAndStart_
[
j
]);
int
seqLength
=
std
::
get
<
0
>
(
seqLengthAndStart_
[
inlinks_id
][
j
]);
if
(
i
>=
seqLength
)
{
break
;
}
int
seqStart
=
std
::
get
<
1
>
(
seqLengthAndStart_
[
j
]);
++
numSeqs
;
int
seqStart
=
std
::
get
<
1
>
(
seqLengthAndStart_
[
inlinks_id
][
j
]);
allIds
.
push_back
(
reversed_
?
(
seqStart
+
seqLength
-
1
-
i
)
:
(
seqStart
+
i
));
}
info_
.
idIndex
.
push_back
(
allIds
.
size
());
inlink_info
->
idIndex
.
push_back
(
allIds
.
size
());
numSeqs_
.
push_back
(
numSeqs
);
}
}
// copy and check scatterId
copyScattedId
(
allIds
,
&
info_
.
allIds
,
input
.
getBatchSize
());
CHECK_EQ
(
info_
.
idIndex
.
size
(),
static_cast
<
size_t
>
(
maxSequenceLength_
+
1
));
// inFrameLine select rows in real layer one time
for
(
auto
&
inFrameLine
:
inFrameLines_
)
{
selectRowsOneTime
(
inFrameLine
.
inLayer
,
info_
.
allIds
,
&
inFrameLine
.
outArg
,
passType
);
}
copyScattedId
(
allIds
,
&
inlink_info
->
allIds
,
input
.
getBatchSize
());
CHECK_EQ
(
inlink_info
->
idIndex
.
size
(),
static_cast
<
size_t
>
(
maxSequenceLength_
+
1
));
}
/* like createInFrameInfo, but for all realLayer of memoryFrameLines*/
...
...
@@ -633,19 +700,20 @@ void RecurrentGradientMachine::createMemoryFrameInfo(
sequenceStartPositions
.
push_back
(
0
);
// first element = 0
const
int
*
starts
=
input
.
sequenceStartPositions
->
getData
(
false
);
for
(
size_t
i
=
0
;
i
<
numSequences
;
++
i
)
{
int
seqId
=
std
::
get
<
2
>
(
seqLengthAndStart_
[
i
]);
// memory info adopt info of inlinks[0]
int
seqId
=
std
::
get
<
2
>
(
seqLengthAndStart_
[
0
][
i
]);
for
(
int
k
=
starts
[
seqId
];
k
<
starts
[
seqId
+
1
];
++
k
)
{
allIds
.
push_back
(
k
);
}
sequenceStartPositions
.
push_back
(
sequenceStartPositions
.
back
()
+
starts
[
seqId
+
1
]
-
starts
[
seqId
]);
starts
[
seqId
+
1
]
-
starts
[
seqId
]);
}
createSeqPos
(
sequenceStartPositions
,
&
(
*
memoryFrameLine
).
sequenceStartPositions
);
}
else
{
// for scatterAgentLayer
for
(
size_t
i
=
0
;
i
<
numSequences
;
++
i
)
{
allIds
.
push_back
(
std
::
get
<
2
>
(
seqLengthAndStart_
[
i
]));
allIds
.
push_back
(
std
::
get
<
2
>
(
seqLengthAndStart_
[
0
][
i
]));
}
}
// copy and check scatterId
...
...
@@ -699,18 +767,19 @@ size_t RecurrentGradientMachine::getGenBatchSize() {
for
(
auto
&
memoryFrameLine
:
memoryFrameLines_
)
{
if
(
!
memoryFrameLine
.
rootLayer
)
continue
;
Argument
&
bootArg
=
memoryFrameLine
.
rootLayer
->
getOutput
();
size_t
batchSize
=
memoryFrameLine
.
is_sequence
?
bootArg
.
getNumSequences
()
:
bootArg
.
getBatchSize
();
size_t
batchSize
=
memoryFrameLine
.
is_sequence
?
bootArg
.
getNumSequences
()
:
bootArg
.
getBatchSize
();
if
(
numSequences
)
{
CHECK_EQ
(
numSequences
,
batchSize
);
}
else
{
numSequences
=
batchSize
;
}
}
CHECK
(
numSequences
)
<<
"Fail to get batch size in generation. "
"At least one of the Memory layer MUST have a layer that is NOT in "
"the layer group to boot it, and this boot layer is used to "
"decide batch_size in generation process."
;
CHECK
(
numSequences
)
<<
"Fail to get batch size in generation. "
"At least one of the Memory layer MUST have a layer that is NOT in "
"the layer group to boot it, and this boot layer is used to "
"decide batch_size in generation process."
;
return
numSequences
;
}
...
...
@@ -732,7 +801,9 @@ void RecurrentGradientMachine::generateSequence() {
// connect boot frame memory links
std
::
vector
<
int
>
ids
(
numSequences
);
for
(
size_t
i
=
0
;
i
<
numSequences
;
++
i
)
{
ids
[
i
]
=
i
;
}
for
(
size_t
i
=
0
;
i
<
numSequences
;
++
i
)
{
ids
[
i
]
=
i
;
}
for
(
auto
&
memoryFrameLine
:
memoryFrameLines_
)
{
if
(
memoryFrameLine
.
rootAgent
)
{
auto
scatterAgent
=
...
...
@@ -756,7 +827,8 @@ void RecurrentGradientMachine::generateSequence() {
// init outArg
size_t
resultNum
=
generator_
.
config
.
num_results_per_sample
();
IVector
::
resizeOrCreate
(
generator_
.
outArg
.
ids
,
IVector
::
resizeOrCreate
(
generator_
.
outArg
.
ids
,
generator_
.
config
.
max_num_frames
()
*
numSequences
*
resultNum
,
false
);
if
(
resultNum
>
1
)
{
CHECK_LE
(
resultNum
,
static_cast
<
size_t
>
(
generator_
.
config
.
beam_size
()));
...
...
@@ -847,7 +919,9 @@ void RecurrentGradientMachine::oneWaySearch(size_t batchSize) {
// path.seqId = -1 indicates end of generation
// of an input sequence
finalPaths
[
seqIds_
[
j
]].
seqId
=
-
1
;
}
else
{
scatterIds
.
push_back
(
j
);
}
}
else
{
scatterIds
.
push_back
(
j
);
}
}
}
...
...
@@ -856,13 +930,12 @@ void RecurrentGradientMachine::oneWaySearch(size_t batchSize) {
starts
[
0
]
=
0
;
generator_
.
ids
.
clear
();
for
(
size_t
i
=
0
;
i
<
batchSize
;
++
i
)
{
generator_
.
ids
.
insert
(
generator_
.
ids
.
end
(),
finalPaths
[
i
].
ids
.
begin
(),
generator_
.
ids
.
insert
(
generator_
.
ids
.
end
(),
finalPaths
[
i
].
ids
.
begin
(),
finalPaths
[
i
].
ids
.
end
());
starts
[
i
+
1
]
=
generator_
.
ids
.
size
();
batchMachineIdVec_
.
insert
(
batchMachineIdVec_
.
end
(),
finalPaths
[
i
].
machineIdVec
.
begin
(),
finalPaths
[
i
].
machineIdVec
.
end
());
finalPaths
[
i
].
machineIdVec
.
begin
(),
finalPaths
[
i
].
machineIdVec
.
end
());
}
}
...
...
@@ -920,9 +993,9 @@ void RecurrentGradientMachine::forwardFrame(int machineCur) {
}
}
void
RecurrentGradientMachine
::
singlePathExpand
(
Path
&
curPath
,
size_t
curPathId
,
std
::
vector
<
Path
>&
newPaths
,
size_t
expandWidth
)
{
void
RecurrentGradientMachine
::
singlePathExpand
(
Path
&
curPath
,
size_t
curPathId
,
std
::
vector
<
Path
>&
newPaths
,
size_t
expandWidth
)
{
int
calc_id
=
gDiyProbStart
?
gDiyProbStart
(
curPath
.
ids
.
size
(),
curPath
.
ids
.
data
())
:
0
;
...
...
@@ -946,19 +1019,20 @@ void RecurrentGradientMachine::singlePathExpand(
if
(
id
==
-
1
)
break
;
real
newLogProb
=
generator_
.
config
.
log_prob
()
?
std
::
log
(
prob
)
:
prob
;
Path
newPath
(
curPath
,
id
,
newLogProb
,
curPathId
/*machineId*/
,
k
/*topIndex*/
);
Path
newPath
(
curPath
,
id
,
newLogProb
,
curPathId
/*machineId*/
,
k
/*topIndex*/
);
if
(
this
->
beamSearchCtrlCallbacks_
)
{
if
(
beamSearchCtrlCallbacks_
->
stopDetermineCandidates
(
newPath
.
seqId
,
newPath
.
ids
,
newPath
.
probHistory
))
return
;
newPath
.
seqId
,
newPath
.
ids
,
newPath
.
probHistory
))
return
;
}
// outFrameLines_.size() > 1UL
if
(
dataArgsSize_
)
{
newPath
.
machineIdVec
=
curPath
.
machineIdVec
;
newPath
.
machineIdVec
.
push_back
(
curPathId
);
}
bool
atEos
=
eosVec
[
index
]
==
1U
||
newPath
.
ids
.
size
()
>=
(
size_t
)
maxSequenceLength_
;
bool
atEos
=
eosVec
[
index
]
==
1U
||
newPath
.
ids
.
size
()
>=
(
size_t
)
maxSequenceLength_
;
// adjustNewPath
newPath
.
adjustProb
(
calc_id
,
atEos
);
if
(
this
->
beamSearchCtrlCallbacks_
)
{
...
...
@@ -966,16 +1040,18 @@ void RecurrentGradientMachine::singlePathExpand(
newPath
.
seqId
,
newPath
.
ids
,
newPath
.
probHistory
,
&
newPath
.
logProb
);
}
if
(
!
newPath
.
isDropable
())
{
atEos
?
finalPaths_
[
curPath
.
seqId
].
push_back
(
newPath
)
:
newPaths
.
push_back
(
newPath
);
atEos
?
finalPaths_
[
curPath
.
seqId
].
push_back
(
newPath
)
:
newPaths
.
push_back
(
newPath
);
}
}
// for expandWidth
if
(
gDiyProbStop
)
{
gDiyProbStop
(
calc_id
);
}
if
(
gDiyProbStop
)
{
gDiyProbStop
(
calc_id
);
}
}
void
RecurrentGradientMachine
::
beamExpand
(
std
::
vector
<
Path
>&
paths
,
std
::
vector
<
Path
>&
newPaths
)
{
void
RecurrentGradientMachine
::
beamExpand
(
std
::
vector
<
Path
>&
paths
,
std
::
vector
<
Path
>&
newPaths
)
{
size_t
candidatePathCount
=
paths
.
size
();
// idVec.size() could be larger than candidatePathCount * beam,
// so user can drop some node customly.
...
...
@@ -988,7 +1064,7 @@ void RecurrentGradientMachine::beamExpand(
int
curSeqId
=
0
;
for
(
size_t
j
=
0
;
j
<=
candidatePathCount
;
j
++
)
{
// expansions of a single sequence are all processed
curSeqId
=
(
j
<
candidatePathCount
?
paths
[
j
].
seqId
:
curSeqId
+
1
);
curSeqId
=
(
j
<
candidatePathCount
?
paths
[
j
].
seqId
:
curSeqId
+
1
);
if
(
prevSeqId
!=
-
1
&&
curSeqId
!=
prevSeqId
)
{
totalExpandCount
+=
beamShrink
(
newPaths
,
prevSeqId
,
totalExpandCount
);
}
...
...
@@ -1000,11 +1076,14 @@ void RecurrentGradientMachine::beamExpand(
}
// Drop extra nodes to beam size.
size_t
RecurrentGradientMachine
::
beamShrink
(
std
::
vector
<
Path
>&
newPaths
,
size_t
seqId
,
size_t
totalExpandCount
)
{
size_t
minNewPathSize
=
std
::
min
(
getBeamSize
(),
newPaths
.
size
()
-
totalExpandCount
);
if
(
!
minNewPathSize
)
{
return
0
;
}
size_t
RecurrentGradientMachine
::
beamShrink
(
std
::
vector
<
Path
>&
newPaths
,
size_t
seqId
,
size_t
totalExpandCount
)
{
size_t
minNewPathSize
=
std
::
min
(
getBeamSize
(),
newPaths
.
size
()
-
totalExpandCount
);
if
(
!
minNewPathSize
)
{
return
0
;
}
std
::
nth_element
(
newPaths
.
begin
()
+
totalExpandCount
,
newPaths
.
begin
()
+
totalExpandCount
+
minNewPathSize
,
newPaths
.
end
(),
Path
::
greaterPath
);
...
...
@@ -1017,11 +1096,8 @@ size_t RecurrentGradientMachine::beamShrink(
// Remove the already formed paths that are relatively short
finalPaths_
[
seqId
].
erase
(
std
::
remove_if
(
finalPaths_
[
seqId
].
begin
(),
finalPaths_
[
seqId
].
end
(),
[
&
](
Path
&
p
)
{
return
p
.
logProb
<
minPathLogProb
;
}),
std
::
remove_if
(
finalPaths_
[
seqId
].
begin
(),
finalPaths_
[
seqId
].
end
(),
[
&
](
Path
&
p
)
{
return
p
.
logProb
<
minPathLogProb
;
}),
finalPaths_
[
seqId
].
end
());
for
(
auto
p
:
finalPaths_
[
seqId
])
{
if
(
minFinalPathLogProb_
[
seqId
]
>
p
.
logProb
)
{
...
...
@@ -1030,7 +1106,7 @@ size_t RecurrentGradientMachine::beamShrink(
}
if
(
finalPaths_
[
seqId
].
size
()
>=
getBeamSize
()
&&
minFinalPathLogProb_
[
seqId
]
>=
maxPathLogProb
)
{
minFinalPathLogProb_
[
seqId
]
>=
maxPathLogProb
)
{
newPaths
.
resize
(
totalExpandCount
);
return
0
;
}
...
...
@@ -1067,7 +1143,8 @@ void RecurrentGradientMachine::fillGenOutputs() {
// in beam search, here only reserved the top 1 generated result
// for out_links that are not the generated word indices.
batchMachineIdVec_
.
insert
(
batchMachineIdVec_
.
end
(),
path
.
machineIdVec
.
begin
(),
path
.
machineIdVec
.
end
());
path
.
machineIdVec
.
begin
(),
path
.
machineIdVec
.
end
());
}
}
starts
[
i
+
1
]
=
generator_
.
ids
.
size
();
...
...
@@ -1091,21 +1168,21 @@ void RecurrentGradientMachine::copyDataOutlinkFrame(size_t machineCur) {
void
RecurrentGradientMachine
::
createDataOutlink
(
std
::
vector
<
int
>&
machineIdVec
)
{
size_t
seqNum
=
getBeamSize
()
>
1UL
?
finalPaths_
.
size
()
:
finalPaths_
[
0
].
size
();
size_t
seqNum
=
getBeamSize
()
>
1UL
?
finalPaths_
.
size
()
:
finalPaths_
[
0
].
size
();
std
::
vector
<
int
>
starts
(
seqNum
+
1
,
0
);
for
(
size_t
i
=
0
;
i
<
seqNum
;
++
i
)
{
size_t
seqLen
=
getBeamSize
()
>
1UL
?
finalPaths_
[
i
][
0
].
ids
.
size
()
:
finalPaths_
[
0
][
i
].
ids
.
size
();
size_t
seqLen
=
getBeamSize
()
>
1UL
?
finalPaths_
[
i
][
0
].
ids
.
size
()
:
finalPaths_
[
0
][
i
].
ids
.
size
();
starts
[
i
+
1
]
=
starts
[
i
]
+
seqLen
;
}
for
(
size_t
i
=
0
;
i
<
dataArgsSize_
;
i
++
)
{
dataArgs_
[
i
].
concat
(
dataArgsFrame_
[
i
],
machineIdVec
,
starts
,
useGpu_
,
HPPL_STREAM_1
,
PASS_TEST
);
dataArgs_
[
i
].
concat
(
dataArgsFrame_
[
i
],
machineIdVec
,
starts
,
useGpu_
,
HPPL_STREAM_1
,
PASS_TEST
);
auto
dataAgent
=
dynamic_cast
<
DataLayer
*>
(
outFrameLines_
[
i
+
1
].
agentLayer
.
get
());
auto
dataAgent
=
dynamic_cast
<
DataLayer
*>
(
outFrameLines_
[
i
+
1
].
agentLayer
.
get
());
CHECK_NOTNULL
(
dataAgent
);
dataAgent
->
setData
(
dataArgs_
[
i
]);
}
...
...
paddle/gserver/gradientmachines/RecurrentGradientMachine.h
浏览文件 @
93006787
...
...
@@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#pragma once
#include "GradientMachine.h"
...
...
@@ -101,7 +100,7 @@ public:
* Return true if this prefix or candidate is expected to be dropped.
*/
typedef
std
::
function
<
bool
(
int
seqId
,
const
std
::
vector
<
int
>&
,
const
std
::
vector
<
real
>&
)
>
DropCallback
;
const
std
::
vector
<
real
>&
)
>
DropCallback
;
/**
* @brief NormOrDropNodeCallback
...
...
@@ -117,7 +116,7 @@ public:
* The fourth parameter is the probability of the whole path.
*/
typedef
std
::
function
<
void
(
int
seqId
,
const
std
::
vector
<
int
>&
,
std
::
vector
<
real
>&
,
real
*
)
>
NormOrDropNodeCallback
;
std
::
vector
<
real
>&
,
real
*
)
>
NormOrDropNodeCallback
;
/**
* @brief Register beam search control callbacks. Used for prediction.
...
...
@@ -192,7 +191,7 @@ public:
int
machineId
;
// index of sample in frame
int
topIndex
;
// index of MaxIdLayer output in one sample
int
seqId
;
// index of sequence in batch generation
int
seqId
;
// index of sequence in batch generation
std
::
vector
<
int
>
machineIdVec
;
/**
...
...
@@ -206,7 +205,10 @@ public:
/**
* @brief Path default ctor, first logProb is 0.
*/
Path
()
{
logProb
=
0
;
seqId
=
0
;
}
Path
()
{
logProb
=
0
;
seqId
=
0
;
}
explicit
Path
(
size_t
seqId
)
:
seqId
(
seqId
)
{
logProb
=
0
;
}
/**
...
...
@@ -319,21 +321,37 @@ protected:
};
std
::
vector
<
MemoryFrameLine
>
memoryFrameLines_
;
// All inFrameLines and outFrameLines have the same element as follows.
// Each inFrameLines(inlinks) has its own info(elements) below,
// and all outFrameLines(outlinks) share the info with one inFrameLine,
// which is assigned by targetInfoInlinkId_.
struct
Info
{
IVectorPtr
allIds
;
// scattered id of realLayer
std
::
vector
<
int
>
idIndex
;
// index of allIds
ICpuGpuVectorPtr
sequenceStartPositions
;
// scattered sequenceStartPositions
sequenceStartPositions
;
// scattered sequenceStartPositions
std
::
vector
<
int
>
seqStartPosIndex
;
// index of sequenceStartPositions
};
Info
info_
;
std
::
vector
<
Info
>
info_
;
// numSeqs_[i] is the number sequences which is longer than i (for sequence
// data) or has more than i subsequences (for subsequence data)
std
::
vector
<
int
>
numSeqs_
;
// if no subSeq, tuple of (seqLength, seqStart, seqIndex, seqIndex)
// else, tuple of (subSeqLength, subSeqStart, seqIndex, subSeqIndex)
std
::
vector
<
std
::
tuple
<
int
,
int
,
int
,
int
>>
seqLengthAndStart_
;
// each inlinks has a "std::vector<std::tuple<int, int, int, int>>" denotes
// its sequence info:
// if hasSubSeq, tuple of (subSeqLength, subSeqStart, seqIndex, subSeqIndex)
// else, tuple of (seqLength, seqStart, seqIndex, seqIndex)
std
::
vector
<
std
::
vector
<
std
::
tuple
<
int
,
int
,
int
,
int
>>>
seqLengthAndStart_
;
void
createInFrameInfo
(
const
Argument
&
input
,
PassType
passType
);
// the id of inlink which share info with outlinks
int
targetInfoInlinkId_
;
/* create scattered id infomation for all realLayer of inFrameLines one time.
* If hasSubseq, will also create scattered sequenceStartPositions infomation
* for all realLayer of inFrameLines one time.
*/
void
createInFrameInfo
(
int
inlinks_id
,
const
Argument
&
input
,
PassType
passType
);
void
createMemoryFrameInfo
(
MemoryFrameLine
*
memoryFrameLine
,
PassType
passType
);
...
...
@@ -363,6 +381,9 @@ protected:
NeuralNetwork
*
rootNetwork_
;
bool
reversed_
;
// if hasSubseq: max number of sentences(subseq)in batchsize samples
// else: max number of tokens in batchsize samples(sentences)
int
maxSequenceLength_
;
bool
useGpu_
;
bool
stopBeamSearch_
;
...
...
@@ -415,7 +436,7 @@ private:
* @param machineIdVec : select a row of output matrix in each frame
* that the generation process expanded.
*/
void
createDataOutlink
(
std
::
vector
<
int
>
&
machineIdVec
);
void
createDataOutlink
(
std
::
vector
<
int
>&
machineIdVec
);
/*
* @brief used in beam search, connect previous frame to form recurrent link
...
...
paddle/gserver/layers/CTCLayer.cpp
浏览文件 @
93006787
...
...
@@ -49,8 +49,10 @@ void CTCLayer::forward(PassType passType) {
Layer
::
forward
(
passType
);
if
(
useGpu_
)
{
for
(
size_t
i
=
0
;
i
<
inputLayers_
.
size
();
i
++
)
{
tmpCpuInput_
[
i
].
resizeAndCopyFrom
(
getInput
(
i
),
false
,
HPPL_STREAM_1
);
tmpCpuInput_
[
i
].
resizeAndCopyFrom
(
getInput
(
i
),
false
,
HPPL_STREAM_DEFAULT
);
}
hl_stream_synchronize
(
HPPL_STREAM_DEFAULT
);
forwardImp
(
tmpCpuInput_
[
0
],
tmpCpuInput_
[
1
]);
}
else
{
forwardImp
(
getInput
(
0
),
getInput
(
1
));
...
...
@@ -92,9 +94,9 @@ void CTCLayer::backward(const UpdateCallback &callback) {
if
(
useGpu_
)
{
backwardImp
(
callback
,
tmpCpuInput_
[
0
],
tmpCpuInput_
[
1
]);
const_cast
<
Argument
&>
(
getInput
(
0
)).
resizeAndCopyFrom
(
tmpCpuInput_
[
0
],
true
,
HPPL_STREAM_
1
);
resizeAndCopyFrom
(
tmpCpuInput_
[
0
],
true
,
HPPL_STREAM_
DEFAULT
);
const_cast
<
Argument
&>
(
getInput
(
1
)).
resizeAndCopyFrom
(
tmpCpuInput_
[
1
],
true
,
HPPL_STREAM_
1
);
resizeAndCopyFrom
(
tmpCpuInput_
[
1
],
true
,
HPPL_STREAM_
DEFAULT
);
}
else
{
backwardImp
(
callback
,
getInput
(
0
),
getInput
(
1
));
}
...
...
paddle/gserver/layers/ConvOperator.cpp
浏览文件 @
93006787
...
...
@@ -248,7 +248,7 @@ void ConvOperator::forward() {
CHECK_EQ
(
ins_
[
1
]
->
value
->
getHeight
(),
batchSize
);
checkFilterSize
(
ins_
[
1
]
->
value
);
Matrix
::
resizeOrCreate
(
out_
->
value
,
batchSize
,
outputH_
*
outputW_
*
numFilters_
);
outputH_
*
outputW_
*
numFilters_
,
false
,
useGpu_
);
{
AsyncGpuBlock
block
;
for
(
size_t
batchId
=
0
;
batchId
<
batchSize
;
++
batchId
)
{
...
...
paddle/gserver/layers/CostLayer.cpp
浏览文件 @
93006787
...
...
@@ -509,8 +509,10 @@ void HuberTwoClass::forwardImp(Matrix &output, Argument &label,
Matrix
&
cost
)
{
if
(
useGpu_
)
{
for
(
size_t
i
=
0
;
i
<
inputLayers_
.
size
();
i
++
)
{
tmpCpuInput_
[
i
].
resizeAndCopyFrom
(
getInput
(
i
),
false
,
HPPL_STREAM_1
);
tmpCpuInput_
[
i
].
resizeAndCopyFrom
(
getInput
(
i
),
false
,
HPPL_STREAM_DEFAULT
);
}
hl_stream_synchronize
(
HPPL_STREAM_DEFAULT
);
}
forwardImpIn
(
output
,
label
,
cost
);
}
...
...
paddle/gserver/layers/SamplingIdLayer.cpp
浏览文件 @
93006787
...
...
@@ -52,8 +52,10 @@ public:
Layer
::
forward
(
passType
);
if
(
useGpu_
)
{
for
(
size_t
i
=
0
;
i
<
inputLayers_
.
size
();
i
++
)
{
tmpCpuInput_
[
i
].
resizeAndCopyFrom
(
getInput
(
i
),
false
,
HPPL_STREAM_1
);
tmpCpuInput_
[
i
].
resizeAndCopyFrom
(
getInput
(
i
),
false
,
HPPL_STREAM_DEFAULT
);
}
hl_stream_synchronize
(
HPPL_STREAM_DEFAULT
);
forwardImp
(
tmpCpuInput_
[
0
]);
}
else
{
forwardImp
(
getInput
(
0
));
...
...
paddle/gserver/tests/LayerGradUtil.cpp
浏览文件 @
93006787
...
...
@@ -92,7 +92,6 @@ void testState(LayerPtr testLayer, vector<DataLayerPtr>& dataLayers,
testLayer
->
forward
(
PASS_TEST
);
Argument
out
;
out
.
resizeAndCopyFrom
(
testLayer
->
getOutput
(),
/* useGpu= */
false
);
hl_stream_synchronize
(
HPPL_STREAM_DEFAULT
);
if
(
batchOut
.
value
)
{
size_t
dim
=
batchOut
.
value
->
getWidth
();
ASSERT_TRUE
((
bool
)
out
.
value
);
...
...
@@ -220,7 +219,6 @@ void testBatchState(LayerPtr testLayer, vector<DataLayerPtr>& dataLayers,
testLayer
->
forward
(
PASS_TEST
);
Argument
out
;
out
.
resizeAndCopyFrom
(
testLayer
->
getOutput
(),
/* useGpu= */
false
);
hl_stream_synchronize
(
HPPL_STREAM_DEFAULT
);
if
(
batchOut
.
value
)
{
size_t
dim
=
batchOut
.
value
->
getWidth
();
ASSERT_TRUE
((
bool
)
out
.
value
);
...
...
paddle/gserver/tests/Sequence/dummy.list
0 → 100644
浏览文件 @
93006787
dummy_file_no_use
paddle/gserver/tests/rnn_data_provider.py
0 → 100644
浏览文件 @
93006787
# Copyright (c) 2016 Baidu, Inc. All Rights Reserved
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from
paddle.trainer.PyDataProvider2
import
*
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
(
2
)])
def
process_subseq
(
settings
,
file_name
):
for
d
in
data
:
yield
d
@
provider
(
input_types
=
[
integer_value_sequence
(
10
),
integer_value
(
2
)])
def
process_seq
(
settings
,
file_name
):
for
d
in
data
:
seq
=
[]
for
subseq
in
d
[
0
]:
seq
+=
subseq
yield
seq
,
d
[
1
]
paddle/gserver/tests/sequenceGen.py
浏览文件 @
93006787
#!/usr/bin/env python
#coding=utf-8
# Copyright (c) 2016 Baidu, Inc. All Rights Reserved
#
# Licensed under the Apache License, Version 2.0 (the "License");
...
...
paddle/gserver/tests/sequence_nest_rnn.conf
0 → 100644
浏览文件 @
93006787
#edit-mode: -*- python -*-
# Copyright (c) 2016 Baidu, Inc. All Rights Reserved
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from
paddle
.
trainer_config_helpers
import
*
######################## data source ################################
define_py_data_sources2
(
train_list
=
'gserver/tests/Sequence/dummy.list'
,
test_list
=
None
,
module
=
'rnn_data_provider'
,
obj
=
'process_subseq'
)
settings
(
batch_size
=
2
,
learning_rate
=
0
.
01
)
######################## network configure ################################
dict_dim
=
10
word_dim
=
8
hidden_dim
=
8
label_dim
=
3
data
=
data_layer
(
name
=
"word"
,
size
=
dict_dim
)
emb
=
embedding_layer
(
input
=
data
,
size
=
word_dim
)
# This hierachical RNN is designed to be equivalent to the simple RNN in
# sequence_rnn.conf
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 last" should also work. But currently RecurrentGradientMachine
# does not handle it correctly. Current implementation requires that
# all the out links are from sequences. However, it does not report error
# when the out links are not sequences.
return
inner_rnn_output
out
=
recurrent_group
(
step
=
outer_step
,
input
=
SubsequenceInput
(
emb
))
value_printer_evaluator
(
input
=
out
)
rep
=
last_seq
(
input
=
out
)
prob
=
fc_layer
(
size
=
label_dim
,
input
=
rep
,
act
=
SoftmaxActivation
(),
bias_attr
=
True
)
outputs
(
classification_cost
(
input
=
prob
,
label
=
data_layer
(
name
=
"label"
,
size
=
label_dim
)))
paddle/gserver/tests/sequence_rnn.conf
0 → 100644
浏览文件 @
93006787
#edit-mode: -*- python -*-
# Copyright (c) 2016 Baidu, Inc. All Rights Reserved
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from
paddle
.
trainer_config_helpers
import
*
######################## data source ################################
define_py_data_sources2
(
train_list
=
'gserver/tests/Sequence/dummy.list'
,
test_list
=
None
,
module
=
'rnn_data_provider'
,
obj
=
'process_seq'
)
settings
(
batch_size
=
2
,
learning_rate
=
0
.
01
)
######################## network configure ################################
dict_dim
=
10
word_dim
=
8
hidden_dim
=
8
label_dim
=
3
data
=
data_layer
(
name
=
"word"
,
size
=
dict_dim
)
emb
=
embedding_layer
(
input
=
data
,
size
=
word_dim
)
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
)
value_printer_evaluator
(
input
=
out
)
rep
=
last_seq
(
input
=
out
)
prob
=
fc_layer
(
size
=
label_dim
,
input
=
rep
,
act
=
SoftmaxActivation
(),
bias_attr
=
True
)
outputs
(
classification_cost
(
input
=
prob
,
label
=
data_layer
(
name
=
"label"
,
size
=
label_dim
)))
paddle/gserver/tests/test_RecurrentGradientMachine.cpp
浏览文件 @
93006787
...
...
@@ -21,6 +21,8 @@ limitations under the License. */
#include <paddle/trainer/TrainerInternal.h>
#include <paddle/gserver/gradientmachines/GradientMachine.h>
P_DECLARE_int32
(
seed
);
using
namespace
paddle
;
// NOLINT
using
namespace
std
;
// NOLINT
class
TrainerForTest
:
public
paddle
::
Trainer
{
...
...
@@ -68,7 +70,9 @@ void CalCost(const string& conf, const string& dir, real* cost,
CpuVector
vecMomentum
(
dim
);
// vecW needs to be assigned, otherwise the variable is an uncertain value.
vecW
.
zeroMem
();
*
ThreadLocalRand
::
getSeed
()
=
FLAGS_seed
;
vecW
.
randnorm
(
0
,
0.1
);
trainer
.
startTrain
();
for
(
int
i
=
0
;
i
<
num_passes
;
++
i
)
{
...
...
@@ -88,15 +92,13 @@ void CalCost(const string& conf, const string& dir, real* cost,
rmDir
(
dir
.
c_str
());
}
TEST
(
RecurrentGradientMachine
,
HasSubSequence
)
{
void
test
(
const
string
&
conf1
,
const
string
&
conf2
)
{
int
num_passes
=
5
;
real
*
cost1
=
new
real
[
num_passes
];
const
string
conf1
=
"gserver/tests/sequence_layer_group.conf"
;
const
string
dir1
=
"gserver/tests/t1"
;
CalCost
(
conf1
,
dir1
,
cost1
,
num_passes
);
real
*
cost2
=
new
real
[
num_passes
];
const
string
conf2
=
"gserver/tests/sequence_nest_layer_group.conf"
;
const
string
dir2
=
"gserver/tests/t2"
;
CalCost
(
conf2
,
dir2
,
cost2
,
num_passes
);
...
...
@@ -109,6 +111,17 @@ TEST(RecurrentGradientMachine, HasSubSequence) {
delete
[]
cost2
;
}
TEST
(
RecurrentGradientMachine
,
HasSubSequence
)
{
test
(
"gserver/tests/sequence_layer_group.conf"
,
"gserver/tests/sequence_nest_layer_group.conf"
);
}
TEST
(
RecurrentGradientMachine
,
rnn
)
{
test
(
"gserver/tests/sequence_rnn.conf"
,
"gserver/tests/sequence_nest_rnn.conf"
);
}
int
main
(
int
argc
,
char
**
argv
)
{
if
(
paddle
::
version
::
isWithPyDataProvider
())
{
if
(
!
paddle
::
version
::
isWithGpu
())
{
...
...
paddle/gserver/tests/test_RecurrentLayer.cpp
浏览文件 @
93006787
...
...
@@ -299,7 +299,6 @@ void checkRecurrentLayer(LayerConfig layerConfig, size_t batchSize,
Argument
&
cpuInput
=
testCpu
.
dataLayer_
->
getOutput
();
Argument
&
gpuInput
=
testGpu
.
dataLayer_
->
getOutput
();
gpuInput
.
resizeAndCopyFrom
(
cpuInput
,
true
);
hl_stream_synchronize
(
HPPL_STREAM_DEFAULT
);
const
VectorPtr
&
cpuVec
=
testCpu
.
para_
->
getBuf
(
PARAMETER_VALUE
);
const
VectorPtr
&
gpuVec
=
testGpu
.
para_
->
getBuf
(
PARAMETER_VALUE
);
...
...
paddle/math/Matrix.cpp
浏览文件 @
93006787
...
...
@@ -146,6 +146,7 @@ void Matrix::resizeOrCreate(MatrixPtr& matrix, size_t height, size_t width,
if
(
!
matrix
)
{
matrix
=
Matrix
::
create
(
height
,
width
,
trans
,
useGpu
);
}
else
{
CHECK_EQ
(
matrix
->
useGpu
(),
useGpu
);
matrix
->
resize
(
height
,
width
);
}
}
...
...
@@ -161,6 +162,7 @@ void Matrix::resizeOrCreateSparseMatrix(MatrixPtr& matrix, size_t height,
}
else
{
CHECK
(
dynamic_cast
<
CpuSparseMatrix
*>
(
matrix
.
get
())
||
dynamic_cast
<
GpuSparseMatrix
*>
(
matrix
.
get
()));
CHECK_EQ
(
matrix
->
useGpu
(),
useGpu
);
matrix
->
resize
(
height
,
width
,
nnz
,
valueType
,
format
);
}
}
...
...
paddle/math/Vector.cpp
浏览文件 @
93006787
...
...
@@ -800,6 +800,7 @@ void CpuGpuVectorT<T>::resizeOrCreate(size_t size, bool useGpu) {
}
else
if
((
!
useGpu
)
&&
(
!
cpuVectorT_
))
{
cpuVectorT_
=
VectorT
<
T
>::
create
(
size
,
false
);
}
else
{
CHECK
((
useGpu
&&
gpuVectorT_
)
||
(
!
useGpu
&&
cpuVectorT_
));
this
->
resize
(
size
,
useGpu
);
}
}
...
...
paddle/parameter/Argument.cpp
浏览文件 @
93006787
...
...
@@ -25,6 +25,7 @@ static void resizeAndCopy(MatrixPtr& dest, const MatrixPtr& src, bool useGpu,
if
(
!
dest
)
{
dest
=
src
->
clone
(
0
,
0
,
useGpu
);
}
else
{
CHECK_EQ
(
dest
->
useGpu
(),
useGpu
);
dest
->
resize
(
src
->
getHeight
(),
src
->
getWidth
());
}
dest
->
copyFrom
(
*
src
,
stream
);
...
...
@@ -60,12 +61,12 @@ static void resizeAndCopy(MatrixPtr& dest, const MatrixPtr& src,
hl_stream_t
stream
=
HPPL_STREAM_DEFAULT
)
{
if
(
src
)
{
CHECK_LE
((
size_t
)
startRow
+
copySize
,
src
->
getHeight
());
int
height
=
copySize
;
int
width
=
src
->
getWidth
();
if
(
!
dest
)
{
dest
=
src
->
clone
(
height
,
width
,
useGpu
);
}
else
{
CHECK_EQ
(
dest
->
useGpu
(),
useGpu
);
dest
->
resize
(
height
,
width
);
}
MatrixPtr
submat
=
src
->
subMatrix
(
startRow
,
copySize
);
...
...
@@ -182,6 +183,11 @@ static void resizeAndCopy(SVectorPtr& dest, const SVectorPtr& src,
}
}
void
Argument
::
resizeAndCopyFrom
(
const
Argument
&
src
,
bool
useGpu
)
{
resizeAndCopyFrom
(
src
,
useGpu
,
HPPL_STREAM_DEFAULT
);
hl_stream_synchronize
(
HPPL_STREAM_DEFAULT
);
}
void
Argument
::
resizeAndCopyFrom
(
const
Argument
&
src
,
bool
useGpu
,
hl_stream_t
stream
)
{
dataId
=
src
.
dataId
;
...
...
@@ -199,6 +205,14 @@ void Argument::resizeAndCopyFrom(const Argument& src, bool useGpu,
resizeAndCopy
(
strs
,
src
.
strs
,
useGpu
,
stream
);
}
int32_t
Argument
::
resizeAndCopyFrom
(
const
Argument
&
src
,
int32_t
startSeq
,
int32_t
copySize
,
bool
useGpu
)
{
int32_t
size
=
resizeAndCopyFrom
(
src
,
startSeq
,
copySize
,
useGpu
,
HPPL_STREAM_DEFAULT
);
hl_stream_synchronize
(
HPPL_STREAM_DEFAULT
);
return
size
;
}
int32_t
Argument
::
resizeAndCopyFrom
(
const
Argument
&
src
,
int32_t
startSeq
,
int32_t
copySize
,
bool
useGpu
,
hl_stream_t
stream
)
{
...
...
paddle/parameter/Argument.h
浏览文件 @
93006787
...
...
@@ -203,13 +203,28 @@ struct Argument {
* startSeq: the sample id of start
* copySize: how many samples need to copy
* return value: how many samples are copied
* Note that when specifying the stream explicitly in this case,
* synchronize should also be called somewhere after this function
*/
int32_t
resizeAndCopyFrom
(
const
Argument
&
src
,
int32_t
startSeq
,
int32_t
copySize
,
bool
useGpu
=
FLAGS_use_gpu
,
hl_stream_t
stream
=
HPPL_STREAM_DEFAULT
);
int32_t
copySize
,
bool
useGpu
,
hl_stream_t
stream
);
void
resizeAndCopyFrom
(
const
Argument
&
src
,
bool
useGpu
=
FLAGS_use_gpu
,
hl_stream_t
stream
=
HPPL_STREAM_DEFAULT
);
/*
* same with the above function, except that the stream is
* HPPL_STREAM_DEFAULT and synchronize is automatically called
* inside it
*/
int32_t
resizeAndCopyFrom
(
const
Argument
&
src
,
int32_t
startSeq
,
int32_t
copySize
,
bool
useGpu
=
FLAGS_use_gpu
);
void
resizeAndCopyFrom
(
const
Argument
&
src
,
bool
useGpu
,
hl_stream_t
stream
);
/*
* same with the above function, except that the stream is
* HPPL_STREAM_DEFAULT and synchronize is automatically called
* inside it
*/
void
resizeAndCopyFrom
(
const
Argument
&
src
,
bool
useGpu
=
FLAGS_use_gpu
);
/*
@brief Concatenate several arguments into one and put the result into it.
...
...
@@ -240,6 +255,15 @@ struct Argument {
/*
Get Sequence Length, startPositions and max Length according to input
1. For sequence data:
Each tuple is (seq_length, seq_start, seq_id, seq_id)
The tuples are sorted according to seq_length or subseq_length
*maxSequenceLength is the maximal sequence length
2. For subsequence data:
Each tuple is (subseq_length, subseq_start, seq_id, subseq_id)
The tuples are not sorted. They are in the original order.
*maxSequenceLenth is the maximal number of subsequences in each sequence.
*/
void
getSeqLengthAndStart
(
std
::
vector
<
std
::
tuple
<
int
,
int
,
int
,
int
>>*
seqLengthAndStart
,
...
...
proto/ModelConfig.proto.m4
浏览文件 @
93006787
...
...
@@ -452,6 +452,9 @@ message SubModelConfig {
repeated
LinkConfig
out_links
=
10
;
optional
GeneratorConfig
generator
=
11
;
//
the
id
of
inlink
which
share
info
with
outlinks
,
used
in
recurrent
layer
group
optional
int32
target_inlinkid
=
12
;
}
message
ModelConfig
{
...
...
python/paddle/trainer/config_parser.py
浏览文件 @
93006787
...
...
@@ -303,7 +303,8 @@ def MakeLayerNameInSubmodel(name, submodel_name = None):
@
config_func
def
RecurrentLayerGroupWithoutOutLinksBegin
(
name
,
in_links
,
seq_reversed
=
False
):
seq_reversed
=
False
,
target_inlinkname
=
""
):
global
g_current_submodel
config_assert
(
g_config
.
model_config
.
type
==
"recurrent_nn"
,
"RecurrentLayerGroup should be used only in recurrent_nn"
)
...
...
@@ -311,14 +312,19 @@ def RecurrentLayerGroupWithoutOutLinksBegin(name,
SubModelBegin
(
name
)
g_current_submodel
.
is_recurrent_layer_group
=
True
g_current_submodel
.
reversed
=
seq_reversed
g_current_submodel
.
target_inlinkid
=
-
1
in_links_count
=
0
for
link
in
in_links
:
for
link
id
,
link
in
enumerate
(
in_links
)
:
if
isinstance
(
link
,
basestring
):
name
=
link
has_subseq
=
False
else
:
name
=
link
.
link_name
has_subseq
=
link
.
has_subseq
# assign target_inlinkid according to target_inlinkname
if
target_inlinkname
==
name
:
g_current_submodel
.
target_inlinkid
=
linkid
if
in_links_count
==
0
:
in_links_has_subseq
=
has_subseq
else
:
...
...
@@ -331,6 +337,7 @@ def RecurrentLayerGroupWithoutOutLinksBegin(name,
SequenceScatterAgentLayer
(
name
=
name
,
size
=
layer
.
size
)
else
:
ScatterAgentLayer
(
name
=
name
,
size
=
layer
.
size
)
pair
=
g_current_submodel
.
in_links
.
add
()
pair
.
layer_name
=
layer_name
pair
.
link_name
=
MakeLayerNameInSubmodel
(
name
)
...
...
@@ -362,10 +369,12 @@ def RecurrentLayerGroupBegin(name,
in_links
,
out_links
,
generator
=
None
,
target_inlinkname
=
""
,
seq_reversed
=
False
):
RecurrentLayerGroupWithoutOutLinksBegin
(
name
,
in_links
,
seq_reversed
)
seq_reversed
,
target_inlinkname
)
for
link
in
out_links
:
RecurrentLayerGroupSetOutLink
(
link
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录