非自己回帰型機械翻訳 の学習データ（ Mask-Predict モデルと、 EncoderOuts を Upsampling して Decoder の target 入力にして CTCLoss を計算するモデル )

## はじめに

このレポートでは、日本語を英語に翻訳する機械翻訳の学習データについて報告する。注目すべき点は、自己回帰型プログラムより非自己回帰型プログラムの方が、WER が小さく、BLEU が大きい結果がでたことである。

2024年7月28日 4. を追記。

1.Transformer を用いた自己回帰型での学習
　プログラムファイル名　Autoregressive.ipynb
　WER 29.1 と BLEU 47.9 
2.Mask-Predict の非自己回帰型での学習　
　プログラムファイル名　Mask_Predict.ipynb
3.CTCLoss と Mask-Predict での非自己回帰型学習
　プログラムファイル名　CTC_Mask_Predict.ipynb
4.Encoder の出力を Upsampling して Decoder のtaraget 入力に。loss は CTC。
　非自己回帰型
　プログラムファイル名　EncoderOuts_Upsampling.ipynb
　WER 24.1、BLEU 55.1
5.埋め込みソース言語を 2倍のシーケンス長にアップサンプリングして
　12層の TransformerEncoder に通し、CTCLoss で backward
　非自己回帰型
　プログラムファイル名 EncoderOnly.ipynb
　WER 24.5 BLEU 50.3
6.埋め込みソース言語を 2倍のシーケンス長にアップサンプリングして
　12層の RetNet に通し、CTCLoss で backward
　非自己回帰型
　プログラムファイル名 RetNet_MS.ipynb
　WER 32.0 BLEU 37.2
 
の6種類の学習データである。

## 学習データ

データは、日本語英語コーパス

https://www.kecl.ntt.co.jp/icl/lirg/jparacrawl/

のデータです。train 100万件、val 5000件、test 50件としました。token の単位は単語です。私の環境では、英語文に multi-byte 文字が入っていると、idx_to_word.json ファイルの分かち書きの英語が文字化けするので、multi-byte 文字の入った英文は学習に使いませんでした。idx_to_word.json（index と英語分かち書きの対応ファイル）、 idx_to_wakati.json（index と日本語分かち書きの対応ファイル）も作成しました。

## 自己回帰型での学習

学習は、train データ100万件、validation データ 5,000件で 20エポック行った。損失と WER の変化のグラフを掲載する。

![fig1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/9f624fa6-58b3-011a-4598-80549c11b6e2.png)

![fig2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/d5b4d43f-65a4-99bf-ba09-6d93f53cb562.png)

この学習では、途中で、WER と一部 BLEU の値を測定した。上記グラフの WER の値は、Transformer Decoder の target 入力に、target[:,1:] を入力したものであるが、下の表の WER と BLEU は、model への入力は source 言語のみで、Transformer Decoder を自己回帰的に使って得た数値である。
<table>
<caption> Autoregressive trainデータ
<thread>
<th>epoch<th>WER<th>BLEU
<tbody>
<tr><td style="text-align:right;"> 1<td>74.0<td>未記録
<tr><td style="text-align:right;"> 2<td>72.0<td>未記録
<tr><td style="text-align:right;"> 3<td>58.3<td>未記録
<tr><td style="text-align:right;"> 4<td>54.3<td>未記録
<tr><td style="text-align:right;"> 5<td>47.9<td>未記録
<tr><td style="text-align:right;"> 6<td>43.7<td>未記録
<tr><td style="text-align:right;"> 7<td>45.8<td>未記録
<tr><td style="text-align:right;"> 8<td>47.3<td>未記録
<tr><td style="text-align:right;"> 9<td>43.0<td>未記録
<tr><td style="text-align:right;">10<td>40.5<td>未記録
<tr><td style="text-align:right;">11<td colspan="2">未測定
<tr><td style="text-align:right;">12<td>36.7<td>未記録
<tr><td style="text-align:right;">13<td>35.7<td>41.4
<tr><td style="text-align:right;">14<td>34.5<td>42.1
<tr><td style="text-align:right;">15<td>33.8<td>41.7
<tr><td style="text-align:right;">16<td>32.2<td>45.1
<tr><td style="text-align:right;">17<td>30.7<td>47.4
<tr><td style="text-align:right;">18<td colspan="2">未測定
<tr><td style="text-align:right;">19<td>29.5<td>48.7
<tr><td style="text-align:right;">20<td>29.1<td>47.9
</table>

