chainerで自然言語処理できるかマン

chainerで自然言語処理を勉強していくブログ

word2vecの学習が収束しているのかプロットして確認

word2vecのサンプルを実行する際、epoch毎に累積損失(accum_loss)が表示されていましたが、ちゃんと収束しているかがコマンドライン上で見るだけではわかりにくいので、グラフにプロットして確認したいと思います。
が、ちょっとハマったのでメモしておきたいと思います。

コードでは100,000単語ごとに処理時間やスループットを表示しているので、その間の累積損失をプロットします。

コード

matplotlibを使って、プログラムに以下を追加します。

モジュールのインポート。

import numpy as np
import matplotlib.pyplot as plt   # 追加

プロットするデータを保管する変数を準備。

next_count = 100000

py = []              # 追加
sub_accum_loss = 0   # 追加

for epoch in range(args.epoch):

スループットを表示している部分に累積損失を配列に入れる処理を追加します。

for epoch in range(args.epoch):
    ...
    for i in indexes:
        if word_count >= next_count:
            ...
            next_count += 100000
            cur_at = now

            py.append(float(sub_accum_loss))   # 追加(※)
            sub_accum_loss = 0                 # 追加

        ...
        accum_loss += loss.data
        sub_accum_loss += loss.data            # 追加
        word_count += args.batchsize

        ...

コードの最後に描画処理を入れます。

plt.plot(py)                      # 追加
plt.grid()                        # 追加
plt.title("sub_accum_loss")       # 追加
plt.savefig('word2vec_log.png')   # 追加
plt.show()                        # 追加

ハマったところは、配列に追加する(※)部分で、sub_accum_lossの型が「cupy.core.core.ndarray」という0次元配列になっているようで、プロットに失敗していしまっていました。floatに変換する必要があるようです。
numpy - 0-dimension array問題 - Qiita

結果

$ python examples\word2vec\train_word2vec_plot.py --gpu=0

終了時にGUIなグラフ画面が表示され、「word2vec_log.png」にその画像が出力されています。

f:id:chainer_nlp_man:20151205151141p:plain
十分に収束しているようです。