tensorflow2.0のNeural machine translation with attentionで日英翻訳してみる

もともとは機械学習を使ったチャットボットを作りたかったのですが、オンラインの情報はtensorflowのバージョンが古く、pythonやtensorflowのバージョンを下げないと動かせないことが多く難航しました。これらのサンプルは機械翻訳をベースにしているので、まずは、tensorflow2.0の機械翻訳を動かせるようにしてみた。

tensorflowのチュートリアルにある[Neural machine translation with attention](https://www.tensorflow.org/tutorials/text/nmt_with_attention)は機械翻訳のサンプルになっているが、これ自体はスペイン語ー英語翻訳なので、日本語ー英語翻訳できるようにしてました。

#Google Colabで実行
Google Colabで動かせるサンプルがあるのでこれを利用します。

「Run in Google Colab」からGoogle Colabでプロジェクトを開いたのち、「ドライブにコピー」をクリックして保存。

#MeCabの用意
日本語を使うには分かち書きが必要になるので、MeCabを入れてます。

colabのレポジトリが古くてエラーが出ることがあるので、レポジトリを事前に更新。

    !apt update

MeCabを「[ColaboratoryでMeCabを使えようにする。](https://qiita.com/pytry3g/items/897ae738b8fbd3ae7893)」に従ってインストール。

    !apt install aptitude
    !aptitude install mecab libmecab-dev mecab-ipadic-utf8 git make curl xz-utils file -y
    !pip install mecab-python3==0.7

さらにコードセルを追加して、

    import MeCab
を書いて実行


#日本語データをダウンロードするように変更
一番下の、「Next Step」の中のDownload a different datasetへ行くと各種言語のデータがあるので、ここからJapanese - Englishをダウンロードしておく。なぜかColabから直接のダウンロードができないようなので、いったんどっかのページにおいておく。

「# Download the file」から始まるセルを書き換え
 - spa-eng.zipをjpn-eng.zipに変更
 - URLをどっか置いたところのURLに変更
 - 最後の行の/spa-eng/spa.txtを/jpn.txtに変更

各所に、スペイン語を示すspという変数があるがとりあえずそのままにしておく。

#読み込んだ日本語をMeCabで分割する
「# Converts the unicode file to ascii」から始まるセルに対して、いかの二つの修正。

##英数字以外を除去しているのをやめる
def preprocess_sentence(w):の次の行を以下のように変更：

    w = w.lower().strip()

17行目（# replaceing everything..,の次の行）をコメントアウト

##入力文字列をMeCabで分かち書きする。
最後の2行を書き換え。

    tagger = MeCab.Tagger("-Owakati")
    w = '<start> ' + tagger.parse(w) + ' <end>'
    return w

#データの読み込み処理の修正
日本語データには、後ろにライセンス情報が貼っているので、これも読み込むようにしないとエラーになるので修正
「en, sp = create_dataset(path_to_file, None)」から始まるセルの一行目

    en, sp = create_dataset(path_to_file, None)
を

    en, sp, license = create_dataset(path_to_file, None)
に変更

「def load_dataset(path, num_examples=None):」から始まる行も同様に修正

    targ_lang, inp_lang = create_dataset(path, num_examples)
を

    targ_lang, inp_lang, l = create_dataset(path, num_examples)
などと変更。

これで、基本的な準備はおしまいです。
ひとつづつセルを実行してもよいのですが、メニューの「ランタイム」から「すべてのセルを実行」してみましょう。学習部分に20分以上かかるので、合計30分くらいは放置になります。
（なお、Google ColabはWindowを閉じると90分でセッションが切れるので放置しすぎると結果が見れないので注意）。

あとは、Restore the latest checkpoint and testの中にあるコードセルのtranslate()関数の中身を日本語に書き換えてみます。サンプルデータに存在しない単語を使うとエラーになるので注意。
例1）

    translate(u'私は医者になりたい。')
    --> i want to become a doctor . 
例2）

    translate(u'明日は雨が降るかもしれない。')
    --> it may rain tomorrow . 
例3）

    translate(u'どこから来ましたか？')
    --> where did you get ? 

最初の二つはうまく翻訳できましたが、3つ目は？？？

例4）うまくいかない例

    translate(u'私の名前は山田です。')
山田という単語が元の事例に含まれていないので、エラーになります。

Google Colabのおかげで簡単に試すことができました。


#追記１：学習結果の保存
学習結果はtraining_checkpointsに保存されるので、このフォルダのバックアップを取っておけば、セッションが切れた後も学習結果を利用できます。左メニューのファイルから「ドライブをマウント」を選ぶと、以下のコードセルが現れるので実行すると、APIキーの入力が求められるので取得して、入力します。

    from google.colab import drive
    drive.mount('/content/drive')

その後、cpコマンドでバックアップを取ります。

    !mkdir /content/drive/My\ Drive/nmt_ja
    !cp -a training_checkpoints /content/drive/My\ Drive/nmt_ja/

再利用する際には、バックアップを戻して、「Restore the latest checkpoint and test」からcheckpointデータを読み直すことで翻訳機能を利用できます。（セッションが完全に切れている場合にはMeCabのインストール、「Translate」のところのいくつかの定義の実行が必要です。）

#追記２：変換可視化グラフの日本語表示
翻訳のところで、matplotlibを使って翻訳前後の対応が可視化されていますが、日本語が文字化けする上に、ワーニングメッセージが大量に出ます。これに対応するには、matplotlibで正しく日本語を表示させる必要がありまs。

[【超簡単】たったの2ステップで matplotlib の日本語表記を対応させる方法](https://yolo.love/matplotlib/japanese/)を参考に、最初のほうで、japanize-matplotlibをインストールし、

    !pip install japanize-matplotlib

実際に（Download and prepare the datasetの直前のセルで）matplotlib.pyplotをインポートしている直後でインポートします。

    import japanize_matplotlib

これですっきり日本語が表示されます。