EmbedIDで埋め込みベクトルから単語IDを逆算する
2016年04月28日
概要
- ChainerのEmbedIDを拡張した
- コサイン類似度をもとに埋め込みベクトルから単語IDを求める
はじめに
ChainerのEmbedIDは、単語ID(整数値)から対応する埋め込みベクトル(多次元実数ベクトル)を出力します。
今回はこの埋め込みベクトルから単語IDを知るための手法の紹介です。
コードはembed-id-extendedに置いてます。
使い方
単語ベクトル(最初の軸はバッチ)のndarrayを入力します。
from embed_id import EmbedID
...
embed = EmbedID(n_ids, ndim_vec)
vec = embed(id)
id = embed.reverse(vec.data)
実装
入力ベクトルと、EmbedID.Wのそれぞれのベクトルとのコサイン類似度を計算します。
W = self.W.data
xp = cuda.get_array_module(*(vec,))
w_norm = xp.sqrt(xp.sum(W ** 2, axis=1))
v_norm = xp.sqrt(xp.sum(vec ** 2, axis=1))
inner_product = W.dot(vec.T)
norm = w_norm.reshape(1, -1).T.dot(v_norm.reshape(1, -1)) + 1e-6
cosine_similarity = inner_product / norm
こうするとcosine_similarityの最初の軸が単語IDに対応するので(2番目の軸はバッチ)、argmax(axis=0)で類似度が最も高いIDが出てきます。
応用
RNNで自然言語処理をする場合、出力層としてソフトマックス層を使い、教師IDとのsoftmax_cross_entropyで誤差を求めると思います。
今回の拡張EmbedIDを用いるには、まずネットワークからソフトマックス層を取り除き、代わりに埋め込みベクトルを直接出力するように変更します。
そして教師埋め込みベクトルとのmean_squared_errorで二乗誤差を計算し学習を行います。
推論時には出力された埋め込みベクトルをEmbedID.reverseでIDに変換します。
この応用が何の役に立つのかは不明です。
おまけ
これを利用したLSTMはこちら