2017-01-26 6 views
6

にRNNのパープレキシティを計算するためにどのように私は言葉RNNのパープレキシティを計算する方法Word RNNはtensorflow

のテンソルの流れのRNNのimplmentationを実行していますよ。

for e in range(model.epoch_pointer.eval(), args.num_epochs): 
     sess.run(tf.assign(model.lr, args.learning_rate * (args.decay_rate ** e))) 
     data_loader.reset_batch_pointer() 
     state = sess.run(model.initial_state) 
     speed = 0 
     if args.init_from is None: 
      assign_op = model.batch_pointer.assign(0) 
      sess.run(assign_op) 
      assign_op = model.epoch_pointer.assign(e) 
      sess.run(assign_op) 
     if args.init_from is not None: 
      data_loader.pointer = model.batch_pointer.eval() 
      args.init_from = None 
     for b in range(data_loader.pointer, data_loader.num_batches): 
      start = time.time() 
      x, y = data_loader.next_batch() 
      feed = {model.input_data: x, model.targets: y, model.initial_state: state, 
        model.batch_time: speed} 
      summary, train_loss, state, _, _ = sess.run([merged, model.cost, model.final_state, 
                 model.train_op, model.inc_batch_pointer_op], feed) 
      train_writer.add_summary(summary, e * data_loader.num_batches + b) 
      speed = time.time() - start 
      if (e * data_loader.num_batches + b) % args.batch_size == 0: 
       print("{}/{} (epoch {}), train_loss = {:.3f}, time/batch = {:.3f}" \ 
        .format(e * data_loader.num_batches + b, 
          args.num_epochs * data_loader.num_batches, 
          e, train_loss, speed)) 
      if (e * data_loader.num_batches + b) % args.save_every == 0 \ 
        or (e==args.num_epochs-1 and b == data_loader.num_batches-1): # save for the last result 
       checkpoint_path = os.path.join(args.save_dir, 'model.ckpt') 
       saver.save(sess, checkpoint_path, global_step = e * data_loader.num_batches + b) 
       print("model saved to {}".format(checkpoint_path)) 
    train_writer.close() 

答えて

4

プロジェクトあなたが参照している用途sequence_to_sequence_loss_by_example、クロスエントロピー損失を返します。

各エポックで訓練損失や他のものを示して訓練中のコードを以下に示します。だからトレーニングperplexityを計算するためには、hereのように損失を累乗する必要があります。

train_perplexity = tf.exp(train_loss) 

我々はTensorFlowは自然対数(TF Documentation)とクロスエントロピー損失を測定するため、塩基としてEの代わりに2を使用しなければなりません。ありがとう、@Matthias Arroと@Colin Skowのヒント。

詳細説明

2つの確率分布PとQのクロスエントロピーは我々が我々はQ.、Pに基づいて符号化方式を開発する際にPのイベントを符号化する必要があるビットの最小平均数を告げます私たちが通常知らない真の分布です。できるだけイベントごとにビット数の少ない素敵なコーディングスキームを開発できるように、PをできるだけPに近づけたいと思っています。

クロスエントロピーの計算で基数2を使用すると、ビットを小節としてしか使用できないので、ビットを言うべきではありません。しかし、TensorFlowは自然対数を使用するので、代わりにnatsのクロスエントロピーを測定しましょう。

したがって、コーパス内のすべてのトークン(文字/単語)が次のトークンに等しくなる可能性があるという悪い言語モデルがあるとします。 1000トークンのコーパスに対して、このモデルは、log(1000)= 6.9 natsのクロスエントロピーを有する。次のトークンを予測するときは、各ステップで1000個のトークンを均等に選択する必要があります。

より良い言語モデルは、Pに近い確率分布Qを決定するでしょう。したがって、クロスエントロピーは低くなります。クロスエントロピーが3.9ナットになる可能性があります。私たちは今、パープレキシティを測定したい場合は、我々は単にクロスエントロピー累乗:

EXP(3.9)だから、49.4

を=を、我々は損失を計算しているため、サンプル、上、良いモデルでしたあたかも50個のトークンの中から一様かつ独立して選択しなければならないかのように混乱します。

+0

私の場合、列車のロスは6.3であるため、列車の錯覚は2^6 = 64となりますか? –

+0

@ShanKhanはい。あなたのモデルは、単語ごとに64のオプションの中からランダムに選択しなければならないかのように、トレーニングデータ上で混乱します。 –

+1

downvoterはなぜコメントするのを気にしますか? –

0

あなたの損失関数が、あなたにベース2またはベースeのデータの対数尤度を与えるかどうかによって異なります。このモデルはlegacy_seq2seq.sequence_loss_by_exampleを使用しています。これはTensorFlowのバイナリクロスエントロピーを使用しています(appears to use logs of base e)。したがって、離散確率分布(テキスト)を扱っていても、Colin Skowが示唆したように、eで累乗する必要があります。つまり、tf.exp(train_loss)を使用する必要があります。