TensorFlow : TensorLayer : チュートリアル (4) Word2Vec (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 12/05/2018
* 本ページは、TensorLayer の以下のドキュメントの一部を翻訳した上で適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
チュートリアル (4)
Word2Vec サンプルを実行する
チュートリアルのこのパートでは、単語群のための行列を訓練します、そこでは各単語は行列の一意の行ベクトルにより表すことができます。最後には、類似の単語は類似のベクトルを持つでしょう。それから単語群を 2-次元平面にプロット出力するとき、類似の単語は互いに近くに群がることになります。
python tutorial_word2vec_basic.py
総てが正しくセットアップされれば、最後に出力を得るでしょう。
単語埋め込みを理解する
単語埋め込み
何故ベクトル表現を使用することを望むのか、そしてベクトルをどのように計算するかを理解するために Colah のブログ Word Representations を読むことを強く勧めます。word2vec についてのより詳細は Word2vec Parameter Learning Explained で見つけられます。
基本的には、埋め込み行列の訓練は教師なし学習です。総ての単語が一意の ID で表わされるとき、それは埋め込み行列の行インデックスで、単語はベクトルに変換できて、それは意味をより良く表わすことができます。例えば、一定の male-female 差分ベクトルがあるようです: woman − man = queen – king, これはベクトルの 1 次元が性別を表わすことを意味します。
モデルは次のように作成できます。
# train_inputs is a row vector, a input is an integer id of single word. # train_labels is a column vector, a label is an integer id of single word. # valid_dataset is a column vector, a valid set is an integer id of single word. train_inputs = tf.placeholder(tf.int32, shape=[batch_size]) train_labels = tf.placeholder(tf.int32, shape=[batch_size, 1]) valid_dataset = tf.constant(valid_examples, dtype=tf.int32) # Look up embeddings for inputs. emb_net = tl.layers.Word2vecEmbeddingInputlayer( inputs = train_inputs, train_labels = train_labels, vocabulary_size = vocabulary_size, embedding_size = embedding_size, num_sampled = num_sampled, nce_loss_args = {}, E_init = tf.random_uniform_initializer(minval=-1.0, maxval=1.0), E_init_args = {}, nce_W_init = tf.truncated_normal_initializer( stddev=float(1.0/np.sqrt(embedding_size))), nce_W_init_args = {}, nce_b_init = tf.constant_initializer(value=0.0), nce_b_init_args = {}, name ='word2vec_layer', )
データセット反復と損失
Word2vec は訓練のためにネガティブ・サンプリングと Skip-Gram モデルを使用します。Noise-Contrastive Estimation (NCE) 損失は損失の計算を減じるのを助けることができます。Skip-Gram はコンテキストとターゲットを反対にして、そのターゲット単語から各コンテキスト単語を予測することを試みます。次のように訓練データを生成するために tl.nlp.generate_skip_gram_batch を使用します、tutorial_generate_text.py を見てください。
# NCE cost expression is provided by Word2vecEmbeddingInputlayer cost = emb_net.nce_cost train_params = emb_net.all_params train_op = tf.train.AdagradOptimizer(learning_rate, initial_accumulator_value=0.1, use_locking=False).minimize(cost, var_list=train_params) data_index = 0 while (step < num_steps): batch_inputs, batch_labels, data_index = tl.nlp.generate_skip_gram_batch( data=data, batch_size=batch_size, num_skips=num_skips, skip_window=skip_window, data_index=data_index) feed_dict = {train_inputs : batch_inputs, train_labels : batch_labels} _, loss_val = sess.run([train_op, cost], feed_dict=feed_dict)
既存の埋め込み行列を restore する
埋め込み行列を訓練する最後に、行列と対応する辞書をセーブします。それから次回、行列と辞書を次のように restore できます。(tutorial_generate_text.py の main_restore_embedding_layer 参照)
vocabulary_size = 50000 embedding_size = 128 model_file_name = "model_word2vec_50k_128" batch_size = None print("Load existing embedding matrix and dictionaries") all_var = tl.files.load_npy_to_any(name=model_file_name+'.npy') data = all_var['data']; count = all_var['count'] dictionary = all_var['dictionary'] reverse_dictionary = all_var['reverse_dictionary'] tl.nlp.save_vocab(count, name='vocab_'+model_file_name+'.txt') del all_var, data, count load_params = tl.files.load_npz(name=model_file_name+'.npz') x = tf.placeholder(tf.int32, shape=[batch_size]) y_ = tf.placeholder(tf.int32, shape=[batch_size, 1]) emb_net = tl.layers.EmbeddingInputlayer( inputs = x, vocabulary_size = vocabulary_size, embedding_size = embedding_size, name ='embedding_layer') tl.layers.initialize_global_variables(sess) tl.files.assign_params(sess, [load_params[0]], emb_net)
以上