2016-11-24 9 views
22

私は次のように定義された要約の束を持っていると仮定すると:複数のバッチを平均化するにはどうすればよいですか?

loss = ... 
tf.scalar_summary("loss", loss) 
# ... 
summaries = tf.merge_all_summaries() 

私はsummariesテンソルにトレーニングデータ上のすべてのいくつかの手順を評価し、SummaryWriterに結果を渡すことができます。 結果は1つのバッチでのみ計算されるため、ノイズの多いサマリーになります。

しかし、検証データセット全体のサマリーを計算したいと思います。 もちろん、バリデーションデータセットを1つのバッチとして渡すことはできません。バッチが大きすぎるためです。 したがって、各検証バッチのサマリー出力を取得します。

サマリーが検証セット全体で計算されたように、サマリーを平均化する方法はありますか?

答えて

25

はPythonであなたの測定の平均化を行い、それぞれの平均のための新しい概要オブジェクトを作成します。ここで私は何をすべきかです:

accuracies = [] 

# Calculate your measure over as many batches as you need 
for batch in validation_set: 
    accuracies.append(sess.run([training_op])) 

# Take the mean of you measure 
accuracy = np.mean(accuracies) 

# Create a new Summary object with your measure 
summary = tf.Summary() 
summary.value.add(tag="%sAccuracy" % prefix, simple_value=accuracy) 

# Add it to the Tensorboard summary writer 
# Make sure to specify a step parameter to get nice graphs over time 
summary_writer.add_summary(summary, global_step) 
+0

Pythonコードで直接サマリーオブジェクトを構築するためのAPIがあることを知りませんでした。プロトコルバッファーなので意味があります。 – Georg

1

あなたは次のように、現在の合計を保存平均化し、各バッチの後に平均を再計算することができます

loss_sum = tf.Variable(0.) 
inc_op = tf.assign_add(loss_sum, loss) 
clear_op = tf.assign(loss_sum, 0.) 
average = loss_sum/batches 
tf.scalar_summary("average_loss", average) 

sess.run(clear_op) 
for i in range(batches): 
    sess.run([loss, inc_op]) 

sess.run(average) 
+0

は、このグラフにするたびに新しいスカラー概要を追加しないだろうコードは実行されますか? – Georg

+0

はい、あなたはそれを一度だけ実行するつもりだと思っていましたが(今は理解できませんが)今編集中... – sygi

+0

これは妥当と思われます。しかし、より洗練されたソリューションがあったらいいなあと思う。だが、それを思いつくことはできない。 – Georg

-1

私は一つの解決策を自分自身を発見しました。私はそれが一種のハッキーだと思うし、より洗練されたソリューションがあることを願っています。セットアップ中

:トレーニングループ内

valid_loss_placeholder = tf.placeholder(dtype=tf.float32, shape=[]) 
valid_loss_summary = tf.scalar_summary("valid loss", valid_loss_placeholder) 

# Compute valid loss in python by doing sess.run() for each batch 
# and averaging 
valid_loss = ... 

summary = sess.run(valid_loss_summary, {valid_loss_placeholder: valid_loss}) 
summary_writer.add_summary(summary, step) 
5

私は平均外のグラフを計算を避けるだろう。

あなたはtf.train.ExponentialMovingAverageを使用することができます。

その後
ema = tf.train.ExponentialMovingAverage(decay=my_decay_value, zero_debias=True) 
maintain_ema_op = ema.apply(your_losses_list) 

# Create an op that will update the moving averages after each training step. 
with tf.control_dependencies([your_original_train_op]): 
    train_op = tf.group(maintain_ema_op) 

、使用:

sess.run(train_op) 

それが制御依存として定義されているためmaintain_ema_opを呼び出します。

あなたの指数移動平均値、使用得るために:

moving_average = ema.average(an_item_from_your_losses_list_above) 

をそして使用してその値を取得する:

value = sess.run(moving_average) 

これは、あなたの計算グラフ内移動平均を計算します。

+0

@MZHnなぜTFに内部的に計算させるのが良いのですか?はるかに速いですか? (Pythonのような平均操作を処理することができるように思える) – DankMasterDan

4

テンソルフローに計算を実行させるのが常に良いと思います。

ストリーミングメトリックをご覧ください。彼らはあなたの現在のバッチの情報をフィードするための更新機能と平均化された要約を得るための機能を持っています。 多少このように見えるようになるだろう:

accuracy = ... 
streaming_accuracy, streaming_accuracy_update = tf.contrib.metrics.streaming_mean(accuracy) 
streaming_accuracy_scalar = tf.summary.scalar('streaming_accuracy', streaming_accuracy) 

# set up your session etc. 

for i in iterations: 
     for b in batches: 
       sess.run([streaming_accuracy_update], feed_dict={...}) 

    streaming_summ = sess.run(streaming_accuracy_scalar) 
    writer.add_summary(streaming_summary, i) 

またtensorflowのマニュアルを参照してください。https://www.tensorflow.org/versions/master/api_guides/python/contrib.metrics

と、この質問: How to accumulate summary statistics in tensorflow

+0

'sess.run(tf.local_variables_initializer())'が必要です。 –

関連する問題