Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
97708add
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看板
未验证
提交
97708add
编写于
6月 09, 2020
作者:
H
Huihuang Zheng
提交者:
GitHub
6月 09, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[Dy2stat] Add word2vec as unittest (#24944)
[Dy2stat] Add word2vec as unittest
上级
0eb1b0bc
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
306 addition
and
0 deletion
+306
-0
python/paddle/fluid/tests/unittests/dygraph_to_static/test_word2vec.py
.../fluid/tests/unittests/dygraph_to_static/test_word2vec.py
+306
-0
未找到文件。
python/paddle/fluid/tests/unittests/dygraph_to_static/test_word2vec.py
0 → 100644
浏览文件 @
97708add
# Copyright (c) 2020 PaddlePaddle Authors. 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.
import
io
import
os
import
sys
import
requests
from
collections
import
OrderedDict
import
math
import
random
import
numpy
as
np
import
paddle
import
paddle.fluid
as
fluid
import
unittest
from
paddle.fluid.dygraph.nn
import
Embedding
from
paddle.fluid.dygraph
import
ProgramTranslator
from
paddle.fluid.dygraph
import
declarative
def
fake_text
():
corpus
=
[]
for
i
in
range
(
100
):
line
=
"i love paddlepaddle"
corpus
.
append
(
line
)
return
corpus
corpus
=
fake_text
()
def
data_preprocess
(
corpus
):
new_corpus
=
[]
for
line
in
corpus
:
line
=
line
.
strip
().
lower
()
line
=
line
.
split
(
" "
)
new_corpus
.
append
(
line
)
return
new_corpus
corpus
=
data_preprocess
(
corpus
)
def
build_dict
(
corpus
,
min_freq
=
3
):
word_freq_dict
=
dict
()
for
line
in
corpus
:
for
word
in
line
:
if
word
not
in
word_freq_dict
:
word_freq_dict
[
word
]
=
0
word_freq_dict
[
word
]
+=
1
word_freq_dict
=
sorted
(
word_freq_dict
.
items
(),
key
=
lambda
x
:
x
[
1
],
reverse
=
True
)
word2id_dict
=
dict
()
word2id_freq
=
dict
()
id2word_dict
=
dict
()
word2id_freq
[
0
]
=
1.
word2id_dict
[
'[oov]'
]
=
0
id2word_dict
[
0
]
=
'[oov]'
for
word
,
freq
in
word_freq_dict
:
if
freq
<
min_freq
:
word2id_freq
[
0
]
+=
freq
continue
curr_id
=
len
(
word2id_dict
)
word2id_dict
[
word
]
=
curr_id
word2id_freq
[
word2id_dict
[
word
]]
=
freq
id2word_dict
[
curr_id
]
=
word
return
word2id_freq
,
word2id_dict
,
id2word_dict
word2id_freq
,
word2id_dict
,
id2word_dict
=
build_dict
(
corpus
)
vocab_size
=
len
(
word2id_freq
)
print
(
"there are totoally %d different words in the corpus"
%
vocab_size
)
for
_
,
(
word
,
word_id
)
in
zip
(
range
(
50
),
word2id_dict
.
items
()):
print
(
"word %s, its id %d, its word freq %d"
%
(
word
,
word_id
,
word2id_freq
[
word_id
]))
def
convert_corpus_to_id
(
corpus
,
word2id_dict
):
new_corpus
=
[]
for
line
in
corpus
:
new_line
=
[
word2id_dict
[
word
]
if
word
in
word2id_dict
else
word2id_dict
[
'[oov]'
]
for
word
in
line
]
new_corpus
.
append
(
new_line
)
return
new_corpus
corpus
=
convert_corpus_to_id
(
corpus
,
word2id_dict
)
def
subsampling
(
corpus
,
word2id_freq
):
def
keep
(
word_id
):
return
random
.
uniform
(
0
,
1
)
<
math
.
sqrt
(
1e-4
/
word2id_freq
[
word_id
]
*
len
(
corpus
))
new_corpus
=
[]
for
line
in
corpus
:
new_line
=
[
word
for
word
in
line
if
keep
(
word
)]
new_corpus
.
append
(
line
)
return
new_corpus
corpus
=
subsampling
(
corpus
,
word2id_freq
)
def
build_data
(
corpus
,
word2id_dict
,
word2id_freq
,
max_window_size
=
3
,
negative_sample_num
=
10
):
dataset
=
[]
for
line
in
corpus
:
for
center_word_idx
in
range
(
len
(
line
)):
window_size
=
random
.
randint
(
1
,
max_window_size
)
center_word
=
line
[
center_word_idx
]
positive_word_range
=
(
max
(
0
,
center_word_idx
-
window_size
),
min
(
len
(
line
)
-
1
,
center_word_idx
+
window_size
))
positive_word_candidates
=
[
line
[
idx
]
for
idx
in
range
(
positive_word_range
[
0
],
positive_word_range
[
1
]
+
1
)
if
idx
!=
center_word_idx
and
line
[
idx
]
!=
line
[
center_word_idx
]
]
if
not
positive_word_candidates
:
continue
for
positive_word
in
positive_word_candidates
:
dataset
.
append
((
center_word
,
positive_word
,
1
))
i
=
0
while
i
<
negative_sample_num
:
negative_word_candidate
=
random
.
randint
(
0
,
vocab_size
-
1
)
if
negative_word_candidate
not
in
positive_word_candidates
:
dataset
.
append
((
center_word
,
negative_word_candidate
,
0
))
i
+=
1
return
dataset
dataset
=
build_data
(
corpus
,
word2id_dict
,
word2id_freq
)
for
_
,
(
center_word
,
target_word
,
label
)
in
zip
(
range
(
50
),
dataset
):
print
(
"center_word %s, target %s, label %d"
%
(
id2word_dict
[
center_word
],
id2word_dict
[
target_word
],
label
))
def
build_batch
(
dataset
,
batch_size
,
epoch_num
):
center_word_batch
=
[]
target_word_batch
=
[]
label_batch
=
[]
eval_word_batch
=
[]
for
epoch
in
range
(
epoch_num
):
for
center_word
,
target_word
,
label
in
dataset
:
center_word_batch
.
append
([
center_word
])
target_word_batch
.
append
([
target_word
])
label_batch
.
append
([
label
])
if
len
(
eval_word_batch
)
<
5
:
eval_word_batch
.
append
([
random
.
randint
(
0
,
99
)])
elif
len
(
eval_word_batch
)
<
10
:
eval_word_batch
.
append
([
random
.
randint
(
0
,
vocab_size
-
1
)])
if
len
(
center_word_batch
)
==
batch_size
:
yield
np
.
array
(
center_word_batch
).
astype
(
"int64"
),
np
.
array
(
target_word_batch
).
astype
(
"int64"
),
np
.
array
(
label_batch
).
astype
(
"float32"
),
np
.
array
(
eval_word_batch
).
astype
(
"int64"
)
center_word_batch
=
[]
target_word_batch
=
[]
label_batch
=
[]
eval_word_batch
=
[]
if
len
(
center_word_batch
)
>
0
:
yield
np
.
array
(
center_word_batch
).
astype
(
"int64"
),
np
.
array
(
target_word_batch
).
astype
(
"int64"
),
np
.
array
(
label_batch
).
astype
(
"float32"
),
np
.
array
(
eval_word_batch
).
astype
(
"int64"
)
class
SkipGram
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
name_scope
,
vocab_size
,
embedding_size
,
init_scale
=
0.1
):
super
(
SkipGram
,
self
).
__init__
(
name_scope
)
self
.
vocab_size
=
vocab_size
self
.
embedding_size
=
embedding_size
self
.
embedding
=
Embedding
(
size
=
[
self
.
vocab_size
,
self
.
embedding_size
],
dtype
=
'float32'
,
param_attr
=
fluid
.
ParamAttr
(
name
=
'embedding_para'
,
initializer
=
fluid
.
initializer
.
UniformInitializer
(
low
=-
0.5
/
self
.
embedding_size
,
high
=
0.5
/
self
.
embedding_size
)))
self
.
embedding_out
=
Embedding
(
size
=
[
self
.
vocab_size
,
self
.
embedding_size
],
dtype
=
'float32'
,
param_attr
=
fluid
.
ParamAttr
(
name
=
'embedding_out_para'
,
initializer
=
fluid
.
initializer
.
UniformInitializer
(
low
=-
0.5
/
self
.
embedding_size
,
high
=
0.5
/
self
.
embedding_size
)))
@
declarative
def
forward
(
self
,
center_words
,
target_words
,
label
):
center_words_emb
=
self
.
embedding
(
center_words
)
target_words_emb
=
self
.
embedding_out
(
target_words
)
# center_words_emb = [batch_size, embedding_size]
# target_words_emb = [batch_size, embedding_size]
word_sim
=
fluid
.
layers
.
elementwise_mul
(
center_words_emb
,
target_words_emb
)
word_sim
=
fluid
.
layers
.
reduce_sum
(
word_sim
,
dim
=-
1
)
pred
=
fluid
.
layers
.
sigmoid
(
word_sim
)
loss
=
fluid
.
layers
.
sigmoid_cross_entropy_with_logits
(
word_sim
,
label
)
loss
=
fluid
.
layers
.
reduce_mean
(
loss
)
return
pred
,
loss
batch_size
=
512
epoch_num
=
1
embedding_size
=
200
learning_rate
=
1e-3
total_steps
=
len
(
dataset
)
*
epoch_num
//
batch_size
def
train
(
to_static
):
program_translator
=
ProgramTranslator
()
program_translator
.
enable
(
to_static
)
random
.
seed
(
0
)
np
.
random
.
seed
(
0
)
place
=
fluid
.
CUDAPlace
(
0
)
if
fluid
.
is_compiled_with_cuda
(
)
else
fluid
.
CPUPlace
()
with
fluid
.
dygraph
.
guard
(
place
):
fluid
.
default_startup_program
().
random_seed
=
1000
fluid
.
default_main_program
().
random_seed
=
1000
skip_gram_model
=
SkipGram
(
"skip_gram_model"
,
vocab_size
,
embedding_size
)
adam
=
fluid
.
optimizer
.
AdamOptimizer
(
learning_rate
=
learning_rate
,
parameter_list
=
skip_gram_model
.
parameters
())
step
=
0
ret
=
[]
for
center_words
,
target_words
,
label
,
eval_words
in
build_batch
(
dataset
,
batch_size
,
epoch_num
):
center_words_var
=
fluid
.
dygraph
.
to_variable
(
center_words
)
target_words_var
=
fluid
.
dygraph
.
to_variable
(
target_words
)
label_var
=
fluid
.
dygraph
.
to_variable
(
label
)
pred
,
loss
=
skip_gram_model
(
center_words_var
,
target_words_var
,
label_var
)
loss
.
backward
()
adam
.
minimize
(
loss
)
skip_gram_model
.
clear_gradients
()
step
+=
1
mean_loss
=
np
.
mean
(
loss
.
numpy
())
print
(
"step %d / %d, loss %f"
%
(
step
,
total_steps
,
mean_loss
))
ret
.
append
(
mean_loss
)
return
np
.
array
(
ret
)
class
TestWord2Vec
(
unittest
.
TestCase
):
def
test_dygraph_static_same_loss
(
self
):
dygraph_loss
=
train
(
to_static
=
False
)
static_loss
=
train
(
to_static
=
True
)
self
.
assertTrue
(
np
.
allclose
(
dygraph_loss
,
static_loss
),
msg
=
"dygraph_loss: {}
\n
static_loss: {}"
.
format
(
dygraph_loss
,
static_loss
))
if
__name__
==
'__main__'
:
unittest
.
main
()
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录