如何在oepnNMT中进行Transformer实验
NMT的评价指标
BLEU
BLEU(bilingual evaluation understudy)由(Papineni et al.,2002)提出,是一个用于评估机器翻译质量的指标。BLEU的主要思想就是,机器翻译(候选翻译,candidate,简称c)和人工翻译(参考翻译,reference,简称r)的结果越相近,则机器翻译的效果越好。
BLEU的计算中,首先通过modified N-gram模型惩罚比参考翻译更长的候选翻译,然后使用brevity penalty(BP)用于惩罚与参考翻译长度不匹配的候选翻译(如长度过短的翻译)。定义best match length(最佳匹配长度),best match length表示候选翻译和参考翻译的长度相同,只要候选翻译和任何一个参考翻译的长度相等,那么就满足best match length,这种情况下惩罚因子为$BP=1$,相当于没有惩罚。$BP$的取值如下:
$$
BP=\left{
\begin{array}{rcl}
1 & if & {c>r}\
e^{(1-r/c)} & if & {c\leq r}\
\end{array} \right.
$$
BLEU的计算公式如下:
$$
BLEU=BP \cdot exp(\Sigma_{n=1}^Nw_nlogp_n)
$$
通常取$N=4$,$w_n=1/N$。
BLEU能够方便、快速地判断句子的翻译质量,但是BLEU也存在一些缺点,如没有考虑到语法的准确性,而且未考虑同义词或者相似表达的情况。
BLEU其实是一组参数化方法,包括以下的参数:
- 使用的参考翻译数量
- 长度惩罚的计算
- n-gram长度的最大值(通常为4)
- 应用于0-count n-grams的平滑
对于使用同一个数据集实验的不同文章,对BLEU参数的选取可能会影响BLEU的分数,为了标准化BLEU,明确其所使用的参数,使得BLEU分数能够直接进行比较,(Post,2018)提出了一种标准化计算BLEU的工具sacreBLEU。
Perplexity
对于一个好的语言模型来说,更真实且更容易观测到的句子应该要比语法错误或者较少出现的句子计算出的概率更高。通常使用未出现的测试数据集来衡量模型的表现,但是这样的外部评估需要对模型进行多次测试,代价较大。Perplexity(困惑度)是一种内在评估,它测试语言模型本身,而不是特定的任务或者程序。困惑度是一种极端外在评估下的较差的近似。困惑度仅适用于实验的初期,之后实验还需要运用外部评估来最终确定模型的性能。
长度为$N$的句子$S$的困惑度的计算公式为:
$$
PP(S)=P(w_1w_2…w_N)^{-\frac{1}{N}}\=\sqrt[N]{p(w_1w_2…w_N)}\=\sqrt[N]{\prod_{i=1}^N\frac{1}{p(w_i|w_1w_2…w_i-1)}}
$$
其中$p(w_i)$是第$i$个词的概率,困惑度越小,说明句子的概率越大,则语言模型越好。
另一种想法是可以将Perplexity看成是weighted average branching factor(加权的平均分支系数)。分支系数指的就是下一个单词可能的选择。可以直观地理解,模型生成下一个词时,可能的选择越少,那么模型就越准确。
实验
数据集
获取数据集
1 | echo "Downloading and extracting Commoncrawl data (919 MB) for training..." |
使用WMT 14 dataset中的en-de数据集进行实验,原始数据的信息为:
为了方便测试模型性能,使用OpenNMT提供的toy-en-de数据集,该数据集中训练集有10000个句子,验证集有3000个句子,测试集有2737个句子。训练、验证、测试集中,每个英文句子都有对应的人工翻译的德语句子。
源码来源
https://opennmt.net/OpenNMT-py/quickstart.html#step-3-translate
Transformer的代码来源于OpenNMT,OpenNMT-py中Transformer的部分和上周看的代码一致(同一个团队完成的),除此之外,OpenNMT还有包括Seq2seq、Attention等机制完成NMT的源码。但是OpenNMT无法直接计算BLEU, 计算BLEU的方法有两种,分别是:
1 | import sacrebleu |
模型最后输出的翻译结果如果是词的列表而非句子的话,需要进行detokenize,将词语列表转换为句子,可以使用sacremoses工具进行detokenize。
https://github.com/moses-smt/mosesdecoder/blob/master/scripts/generic/multi-bleu.perl
使用方法:
下载get_ende_bleu.sh文件,
1 | perl multi-bleu.perl ref.txt [ref2.txt ...]< pre.txt |
模型参数
模型参数和base Transformer相同,模型结构附在最后(太长了)。
实验结果
对于该数据集的结果,在PaperwithCode中对目前的方法进行了排序和追踪。Transformer在完整的数据集上的Baseline是27.3,但是跑出来的几个结果BLEU均远低于27.3。
我为了减少训练时间将train step设置成了50000(baseline中的train step是200000),但当train step为50000时,模型训练的时间约为8小时左右(用服务器的两张卡),不过该train step下模型已经得到较高的BLEU值,应该已经收敛。我用训练好的模型来预测测试集和验证集的结果相差不大,BLEU大概不到10,预测训练集的BLEU为99.5左右,可能是模型出现过拟合现象。
github相关的项目issue中也有类似的问题,一些解决办法是减小learning rate,还有一些方法是修改其他参数。
TODO: 后续打算首先是先按照github issue中的修改方法调参,还有可能是语料库建立时的问题,下周将一并排查。
参考文献
- Papineni, Kishore, et al. “Bleu: a method for automatic evaluation of machine translation.” Proceedings of the 40th annual meeting of the Association for Computational Linguistics. 2002.
- Post, Matt. “A call for clarity in reporting BLEU scores.” arXiv preprint arXiv:1804.08771 (2018).
- Speech and Language Processing Chapter3. Daniel Jurafsky & James H. Martin.
- Yasmin Moslem.Computing BLEU Score for Machine Translation
原文作者: Ruoting Wu
原文链接: https://codingclaire.github.io/2021/07/21/2021-07-21-opennmt-transformer/
许可协议: 知识共享署名-非商业性使用 4.0 国际许可协议