20エポックの時に WER 29.1 と BLEU 47.9 が得られている。

## Mask-Predict による学習。

Mask-Predict による学習を行った。学習は、train データ100万件、validation データ 5,000件で 20エポック行った。loss0、loss、WER と BLEU の変化のグラフを掲載する。loss0 は、マスクされた target 言語の損失であり、loss は、loss0 に target 文章の長さの予測の損失を加えた値である。

![fig3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/d5372f9b-755e-5d0c-a248-b5ede9b0d33e.png)

![fig4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/13ee7c4f-02e5-f378-992f-3d6e0e7b371c.png)

![fig5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/ed1c6842-652a-df01-5cf4-cf54aba3c16c.png)

![fig6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/303e9047-5702-d7b4-ce07-b61a9d6cd75c.png)


次に、各エポックにおけるWERとBLEU の値を計測したので、掲載する。この計測では、モデルへの入力は、source 言語のみであり、教師データの情報は使っていない。Transformer Decoder の target 入力は、&lt;pad&gt; 以外すべての sequence で  &lt;mask&gt; の埋め込み文章から始めて10回イタレーションした。推論に用いた関数などは、Fairseq の Mask-Predict

https://github.com/facebookresearch/Mask-Predict/tree/main

を参考にさせて頂いた。length_beam_size は 3 とした。これは、ターゲット言語の長さ予測の 3 種類について、イタレーションするということである。また、batch_size = 1, number_of_test_data = 50 である。

<table>
<caption>Mask-Preict trainデータ
<th>epoch<th>WER<th>BLEU
<tr><td style="text-align:right;"> 1<td>66.9<td>0.78
<tr><td style="text-align:right;"> 2<td>54.1<td>10.3
<tr><td style="text-align:right;"> 3<td>45.4<td>24.4
<tr><td style="text-align:right;"> 4<td>42.0<td>27.5
<tr><td style="text-align:right;"> 5<td>38.9<td>33.7
<tr><td style="text-align:right;"> 6<td>39.9<td>33.3
<tr><td style="text-align:right;"> 7<td>34.0<td>42.8
<tr><td style="text-align:right;"> 8<td colspan="2">未測定
<tr><td style="text-align:right;"> 9<td>34.3<td>39.8
<tr><td style="text-align:right;">10<td colspan="2">未測定
<tr><td style="text-align:right;">11<td>34.7<td>40.4
<tr><td style="text-align:right;">12<td>32.6<td>44.9
<tr><td style="text-align:right;">13<td>34.8<td>43.0
<tr><td style="text-align:right;">14<td>34.6<td>40.1
<tr><td style="text-align:right;">15<td>35.1<td>37.8
<tr><td style="text-align:right;">16<td>35.8<td>37.4
<tr><td style="text-align:right;">17<td>34.4<td>42.5
<tr><td style="text-align:right;">18<td>33.5<td>39.8
<tr><td style="text-align:right;">19<td>35.1<td>42.1
<tr><td style="text-align:right;">20<td>34.4<td>40.2
</table>

エポック12で WER 32.6, BLEU 44.9 を得た。

## CTC loss を用いた Mask-Predict

Mask-Predict の精度のネックは、target 言語の sequence 長の予測にあるのではないかと考えた。CTC Loss は、長さへの依存が少ないという印象があったため、CTCLoss を使うことにした。CTCLoss を使うためには、確実に source 言語の sequence 長より target 言語の sequence 長が長くなければならないため、target 言語を 2倍に upsampling した。

