web-dev-qa-db-ja.com

LSTMptbモデルのテンソルフローの例を使用して次の単語を予測する

次のWord予測を行うためにtensorflow LSTMモデル を使用しようとしています。

これで説明されているように 関連する質問 (受け入れられた回答はありません)この例には、次の単語の確率を抽出するための擬似コードが含まれています。

_lstm = rnn_cell.BasicLSTMCell(lstm_size)
# Initial state of the LSTM memory.
state = tf.zeros([batch_size, lstm.state_size])

loss = 0.0
for current_batch_of_words in words_in_dataset:
  # The value of state is updated after processing each batch of words.
  output, state = lstm(current_batch_of_words, state)

  # The LSTM output can be used to make next Word predictions
  logits = tf.matmul(output, softmax_w) + softmax_b
  probabilities = tf.nn.softmax(logits)
  loss += loss_function(probabilities, target_words)
_

確率ベクトルを解釈する方法について混乱しています。 ptb_Word_lm.pyPTBModelの___init___関数を変更して、確率とロジットを保存しました。

_class PTBModel(object):
  """The PTB model."""

  def __init__(self, is_training, config):
    # General definition of LSTM (unrolled)
    # identical to tensorflow example ...     
    # omitted for brevity ...


    # computing the logits (also from example code)
    logits = tf.nn.xw_plus_b(output,
                             tf.get_variable("softmax_w", [size, vocab_size]),
                             tf.get_variable("softmax_b", [vocab_size]))
    loss = seq2seq.sequence_loss_by_example([logits],
                                            [tf.reshape(self._targets, [-1])],
                                            [tf.ones([batch_size * num_steps])],
                                            vocab_size)
    self._cost = cost = tf.reduce_sum(loss) / batch_size
    self._final_state = states[-1]

    # my addition: storing the probabilities and logits
    self.probabilities = tf.nn.softmax(logits)
    self.logits = logits

    # more model definition ...
_

次に、それらに関する情報を_run_Epoch_関数に出力します。

_def run_Epoch(session, m, data, eval_op, verbose=True):
  """Runs the model on the given data."""
  # first part of function unchanged from example

  for step, (x, y) in enumerate(reader.ptb_iterator(data, m.batch_size,
                                                    m.num_steps)):
    # evaluate proobability and logit tensors too:
    cost, state, probs, logits, _ = session.run([m.cost, m.final_state, m.probabilities, m.logits, eval_op],
                                 {m.input_data: x,
                                  m.targets: y,
                                  m.initial_state: state})
    costs += cost
    iters += m.num_steps

    if verbose and step % (Epoch_size // 10) == 10:
      print("%.3f perplexity: %.3f speed: %.0f wps, n_iters: %s" %
            (step * 1.0 / Epoch_size, np.exp(costs / iters),
             iters * m.batch_size / (time.time() - start_time), iters))
      chosen_Word = np.argmax(probs, 1)
      print("Probabilities shape: %s, Logits shape: %s" % 
            (probs.shape, logits.shape) )
      print(chosen_Word)
      print("Batch size: %s, Num steps: %s" % (m.batch_size, m.num_steps))

  return np.exp(costs / iters)
_

これにより、次のような出力が生成されます。

_0.000 perplexity: 741.577 speed: 230 wps, n_iters: 220
(20, 10000) (20, 10000)
[ 14   1   6 589   1   5   0  87   6   5   3   5   2   2   2   2   6   2  6   1]
Batch size: 1, Num steps: 20
_

probsベクトルが確率の配列であり、語彙内の単語ごとに1つ(たとえば、形状_(1, vocab_size)_)であると期待していました。つまり、np.argmax(probs, 1)他の質問で提案されているように。

ただし、ベクトルの最初の次元は、実際には展開されたLSTMのステップ数(小さな構成設定が使用されている場合は20)に等しいため、どうすればよいかわかりません。予測されたWordにアクセスするには、最後の値を使用する必要がありますか(これは最終ステップの出力であるため)?それとも私が見逃しているものは他にありますか?

この評価を実行する必要がある seq2seq.sequence_loss_by_example の実装を見て、予測がどのように行われ、評価されるかを理解しようとしましたが、これは_gen_nn_ops._sparse_softmax_cross_entropy_with_logits_を呼び出すことになります。 githubリポジトリに含まれるため、他にどこを見ればよいかわかりません。

私はテンソルフローとLSTMの両方にまったく慣れていないので、助けていただければ幸いです。

11
rebeccaroisin

outputテンソルには、各タイムステップのLSTMセル出力の連結が含まれます(その定義を参照 ここ )。したがって、_chosen_Word[-1]_(または、展開されたLSTMに一致するようにシーケンスが埋め込まれている場合は_chosen_Word[sequence_length - 1]_)を取ることで、次の単語の予測を見つけることができます。

tf.nn.sparse_softmax_cross_entropy_with_logits() opは、パブリックAPIに別の名前で文書化されています。技術的な理由から、GitHubリポジトリに表示されない生成されたラッパー関数を呼び出します。 opの実装はC++で、 ここ です。

8
mrry

私もseq2seqモデルを実装しています。

だから私は私の理解で説明しようとしましょう:

LSTMモデルのoutputsは、サイズ[batch_sizesizeの2Dテンソルのリスト(長さnum_steps)です。 =]。

コード行:

output = tf.reshape(tf.concat(1, outputs), [-1, size])

サイズ[batch_size x num_stepssize]の2Dテンソルである新しいoutputを生成します。

あなたの場合、batch_size = 1およびnum_steps = 20->出力形状は[2size]です。

コード行:

logits = tf.nn.xw_plus_b(output, tf.get_variable("softmax_w", [size, vocab_size]), tf.get_variable("softmax_b", [vocab_size]))

<=> output [batch_size x num_steps、size] x softmax_w [size、vocab_size]はlogits of size [batch_size x num_stepsvocab_size]。
あなたの場合、logitsサイズ[2vocab_size]-> probsテンソルlogits by [2vocab_size]と同じサイズです。

コード行:

chosen_Word = np.argmax(probs, 1)

chosen_Wordサイズのテンソル[21]を出力します。各値は、現在のWordの次の予測Wordインデックスです。

コード行:

loss = seq2seq.sequence_loss_by_example([logits], [tf.reshape(self._targets, [-1])], [tf.ones([batch_size * num_steps])])

シーケンスのbatch_sizeのソフトマックスクロスエントロピー損失を計算することです。

5
Tony Khánh