2017-12-30 57 views
2

テンソルフローの公式サンプルコードptb_word_ln.pyを見ているうちにembedding_lookupに関する質問があります。 the embedding_lookup nodeembedding_lookupはエンコーダとしてのみ使用されていますが、ptb_word_ln.pyにはデコーダがありません

入力としてのみ使用されています。出力はこれを使用しません。損失の評価はこの埋め込みの恩恵を受けることはできません。 embedding_lookupを使用したメリットは何ですか?オプティマイザでこのワード埋め込みを使用したい場合は、明示的に損失関数に接続しないでください。

次のようなソースコード:実際

self._input = input_ 

batch_size = input_.batch_size 
num_steps = input_.num_steps 
size = config.hidden_size 
vocab_size = config.vocab_size 

def lstm_cell(): 
    # With the latest TensorFlow source code (as of Mar 27, 2017), 
    # the BasicLSTMCell will need a reuse parameter which is unfortunately not 
    # defined in TensorFlow 1.0. To maintain backwards compatibility, we add 
    # an argument check here: 
    if 'reuse' in inspect.getargspec(
     tf.contrib.rnn.BasicLSTMCell.__init__).args: 
    return tf.contrib.rnn.BasicLSTMCell(
     size, forget_bias=0.0, state_is_tuple=True, 
     reuse=tf.get_variable_scope().reuse) 
    else: 
    return tf.contrib.rnn.BasicLSTMCell(
     size, forget_bias=0.0, state_is_tuple=True) 
attn_cell = lstm_cell 
if is_training and config.keep_prob < 1: 
    def attn_cell(): 
    return tf.contrib.rnn.DropoutWrapper(
     lstm_cell(), output_keep_prob=config.keep_prob) 
cell = tf.contrib.rnn.MultiRNNCell(
    [attn_cell() for _ in range(config.num_layers)], state_is_tuple=True) 

self._initial_state = cell.zero_state(batch_size, data_type()) 

with tf.device("/cpu:0"): 
    embedding = tf.get_variable(
     "embedding", [vocab_size, size], dtype=data_type()) 
    inputs = tf.nn.embedding_lookup(embedding, input_.input_data)#only use embeddings here 

if is_training and config.keep_prob < 1: 
    inputs = tf.nn.dropout(inputs, config.keep_prob) 

outputs = [] 
state = self._initial_state 
with tf.variable_scope("RNN"): 
    for time_step in range(num_steps): 
    if time_step > 0: tf.get_variable_scope().reuse_variables() 
    (cell_output, state) = cell(inputs[:, time_step, :], state) 
    outputs.append(cell_output) 

output = tf.reshape(tf.stack(axis=1, values=outputs), [-1, size]) 
softmax_w = tf.get_variable(
    "softmax_w", [size, vocab_size], dtype=data_type()) 
softmax_b = tf.get_variable("softmax_b", [vocab_size], dtype=data_type()) 
logits = tf.matmul(output, softmax_w) + softmax_b 
loss = tf.contrib.legacy_seq2seq.sequence_loss_by_example(
    [logits], 
    [tf.reshape(input_.targets, [-1])], 
    [tf.ones([batch_size * num_steps], dtype=data_type())]) 
self._cost = cost = tf.reduce_sum(loss)/batch_size 
self._final_state = state 

if not is_training: 
    return 

self._lr = tf.Variable(0.0, trainable=False) 
tvars = tf.trainable_variables() 
grads, _ = tf.clip_by_global_norm(tf.gradients(cost, tvars), 
            config.max_grad_norm) 
optimizer = tf.train.GradientDescentOptimizer(self._lr) 
self._train_op = optimizer.apply_gradients(
    zip(grads, tvars), 
    global_step=tf.contrib.framework.get_or_create_global_step()) 

self._new_lr = tf.placeholder(
    tf.float32, shape=[], name="new_learning_rate") 
self._lr_update = tf.assign(self._lr, self._new_lr) 

答えて

1

出力は埋め込みルックアップを使用しません。 TensorFlowプログラムは、通常、構築フェーズ、グラフのアセンブル、およびセッションを使用してグラフ内でopsを実行する実行フェーズに構造化されます。 loss(logits(output(outputs(cell_output(cell(inputs(embedding_lookup(embedding)))))))) I:あなたはこの順序で、グラフ上の次のノードを計算する必要が損失を計算するために、あなたのケースで

:これらは、関数呼び出しにネストされた場合は、それを見て

loss -> logits -> output -> outputs -> cell -> inputs -> embedding_lookup もう一つの方法は、より明確にするために、各関数(op)から追加の引数を出しています。

+0

こんにちはgidim、あなたの返信ありがとうございます。 Emm、私はまだあなたが "出力が埋め込みルックアップを使う"と言った理由を理解できません。コードから、埋め込みは入力によってのみ使用されます。損失関数は、1ホット・ロスでなければならない出力* softmax_w + softmax_bによって計算されます。だから私は埋め込みは損失の結果によって利用されているとは思わない。では、ここでembedding_lookupを使用する利点は何ですか? – setail

+0

埋め込みは損失によって確実に利用されます。出力はどのように計算されますか?ちょうどコードに従ってください。別の例で問題を編集した – gidim

関連する問題