Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
a037b099
P
Paddle
项目概览
机器未来
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
a037b099
编写于
8月 14, 2017
作者:
C
caoying03
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
finish unittest.
上级
1e828dc1
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
191 addition
and
28 deletion
+191
-28
paddle/gserver/layers/CrossEntropyOverBeam.cpp
paddle/gserver/layers/CrossEntropyOverBeam.cpp
+1
-0
paddle/gserver/tests/test_CrossEntropyOverBeamGrad.cpp
paddle/gserver/tests/test_CrossEntropyOverBeamGrad.cpp
+190
-28
未找到文件。
paddle/gserver/layers/CrossEntropyOverBeam.cpp
浏览文件 @
a037b099
...
...
@@ -22,6 +22,7 @@ bool CrossEntropyOverBeam::init(const LayerMap& layerMap,
const
ParameterMap
&
parameterMap
)
{
/* Initialize the basic parent class */
Layer
::
init
(
layerMap
,
parameterMap
);
CHECK_EQ
(
0U
,
inputLayers_
.
size
()
%
3
)
<<
"Error input number."
;
setNeedSequenceInfo
(
false
);
...
...
paddle/gserver/tests/test_CrossEntropyOverBeamGrad.cpp
浏览文件 @
a037b099
...
...
@@ -12,6 +12,7 @@ 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 <random>
#include <sstream>
#include <gtest/gtest.h>
...
...
@@ -27,6 +28,10 @@ using namespace paddle; // NOLINT
DECLARE_int32
(
gpu_id
);
DECLARE_bool
(
thread_local_rand_use_global_seed
);
const
size_t
MAX_SEQ_NUM
=
10
;
const
size_t
MAX_SEQ_LEN
=
27
;
const
size_t
MAX_BEAM_SIZE
=
10
;
struct
SingleBeamExpansion
{
vector
<
int
>
seqStartPos
;
vector
<
int
>
subSeqStartPos
;
...
...
@@ -34,37 +39,195 @@ struct SingleBeamExpansion {
// TODO(caoying): store this into Argument.ids
vector
<
real
>
selectedIndices
;
vector
<
int
>
groundTruth
;
vector
<
int
>
labelSeqStartPos
;
vector
<
size_t
>
inBeam
;
vector
<
int
>
rowIdxInBeam
;
};
void
genCandidateScores
(
bool
hasSubSeq
,
vector
<
real
>&
scores
,
void
genRand
(
real
*
numbers
,
size_t
n
)
{
default_random_engine
generator
;
uniform_real_distribution
<
double
>
distribution
(
0.0
,
1.0
);
for
(
size_t
i
=
0
;
i
<
n
;
++
i
)
numbers
[
i
]
=
distribution
(
generator
);
}
vector
<
real
>
randSampling
(
real
range
,
int
n
)
{
CHECK_GE
(
range
,
n
);
vector
<
real
>
num
(
range
);
iota
(
begin
(
num
),
end
(
num
),
0.
);
if
(
range
==
n
)
return
num
;
random_shuffle
(
begin
(
num
),
end
(
num
));
num
.
resize
(
n
);
sort
(
begin
(
num
),
end
(
num
));
return
num
;
}
void
genCandidateScores
(
bool
hasSubseq
,
size_t
beamSize
,
SingleBeamExpansion
&
prevBeam
,
SingleBeamExpansion
&
curBeam
)
{
vector
<
int
>&
seqStartPos
=
curBeam
.
seqStartPos
;
seqStartPos
.
resize
(
1
,
0
);
vector
<
int
>&
subSeqStartPos
=
curBeam
.
subSeqStartPos
;
subSeqStartPos
.
resize
(
1
,
0
);
srand
((
size_t
)(
time
(
NULL
)));
// srand(1);
if
(
prevBeam
.
selectedIndices
.
size
())
{
if
(
prevBeam
.
subSeqStartPos
.
size
()
>
1
)
{
int
seqIdx
=
1
;
// samples in previous beam are nested sequences.
for
(
size_t
i
=
1
;
i
<
prevBeam
.
subSeqStartPos
.
size
();
++
i
)
{
for
(
size_t
j
=
0
;
j
<
beamSize
;
++
j
)
{
if
(
prevBeam
.
selectedIndices
[(
i
-
1
)
*
beamSize
+
j
]
==
-
1.
)
break
;
for
(
size_t
k
=
0
;
k
<
beamSize
;
++
k
)
subSeqStartPos
.
push_back
(
1
+
(
rand
()
%
MAX_SEQ_LEN
)
+
subSeqStartPos
.
back
());
}
if
(
prevBeam
.
seqStartPos
[
seqIdx
]
==
prevBeam
.
subSeqStartPos
[
i
])
{
seqStartPos
.
push_back
(
subSeqStartPos
.
back
());
seqIdx
++
;
}
}
}
else
{
// samples in previous beam are sequences.
for
(
size_t
i
=
0
;
i
<=
prevBeam
.
selectedIndices
.
size
();
++
i
)
{
if
(
i
&&
i
%
beamSize
==
0
)
{
seqStartPos
.
push_back
(
subSeqStartPos
.
back
());
if
(
i
==
prevBeam
.
selectedIndices
.
size
())
break
;
}
if
(
prevBeam
.
selectedIndices
[
i
]
==
-
1.
)
continue
;
subSeqStartPos
.
push_back
(
subSeqStartPos
.
back
()
+
(
1
+
(
rand
()
%
MAX_SEQ_LEN
)));
}
}
}
else
{
// the first beam expansion
int
seqNum
=
1
+
(
rand
()
%
MAX_SEQ_NUM
);
for
(
int
i
=
0
;
i
<
seqNum
;
++
i
)
{
if
(
hasSubseq
)
{
for
(
size_t
j
=
0
;
j
<
1
+
(
rand
()
%
MAX_SEQ_NUM
);
++
j
)
subSeqStartPos
.
push_back
(
subSeqStartPos
.
back
()
+
(
1
+
(
rand
()
%
MAX_SEQ_LEN
)));
seqStartPos
.
push_back
(
subSeqStartPos
.
back
());
}
else
{
seqStartPos
.
push_back
(
seqStartPos
.
back
()
+
(
1
+
(
rand
()
%
MAX_SEQ_LEN
)));
}
}
}
size_t
totalSeqNum
=
hasSubseq
?
subSeqStartPos
.
back
()
:
seqStartPos
.
back
();
curBeam
.
candidateScores
.
resize
(
totalSeqNum
,
0.
);
genRand
(
curBeam
.
candidateScores
.
data
(),
totalSeqNum
);
}
void
genSelectedIndices
(
size_t
beamSize
,
vector
<
int
>&
seqStartPos
,
vector
<
int
>&
subSeqStartPos
)
{}
void
genSelectedIndicesAndGroundtruth
(
size_t
beamSize
,
vector
<
int
>&
seqStartPos
,
vector
<
real
>&
selectedIndices
)
{}
SingleBeamExpansion
genOneBeam
(
size_t
beamSize
,
bool
hasSubSeq
)
{
SingleBeamExpansion
beam
;
genCandidateScores
(
hasSubSeq
,
beam
.
candidateScores
,
beam
.
seqStartPos
,
beam
.
subSeqStartPos
);
genSelectedIndicesAndGroundtruth
(
beamSize
,
hasSubSeq
?
beam
.
subSeqStartPos
:
beam
.
seqStartPos
,
beam
.
selectedIndices
);
return
beam
;
vector
<
real
>&
selectedIndices
)
{
size_t
selectedIdsCount
=
beamSize
*
(
seqStartPos
.
size
()
-
1
);
selectedIndices
.
resize
(
selectedIdsCount
,
-
1.
);
for
(
size_t
i
=
0
;
i
<
seqStartPos
.
size
()
-
1
;
++
i
)
{
int
seqLen
=
seqStartPos
[
i
+
1
]
-
seqStartPos
[
i
];
int
n
=
min
(
seqLen
,
static_cast
<
int
>
(
beamSize
));
vector
<
real
>
ids
=
randSampling
(
seqLen
,
n
);
memcpy
(
selectedIndices
.
data
()
+
i
*
beamSize
,
ids
.
data
(),
sizeof
(
real
)
*
ids
.
size
());
}
}
void
genGroundTruth
(
vector
<
SingleBeamExpansion
>&
beamExpansions
,
size_t
beamSize
)
{
size_t
seqNum
=
beamExpansions
[
1
].
seqStartPos
.
size
()
-
1
;
for
(
size_t
i
=
2
;
i
<
beamExpansions
.
size
();
++
i
)
CHECK_EQ
(
seqNum
,
beamExpansions
[
i
-
1
].
seqStartPos
.
size
()
-
1
);
// srand(1);
srand
((
size_t
)(
time
(
NULL
)));
// initialize the first beam.
SingleBeamExpansion
&
beam
=
beamExpansions
[
1
];
beam
.
groundTruth
.
resize
(
seqNum
,
0
);
beam
.
inBeam
.
resize
(
seqNum
,
0
);
beam
.
rowIdxInBeam
.
resize
(
seqNum
,
-
1
);
auto
begPos
=
beam
.
selectedIndices
.
begin
();
for
(
size_t
i
=
0
;
i
<
seqNum
;
++
i
)
{
int
seqLen
=
beam
.
seqStartPos
[
i
+
1
]
-
beam
.
seqStartPos
[
i
];
int
label
=
rand
()
%
seqLen
;
auto
endPos
=
begPos
+
beamSize
;
beam
.
groundTruth
[
i
]
=
label
;
if
(
find
(
begPos
,
endPos
,
real
(
label
))
!=
endPos
)
beam
.
inBeam
[
i
]
=
1
;
begPos
=
endPos
;
beam
.
rowIdxInBeam
[
i
]
=
i
;
}
// iterate over each beam expansions
for
(
size_t
i
=
2
;
i
<
beamExpansions
.
size
();
++
i
)
{
SingleBeamExpansion
&
curBeam
=
beamExpansions
[
i
];
SingleBeamExpansion
&
prevBeam
=
beamExpansions
[
i
-
1
];
curBeam
.
groundTruth
.
resize
(
seqNum
,
0
);
curBeam
.
inBeam
.
resize
(
seqNum
,
0
);
curBeam
.
rowIdxInBeam
.
resize
(
seqNum
,
-
1
);
// iterate over each sequence
for
(
size_t
j
=
0
;
j
<
seqNum
;
++
j
)
{
if
(
prevBeam
.
inBeam
[
j
])
{
// gold sequence falls in the beam in previous search.
auto
begPos
=
prevBeam
.
selectedIndices
.
begin
();
auto
endPos
=
begPos
+
prevBeam
.
rowIdxInBeam
[
j
]
*
beamSize
;
size_t
totalExpansion
=
prevBeam
.
rowIdxInBeam
[
j
]
*
beamSize
-
count
(
begPos
,
endPos
,
-
1.
);
curBeam
.
rowIdxInBeam
[
j
]
=
totalExpansion
+
prevBeam
.
groundTruth
[
j
];
CHECK_LE
(
curBeam
.
rowIdxInBeam
[
j
]
+
1
,
curBeam
.
subSeqStartPos
.
size
()
-
1
);
int
start
=
curBeam
.
subSeqStartPos
[
curBeam
.
rowIdxInBeam
[
j
]];
int
end
=
curBeam
.
subSeqStartPos
[
curBeam
.
rowIdxInBeam
[
j
]
+
1
];
CHECK_GT
(
size_t
(
end
),
size_t
(
start
));
int
label
=
rand
()
%
(
end
-
start
);
curBeam
.
groundTruth
[
j
]
=
label
;
auto
findBeg
=
curBeam
.
selectedIndices
.
begin
()
+
curBeam
.
rowIdxInBeam
[
j
]
*
beamSize
;
auto
findEnd
=
findBeg
+
beamSize
;
if
(
find
(
findBeg
,
findEnd
,
real
(
label
))
!=
findEnd
)
curBeam
.
inBeam
[
j
]
=
1
;
}
else
{
// in previous search, gold sequence has fallen off the beam,
// the beam search stops, here use -1 as a dummy label.
// It will not used in calculation the cost.
beamExpansions
[
i
].
groundTruth
[
j
]
=
-
1
;
}
}
}
}
void
genOneBeam
(
size_t
beamSize
,
bool
hasSubseq
,
SingleBeamExpansion
&
prevBeam
,
SingleBeamExpansion
&
curBeam
)
{
genCandidateScores
(
hasSubseq
,
beamSize
,
prevBeam
,
curBeam
);
genSelectedIndices
(
beamSize
,
hasSubseq
?
curBeam
.
subSeqStartPos
:
curBeam
.
seqStartPos
,
curBeam
.
selectedIndices
);
}
void
genRandomBeamExpansion
(
size_t
expansionCount
,
size_t
beamSize
,
vector
<
SingleBeamExpansion
>&
beamExpansions
)
{
beamExpansions
.
clear
();
for
(
size_t
i
=
0
;
i
<
expansionCount
;
++
i
)
{
beamExpansions
.
emplace_back
(
genOneBeam
(
beamSize
,
i
));
}
beamExpansions
.
resize
(
expansionCount
+
1
);
// beamExpansions[0] is reserved.
for
(
size_t
i
=
1
;
i
<=
expansionCount
;
++
i
)
genOneBeam
(
beamSize
,
bool
(
i
-
1
),
beamExpansions
[
i
-
1
],
beamExpansions
[
i
]);
genGroundTruth
(
beamExpansions
,
beamSize
);
}
void
testCrossEntropyOverBeam
(
bool
useGpu
)
{
...
...
@@ -72,12 +235,12 @@ void testCrossEntropyOverBeam(bool useGpu) {
config
.
layerConfig
.
set_type
(
"cross_entropy_over_beam"
);
const
size_t
expansionCount
=
3
;
const
size_t
beamSize
=
3
;
const
size_t
beamSize
=
MAX_BEAM_SIZE
;
vector
<
SingleBeamExpansion
>
beams
;
genRandomBeamExpansion
(
expansionCount
,
beamSize
,
beams
);
size_t
seqNum
=
0
;
for
(
size_t
i
=
0
;
i
<
beams
.
size
();
++
i
)
{
for
(
size_t
i
=
1
;
i
<
beams
.
size
();
++
i
)
{
const
SingleBeamExpansion
&
beam
=
beams
[
i
];
// create scores for all the candidates
MatrixPtr
candidateScorePtr
=
...
...
@@ -88,7 +251,7 @@ void testCrossEntropyOverBeam(bool useGpu) {
ostringstream
paramName
;
paramName
<<
"candidate_scores_"
<<
i
;
if
(
beam
.
subSeqStartPos
.
size
())
{
if
(
beam
.
subSeqStartPos
.
size
()
>
1
)
{
seqNum
=
beam
.
subSeqStartPos
.
size
()
-
1
;
config
.
inputDefs
.
push_back
({
INPUT_SELF_DEFINE_DATA
,
paramName
.
str
(),
...
...
@@ -118,10 +281,9 @@ void testCrossEntropyOverBeam(bool useGpu) {
// create the ground truth
paramName
.
clear
();
paramName
<<
"label_"
<<
i
;
config
.
inputDefs
.
push_back
({
INPUT_SELF_DEFINE_DATA
,
paramName
.
str
(),
beam
.
groundTruth
,
beam
.
labelSeqStartPos
});
config
.
inputDefs
.
push_back
(
{
INPUT_SELF_DEFINE_DATA
,
paramName
.
str
(),
beam
.
groundTruth
});
config
.
layerConfig
.
add_inputs
();
}
testLayerGrad
(
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录