EmbedID に学習済み word2vec の重みパラメータをセットする [Chainer]

深層学習における自然言語処理のタスクでは、単語の埋め込み層として、学習済み word2vec (Skip-gram / CBOW) モデルを使用することがあります。 本記事では、Chainer で EmbedID に学習済み word2vec をセットする方法を説明します。

例として、学習済みモデルは次のページで配布されているものを使用します。
GitHub - Kyubyong/wordvectors: Pre-trained word vectors of 30+ languages

上記のページにある "Japanese (w)" のリンクから word2vec モデルをダウンロードして解凍します(Requirements に "mecab" とあるので、単語分割には MeCab + IPA 辞書を使用しているのでしょうか)。

次のコードで EmbedID に学習済み word2vec の重みパラメータをセットします。
※ あらかじめ、Chainer, gensim, NumPy をインストールしておいてください

import gensim
import numpy as np
import chainer.links as L
from chainer import Variable

# word2vec モデルを読み込む
word2vec = gensim.models.Word2Vec.load('ja/ja.bin')

# 単語辞書 (index to word / word to index) を用意する
i2w = word2vec.wv.index2word
w2i = {w: i for i, w in enumerate(i2w)}
n_vocab = len(i2w)

# EmbedID を初期化し、重みパラメータとして word2vec をセットする
emb = L.EmbedID(n_vocab, word2vec.vector_size, initialW=word2vec.wv.vectors)

emb.disable_update()

最終行の emb.disable_update() を実行すると、ニューラルネットの学習中に EmbedID の重みが更新されなくなります。

これで準備は完了です。確認のために、gensim と Chainer で、それぞれ同じ単語を与えたときに同じベクトルが取得できるか見てみます。

e1 = word2vec['今日']
print(e1)

# [-1.5841931  -0.16819568  0.17484002 -0.70384747 -0.34765592 -0.355766
#  -0.23339556  0.6226926   0.2746878   0.15454574 -0.70101714 -0.5748118
#  ...
#  -0.42160854 -0.44855088  1.7454495  -1.893566    1.4198955   0.12920022
#   2.1218472  -0.7616498   3.1082888  -1.3034075   0.2861628   0.31217498]

x = Variable(np.array([w2i['今日']], dtype=np.int32))
e2 = emb(x)
print(e2[0].data)

# [-1.5841931  -0.16819568  0.17484002 -0.70384747 -0.34765592 -0.355766
#  -0.23339556  0.6226926   0.2746878   0.15454574 -0.70101714 -0.5748118
#  ...
#  -0.42160854 -0.44855088  1.7454495  -1.893566    1.4198955   0.12920022
#   2.1218472  -0.7616498   3.1082888  -1.3034075   0.2861628   0.31217498]

同じベクトルが取得できました。問題なく動作するようです。