学習途中の train データ、validation データについての loss0, loss, WER, BLEU の変化のグラフを掲載する。loss0 が、mask を考えずに計算したtarget 文章の CTCLoss である。これに target 言語の長さの予測の損失を加えた値が loss である。

![fig7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/faac42a2-1ed8-29c3-96b2-ea09858318b5.png)

![fig8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/86c496ac-1b50-8737-dfa0-f500e621725c.png)

![fig9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/e51c6929-b889-822a-0963-9245936697f2.png)

![fig10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/666f7ab2-bbdd-d3cb-7624-3da03945e27d.png)


Mask-Predict と同様に、各エポックで、推論結果の評価をおこなった。CTCLoss を用いた Mask-Predict の推論は、二つの関数で比較した。一つは、推論の mask の数を減らすイタレーションにおいて、Transformer Decoder の出力を CTC を考慮した decode をしたのちに、mask のかけなおしを行う関数が inference である。もう一つは、推論の mask の数を減らすイタレーションにおいて、mask の位置をupsampling に合わせておいて、ターゲット言語は、decode　せずに mask のかけなおしを行い、Transformer Decoder　の target 言語の upasmpling を行わない関数が inference1 である。

length_beam_size は 3 とした。これは、ターゲット言語の予測の 3 種類について、イタレーションするということである。また、batch_size = 1, number_of_test_data = 50 である。

当初、予測された target 言語の長さ依存を弱くするために CTCLoss を導入したが、length_beam_size = 2,4,5 より 3 の値が良かった。

<table>
<caption>CTC Mask-Preict train inference 関数データ
<th>　　epoch<th>　　　　WER<th>　　　BLEU
<tr><td style="text-align:right;"> 1<td>76.0<td>0.00
<tr><td style="text-align:right;"> 2<td>59.8<td>16.5
<tr><td style="text-align:right;"> 3<td>52.8<td>24.3
<tr><td style="text-align:right;"> 4<td>57.3<td>22.2
<tr><td style="text-align:right;"> 5<td>48.2<td>25.2
<tr><td style="text-align:right;"> 6<td>51.0<td>25.0
<tr><td style="text-align:right;"> 7<td>45.2<td>29.4
<tr><td style="text-align:right;"> 8<td>44.2<td>28.4
<tr><td style="text-align:right;"> 9<td>46.1<td>28.3
<tr><td style="text-align:right;">10<td>43.8<td>30.7
<tr><td style="text-align:right;">11<td>42.0<td>37.5
<tr><td style="text-align:right;">12<td>41.8<td>35.3
<tr><td style="text-align:right;">13<td>40.9<td>37.4
<tr><td style="text-align:right;">14<td>41.8<td>36.1
<tr><td style="text-align:right;">15<td>39.7<td>36.5
<tr><td style="text-align:right;">16<td>40.1<td>36.8
<tr><td style="text-align:right;">17<td>40.5<td>34.1
<tr><td style="text-align:right;">18<td>38.0<td>38.4
<tr><td style="text-align:right;">19<td>39.8<td>35.5
<tr><td style="text-align:right;">20<td>34.1<td>42.6
</table>
</div>

<div align="center">
<table>
<caption>CTC Mask-Preict train inference1関数データ
<th>　　epoch<th>　　　　WER<th>　　　BLEU
<tr><td style="text-align:right;"> 1<td>73.2<td>0.00
<tr><td style="text-align:right;"> 2<td>56.0<td>13.3
<tr><td style="text-align:right;"> 3<td>49.4<td>20.8
<tr><td style="text-align:right;"> 4<td>41.5<td>27.1
<tr><td style="text-align:right;"> 5<td>45.1<td>24.7
<tr><td style="text-align:right;"> 6<td>38.4<td>33.3
<tr><td style="text-align:right;"> 7<td>34.0<td>34.9
<tr><td style="text-align:right;"> 8<td>38.8<td>35.2
<tr><td style="text-align:right;"> 9<td>39.4<td>30.9
<tr><td style="text-align:right;">10<td>39.4<td>34.9
<tr><td style="text-align:right;">11<td>37.0<td>37.5
<tr><td style="text-align:right;">12<td>38.0<td>37.0
<tr><td style="text-align:right;">13<td>40.2<td>29.2
<tr><td style="text-align:right;">14<td>37.9<td>34.9
<tr><td style="text-align:right;">15<td>38.9<td>36.6
<tr><td style="text-align:right;">16<td>38.9<td>34.4
<tr><td style="text-align:right;">17<td>40.5<td>28.5
<tr><td style="text-align:right;">18<td>37.9<td>33.1
<tr><td style="text-align:right;">19<td>33.2<td>45.3
<tr><td style="text-align:right;">20<td>37.2<td>34.7
</table>
</div>

