Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
models
提交
7b6c3879
M
models
项目概览
PaddlePaddle
/
models
1 年多 前同步成功
通知
222
Star
6828
Fork
2962
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
602
列表
看板
标记
里程碑
合并请求
255
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
models
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
602
Issue
602
列表
看板
标记
里程碑
合并请求
255
合并请求
255
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
7b6c3879
编写于
9月 27, 2018
作者:
G
guosheng
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add gen_data.sh in Transformer
上级
02224d03
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
171 addition
and
12 deletion
+171
-12
fluid/neural_machine_translation/transformer/README_cn.md
fluid/neural_machine_translation/transformer/README_cn.md
+4
-11
fluid/neural_machine_translation/transformer/gen_data.sh
fluid/neural_machine_translation/transformer/gen_data.sh
+166
-0
fluid/neural_machine_translation/transformer/model.py
fluid/neural_machine_translation/transformer/model.py
+1
-1
未找到文件。
fluid/neural_machine_translation/transformer/README_cn.md
浏览文件 @
7b6c3879
...
...
@@ -16,7 +16,7 @@
├── reader.py # 数据读取接口
├── README.md # 文档
├── train.py # 训练脚本
└──
util.py # wordpiece 数据解码工具
└──
gen_data.sh # 数据生成脚本
```
### 简介
...
...
@@ -59,11 +59,8 @@ Decoder 具有和 Encoder 类似的结构,只是相比于组成 Encoder 的 la
### 数据准备
WMT 数据集是机器翻译领域公认的主流数据集;WMT 英德和英法数据集也是 Transformer 论文中所用数据集,其中英德数据集使用了 BPE(byte-pair encoding)[4]编码的数据,英法数据集使用了 wordpiece [5]的数据。我们这里也将使用 WMT 英德和英法翻译数据,并和论文保持一致使用 BPE 和 wordpiece 的数据,下面给出了使用的方法。对于其他自定义数据,参照下文遵循或转换为类似的数据格式即可。
#### WMT 英德翻译数据
[
WMT'16 EN-DE 数据集
](
http://www.statmt.org/wmt16/translation-task.html
)
是一个中等规模的数据集。参照论文,英德数据集我们使用 BPE 编码的数据,这能够更好的解决未登录词(out-of-vocabulary,OOV)的问题
[
4]。用到的 BPE 数据可以参照[这里
](
https://github.com/google/seq2seq/blob/master/docs/data.md
)
进行下载(如果希望在自定义数据中使用 BPE 编码,可以参照
[
这里
](
https://github.com/rsennrich/subword-nmt
)
进行预处理),下载后解压,其中
`train.tok.clean.bpe.32000.en`
和
`train.tok.clean.bpe.32000.de`
为使用 BPE 的训练数据(平行语料,分别对应了英语和德语,经过了 tokenize 和 BPE 的处理),
`newstest2016.tok.bpe.32000.en`
和
`newstest2016.tok.bpe.32000.de`
等为测试数据(
`newstest2016.tok.en`
和
`newstest2016.tok.de`
等则为对应的未使用 BPE 的测试数据),
`vocab.bpe.32000`
为相应的词典文件(源语言和目标语言共享该词典文件)。
WMT 数据集是机器翻译领域公认的主流数据集,
[
WMT'16 EN-DE 数据集
](
http://www.statmt.org/wmt16/translation-task.html
)
是其中一个中等规模的数据集,也是 Transformer 论文中用到的一个数据集,这里将其作为示例,运行
`gen_data.sh`
脚本获取并生成。
参照论文,英德数据集我们使用 BPE 编码的数据,这能够更好的解决未登录词(out-of-vocabulary,OOV)的问题
[
4]。用到的 BPE 数据可以参照[这里
](
https://github.com/google/seq2seq/blob/master/docs/data.md
)
进行下载(如果希望在自定义数据中使用 BPE 编码,可以参照
[
这里
](
https://github.com/rsennrich/subword-nmt
)
进行预处理),下载后解压,其中
`train.tok.clean.bpe.32000.en`
和
`train.tok.clean.bpe.32000.de`
为使用 BPE 的训练数据(平行语料,分别对应了英语和德语,经过了 tokenize 和 BPE 的处理),
`newstest2016.tok.bpe.32000.en`
和
`newstest2016.tok.bpe.32000.de`
等为测试数据(
`newstest2016.tok.en`
和
`newstest2016.tok.de`
等则为对应的未使用 BPE 的测试数据),
`vocab.bpe.32000`
为相应的词典文件(源语言和目标语言共享该词典文件)。
由于本示例中的数据读取脚本
`reader.py`
默认使用的样本数据的格式为
`\t`
分隔的的源语言和目标语言句子对(默认句子中的词之间使用空格分隔),因此需要将源语言到目标语言的平行语料库文件合并为一个文件,可以执行以下命令进行合并:
```
sh
...
...
@@ -74,11 +71,7 @@ paste -d '\t' train.tok.clean.bpe.32000.en train.tok.clean.bpe.32000.de > train.
sed
-i
'1i\<s>\n<e>\n<unk>'
vocab.bpe.32000
```
#### WMT 英法翻译数据
[
WMT'14 EN-FR 数据集
](
http://www.statmt.org/wmt14/translation-task.html
)
是一个较大规模的数据集。参照论文,英法数据我们使用 wordpiece 表示的数据,wordpiece 和 BPE 类似同为采用 sub-word units 来解决 OOV 问题的方法
[
5]。我们提供了已完成预处理的 wordpiece 数据的下载,可以从[这里
](
http://transformer-data.bj.bcebos.com/wmt14_enfr.tar
)
下载,其中
`train.wordpiece.en-fr`
为使用 wordpiece 的训练数据,
`newstest2014.wordpiece.en-fr`
为测试数据(
`newstest2014.tok.en`
和
`newstest2014.tok.fr`
为对应的未经 wordpiece 处理过的测试数据,使用
[
脚本
](
https://github.com/moses-smt/mosesdecoder/blob/master/scripts/tokenizer/tokenizer.perl
)
进行了 tokenize 的处理),
`vocab.wordpiece.en-fr`
为相应的词典文件(源语言和目标语言共享该词典文件)。
提供的英法翻译数据无需进行额外的处理,可以直接使用;需要注意的是,这些用 wordpiece 表示的数据中句子内的 token 之间使用
`\x01`
而非空格进行分隔(因部分 token 内包含空格),这需要在训练时进行指定。
对于其他自定义数据,转换为类似的数据格式即可,如需
### 模型训练
...
...
fluid/neural_machine_translation/transformer/gen_data.sh
0 → 100644
浏览文件 @
7b6c3879
#! /usr/bin/env bash
set
-e
OUTPUT_DIR
=
$PWD
/gen_data
###############################################################################
# change these variables for other WMT data
###############################################################################
OUTPUT_DIR_DATA
=
"
${
OUTPUT_DIR
}
/wmt16_ende_data"
OUTPUT_DIR_BPE_DATA
=
"
${
OUTPUT_DIR
}
/wmt16_ende_data_bpe"
LANG1
=
"en"
LANG2
=
"de"
# each of TRAIN_DATA: ata_url data_tgz data_file
TRAIN_DATA
=(
'http://www.statmt.org/europarl/v7/de-en.tgz'
'europarl-v7-de-en.tgz'
'europarl-v7.de-en'
'http://www.statmt.org/wmt13/training-parallel-commoncrawl.tgz'
'common-crawl.tgz'
'commoncrawl.de-en'
'http://data.statmt.org/wmt16/translation-task/training-parallel-nc-v11.tgz'
'nc-v11.tgz'
'training-parallel-nc-v11/news-commentary-v11.de-en'
)
# each of DEV_TEST_DATA: data_url data_tgz data_file_lang1 data_file_lang2
DEV_TEST_DATA
=(
'http://data.statmt.org/wmt16/translation-task/dev.tgz'
'dev.tgz'
'.*/newstest201[45]-deen-ref.en.sgm'
'.*/newstest201[45]-deen-src.de.sgm'
'http://data.statmt.org/wmt16/translation-task/test.tgz'
'test.tgz'
'.*/newstest2016-deen-ref.en.sgm'
'.*/newstest2016-deen-src.de.sgm'
)
###############################################################################
mkdir
-p
$OUTPUT_DIR_DATA
$OUTPUT_DIR_BPE_DATA
# Extract training data
for
((
i
=
0
;
i<
${#
TRAIN_DATA
[@]
}
;
i+
=
3
))
;
do
data
=
`
echo
${
TRAIN_DATA
[i+1]
}
|
cut
-d
"."
-f
1
`
data_url
=
${
TRAIN_DATA
[i]
}
data_tgz
=
${
TRAIN_DATA
[i+1]
}
data_file
=
${
TRAIN_DATA
[i+2]
}
if
[
!
-e
${
OUTPUT_DIR_DATA
}
/
${
data_tgz
}
]
;
then
echo
"Download "
${
data
}
wget
-O
${
OUTPUT_DIR_DATA
}
/
${
data_tgz
}
${
data_url
}
fi
if
[
!
-d
${
OUTPUT_DIR_DATA
}
/
${
data
}
]
;
then
echo
"Extract "
${
data
}
mkdir
-p
${
OUTPUT_DIR_DATA
}
/
${
data
}
tar
-xvzf
${
OUTPUT_DIR_DATA
}
/
${
data_tgz
}
-C
${
OUTPUT_DIR_DATA
}
/
${
data
}
fi
# concatenate all training data
for
l
in
${
LANG1
}
${
LANG2
}
;
do
for
j
in
${
data_file
}
;
do
if
[
$i
-eq
0
]
;
then
cat
${
OUTPUT_DIR_DATA
}
/
${
data
}
/
$j
.
$l
>
${
OUTPUT_DIR_DATA
}
/train.
$l
else
cat
${
OUTPUT_DIR_DATA
}
/
${
data
}
/
$j
.
$l
>>
${
OUTPUT_DIR_DATA
}
/train.
$l
fi
done
done
done
# Clone mosesdecoder
if
[
!
-d
${
OUTPUT_DIR
}
/mosesdecoder
]
;
then
echo
"Cloning moses for data processing"
git clone https://github.com/moses-smt/mosesdecoder.git
${
OUTPUT_DIR
}
/mosesdecoder
fi
# Extract develop and test data
dev_test_data
=
""
for
((
i
=
0
;
i<
${#
DEV_TEST_DATA
[@]
}
;
i+
=
4
))
;
do
data
=
`
echo
${
DEV_TEST_DATA
[i+1]
}
|
cut
-d
"."
-f
1
`
data_url
=
${
DEV_TEST_DATA
[i]
}
data_tgz
=
${
DEV_TEST_DATA
[i+1]
}
data_lang1
=
${
DEV_TEST_DATA
[i+2]
}
data_lang2
=
${
DEV_TEST_DATA
[i+3]
}
if
[
!
-e
${
OUTPUT_DIR_DATA
}
/
${
data_tgz
}
]
;
then
echo
"Download "
${
data
}
wget
-O
${
OUTPUT_DIR_DATA
}
/
${
data_tgz
}
${
data_url
}
fi
if
[
!
-d
${
OUTPUT_DIR_DATA
}
/
${
data
}
]
;
then
echo
"Extract "
${
data
}
mkdir
-p
${
OUTPUT_DIR_DATA
}
/
${
data
}
tar
-xvzf
${
OUTPUT_DIR_DATA
}
/
${
data_tgz
}
-C
${
OUTPUT_DIR_DATA
}
/
${
data
}
fi
for
data_lang
in
$data_lang1
$data_lang2
;
do
for
j
in
`
find
${
OUTPUT_DIR_DATA
}
/
${
data
}
-regex
${
data_lang
}
`
;
do
data_dir
=
`
dirname
$j
`
data_file
=
`
echo
$j
|
awk
-F
'/'
'{print $NF}'
`
data_out
=
`
echo
${
data_file
}
|
cut
-d
'-'
-f
1
`
# newstest2016
l
=
`
echo
${
data_file
}
|
cut
-d
'.'
-f
2
`
# en
dev_test_data
=
"
${
dev_test_data
}
\|
${
data_out
}
"
# to make regexp
if
[
!
-e
${
data_dir
}
/
${
data_out
}
.
$l
]
;
then
${
OUTPUT_DIR
}
/mosesdecoder/scripts/ems/support/input-from-sgm.perl
\
<
$j
>
${
data_dir
}
/
${
data_out
}
.
$l
cp
${
data_dir
}
/
${
data_out
}
.
$l
${
OUTPUT_DIR_DATA
}
fi
done
done
done
# Tokenize data
for
l
in
${
LANG1
}
${
LANG2
}
;
do
for
f
in
`
ls
${
OUTPUT_DIR_DATA
}
/
*
.
$l
|
grep
"
\(
train
${
dev_test_data
}
\)\.
$l
$"
`
;
do
f_base
=
${
f
%.*
}
# dir/train dir/newstest2016
f_out
=
$f_base
.tok.
$l
if
[
!
-e
$f_out
]
;
then
echo
"Tokenize "
$f
${
OUTPUT_DIR
}
/mosesdecoder/scripts/tokenizer/tokenizer.perl
-q
-l
$l
-threads
8 <
$f
>
$f_out
fi
done
done
# Clean data
for
f
in
${
OUTPUT_DIR_DATA
}
/train.
${
LANG1
}
${
OUTPUT_DIR_DATA
}
/train.tok.
${
LANG1
}
;
do
f_base
=
${
f
%.*
}
# dir/train dir/train.tok
f_out
=
${
f_base
}
.clean
if
[
!
-e
$f_out
.
${
LANG1
}
]
&&
[
!
-e
$f_out
.
${
LANG2
}
]
;
then
echo
"Clean "
${
f_base
}
${
OUTPUT_DIR
}
/mosesdecoder/scripts/training/clean-corpus-n.perl
$f_base
${
LANG1
}
${
LANG2
}
${
f_out
}
1 80
fi
done
# Clone subword-nmt and generate BPE data
if
[
!
-d
${
OUTPUT_DIR
}
/subword-nmt
]
;
then
git clone https://github.com/rsennrich/subword-nmt.git
${
OUTPUT_DIR
}
/subword-nmt
fi
# Generate BPE data and vocabulary
for
num_operations
in
32000
;
do
if
[
!
-e
${
OUTPUT_DIR_BPE_DATA
}
/bpe.
${
num_operations
}
]
;
then
echo
"Learn BPE with
${
num_operations
}
merge operations"
cat
${
OUTPUT_DIR_DATA
}
/train.tok.clean.
${
LANG1
}
${
OUTPUT_DIR_DATA
}
/train.tok.clean.
${
LANG2
}
|
\
${
OUTPUT_DIR
}
/subword-nmt/learn_bpe.py
-s
$num_operations
>
${
OUTPUT_DIR_BPE_DATA
}
/bpe.
${
num_operations
}
fi
for
l
in
${
LANG1
}
${
LANG2
}
;
do
for
f
in
`
ls
${
OUTPUT_DIR_DATA
}
/
*
.
$l
|
grep
"
\(
train
${
dev_test_data
}
\)\.
tok
\(\.
clean
\)\?\.
$l
$"
`
;
do
f_base
=
${
f
%.*
}
# dir/train.tok dir/train.tok.clean dir/newstest2016.tok
f_base
=
${
f_base
##*/
}
# train.tok train.tok.clean newstest2016.tok
f_out
=
${
OUTPUT_DIR_BPE_DATA
}
/
${
f_base
}
.bpe.
${
num_operations
}
.
$l
if
[
!
-e
$f_out
]
;
then
echo
"Apply BPE to "
$f
${
OUTPUT_DIR
}
/subword-nmt/apply_bpe.py
-c
${
OUTPUT_DIR_BPE_DATA
}
/bpe.
${
num_operations
}
<
$f
>
$f_out
fi
done
done
if
[
!
-e
${
OUTPUT_DIR_BPE_DATA
}
/vocab.bpe.
${
num_operations
}
]
;
then
echo
"Create vocabulary for BPE data"
cat
${
OUTPUT_DIR_BPE_DATA
}
/train.tok.clean.bpe.
${
num_operations
}
.
${
LANG1
}
${
OUTPUT_DIR_BPE_DATA
}
/train.tok.clean.bpe.
${
num_operations
}
.
${
LANG2
}
|
\
${
OUTPUT_DIR
}
/subword-nmt/get_vocab.py |
cut
-f1
-d
' '
>
${
OUTPUT_DIR_BPE_DATA
}
/vocab.bpe.
${
num_operations
}
fi
done
# Adapt to the reader
for
f
in
${
OUTPUT_DIR_BPE_DATA
}
/
*
.bpe.
${
num_operations
}
.
${
LANG1
}
;
do
f_base
=
${
f
%.*
}
# dir/train.tok.clean.bpe.32000 dir/newstest2016.tok.bpe.32000
f_out
=
${
f_base
}
.
${
LANG1
}
-
${
LANG2
}
if
[
!
-e
$f_out
]
;
then
paste
-d
'\t'
$f_base
.
${
LANG1
}
$f_base
.
${
LANG2
}
>
$f_out
fi
done
if
[
!
-e
${
OUTPUT_DIR_BPE_DATA
}
/vocab_all.bpe.
${
num_operations
}
]
;
then
sed
'1i\<s>\n<e>\n<unk>'
${
OUTPUT_DIR_BPE_DATA
}
/vocab.bpe.
${
num_operations
}
>
${
OUTPUT_DIR_BPE_DATA
}
/vocab_all.bpe.
${
num_operations
}
fi
echo
"All done."
fluid/neural_machine_translation/transformer/model.py
浏览文件 @
7b6c3879
...
...
@@ -458,7 +458,7 @@ def transformer(src_vocab_size,
use_py_reader
=
False
,
is_test
=
False
):
if
weight_sharing
:
assert
src_vocab_size
==
src
_vocab_size
,
(
assert
src_vocab_size
==
trg
_vocab_size
,
(
"Vocabularies in source and target should be same for weight sharing."
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录