inferece1 のエポック19 で WER 33.2 BLEU 45.3 を得た。

## TransformerEncoder の出力を Upsampling して、TransformerDecoder の target 入力にする非自己回帰型プログラム Loss は CTC。

CTC loss を用いた Mask-Predict では、ターゲット文章（教師データ）をマスクしたものを sequence 方向に 2倍に upsampling して TransformerDecoder の target 入力にした。一方、ここで評価数値を掲載する方法では、TransformerEncoder の出力を sequence 方向に 2倍に upsampling して、TransformerDecoder の target 入力とする。損失は CTC Loss である。

学習は20エポックまで行った。

train データと validation データについての、loss, WER, BLEU のグラフを掲載する。このプログラムでは、学習と推論のニューラルネットワークは predictions = model( source_embed_sentences ) とでき、target_embed_sentences に依存しない。すなわち、学習と推論は同じアルゴリズムの model 関数を使うことができる。推論は非自己回帰型となる。

![fig11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/e32b4ed2-7804-044b-4404-1489b2afe6e3.png)

![fig12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/1b84f1ed-5394-15ee-f8e6-698a6f27e94c.png)


![fig13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/88132d1d-d630-44c6-b2e7-8139e7b68e8f.png)

次にテストデータについての推論評価の表を掲載する。テストデータ数は 50 で batch_size = 1 である。

<table>
<caption>EncoderOuts Upsampling のテストデータについての推論評価値
<th>　　　　　epoch<th>　　　　　　　WER<th>　　　　　　BLEU
<tr><td style="text-align:right;"> 1<td>41.0<td>25.2
<tr><td style="text-align:right;"> 2<td>34.4<td>33.3
<tr><td style="text-align:right;"> 3<td>32.7<td>34.6
<tr><td style="text-align:right;"> 4<td>34.0<td>37.2
<tr><td style="text-align:right;"> 5<td>34.0<td>34.1
<tr><td style="text-align:right;"> 6<td>31.4<td>40.1
<tr><td style="text-align:right;"> 7<td>32.5<td>37.5
<tr><td style="text-align:right;"> 8<td>29.8<td>42.4
<tr><td style="text-align:right;"> 9<td>29.6<td>44.8
<tr><td style="text-align:right;">10<td>26.9<td>47.8
<tr><td style="text-align:right;">11<td>30.0<td>45.6
<tr><td style="text-align:right;">12<td>26.7<td>50.3
<tr><td style="text-align:right;">13<td colspan="2">未測定
<tr><td style="text-align:right;">14<td>25.6<td>50.8
<tr><td style="text-align:right;">15<td>25.3<td>50.8
<tr><td style="text-align:right;">16<td>25.4<td>51.5
<tr><td style="text-align:right;">17<td>24.1<td>55.1
<tr><td style="text-align:right;">18<td>23.2<td>54.1
<tr><td style="text-align:right;">19<td>26.0<td>50.2
<tr><td style="text-align:right;">20<td>24.0<td>52.5
</table>
</div>

エポック17 で、WER 24.1、BLEU 55.1 を得た。一般に、非自己回帰型の精度は自己回帰型の精度より劣るが、今回の実験では、自己回帰型の精度が WER 29.1、 BLEU 47.9 であることを考えると注目に値する。


## 参考のために学習に使ったプログラムを github にアップしておきます。

https://github.com/toshiouchi/Machine_Translation

ここまでは、2024年6月17日までに書きました。

次に、Upsampling Twice + Transformer Encoder 12層　+ CTCLoss の記事は、2025年4月に書いています。

## 埋め込んだソース言語を2倍のシーケンス長にアップサンプリングし、12層のTransformerEncoder に通し、CTCLoss で loss.backward() した場合のデータ。

![Enconly_Loss.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/8778b1ce-6960-4186-8e54-9b8000e01a0a.png)

![Enconly_WER.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/43066d29-3acd-4153-b3a8-042b94b3d330.png)

![Enconly_BLEU.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/6b14b7c5-93a1-4884-9431-e545578eed39.png)

<table>
<caption>Upsampling+TransformerEncoder+CTCLoss の推論評価値
<th>　　　　　epoch<th>　　　　　　　WER<th>　　　　　　BLEU
<tr><td style="text-align:right;"> 1<td>40.9<td>25.5
<tr><td style="text-align:right;"> 2<td>38.0<td>28.5
<tr><td style="text-align:right;"> 3<td>35.1<td>37.0
<tr><td style="text-align:right;"> 4<td>31.1<td>39.7
<tr><td style="text-align:right;"> 5<td>31.8<td>40.3
<tr><td style="text-align:right;"> 6<td>30.4<td>42.5
<tr><td style="text-align:right;"> 7<td>31.7<td>43.4
<tr><td style="text-align:right;"> 8<td>30.9<td>41.9
<tr><td style="text-align:right;"> 9<td>27.1<td>46.1
<tr><td style="text-align:right;">10<td>27.6<td>45.8
<tr><td style="text-align:right;">11<td>23.8<td>49.7
<tr><td style="text-align:right;">12<td>24.5<td>50.3
<tr><td style="text-align:right;">13<td>25.1<td>49.6
<tr><td style="text-align:right;">14<td>25.0<td>49.6
<tr><td style="text-align:right;">15<td>25.5<td>50.5
<tr><td style="text-align:right;">16<td>24.9<td>50.0
<tr><td style="text-align:right;">17〜<td colspan="2">Early Stopping
</table>
</div>

かなり良いデータと考えられる。

## 埋め込んだソース言語を2倍のシーケンス長にアップサンプリングし、12層の RetNet に通し、CTCLoss で loss.backward() した場合のデータ。

RetNet には、

https://github.com/microsoft/torchscale

の　RetNetDecorder を用いた。

![RetNet_loss.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/97e43ed9-69b9-41b0-a73c-c792b7046601.png)

![RetNet_WER.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/21176d96-6841-4d52-b264-07154c2dac0b.png)

![RetNet_BLEU.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/980789db-1bee-4f64-bae4-90c22525b409.png)

<table>
<caption>Upsampling+RetNet+CTCLoss の推論評価値
<th>　　　　　epoch<th>　　　　　　　WER<th>　　　　　　BLEU
<tr><td style="text-align:right;"> 1<td>45.4<td>19.2
<tr><td style="text-align:right;"> 2<td>41.1<td>23.8
<tr><td style="text-align:right;"> 3<td>40.9<td>24.9
<tr><td style="text-align:right;"> 4<td>38.8<td>27.6
<tr><td style="text-align:right;"> 5<td>37.6<td>34.1
<tr><td style="text-align:right;"> 6<td>36.2<td>32.7
<tr><td style="text-align:right;"> 7<td>37.0<td>32.7
<tr><td style="text-align:right;"> 8<td>36.5<td>31.2
<tr><td style="text-align:right;"> 9<td>35.7<td>33.7
<tr><td style="text-align:right;">10<td>35.4<td>35.2
<tr><td style="text-align:right;">11<td>35.1<td>36.8
<tr><td style="text-align:right;">12<td>32.0<td>40.7
<tr><td style="text-align:right;">13<td>33.9<td>37.2
<tr><td style="text-align:right;">14〜<td colspan="2">Early Stopping
</table>
</div>