Lenar Hoyt
Lenar Hoyt

Reputation: 6159

How can I create a scalar summary that is averaged over multiple graph invocations in TensorFlow?

Let's say I have a scenario like this:

import tensorflow as tf

sess = tf.Session()

x = tf.random_normal([])
tf.scalar_summary('x', x)

merged = tf.merge_all_summaries()
sw = tf.train.SummaryWriter('.', sess.graph)

summaries = []
for i in range(100):
  summary = sess.run(merged)
  sw.add_summary(summary, i/10)
  summaries.append(summary)

sw.close()

I want 10 values that have the same global_step to be averaged. Is there a way to accomplish that apart from feeding previous values and adding them inside the graph? Can I perhaps somehow create scalar summaries on the fly using the resulting summaries array of binary Protocol Buffer messages, perhaps by using google.protobuf directly?

Upvotes: 0

Views: 441

Answers (1)

fabmilo
fabmilo

Reputation: 48330

You can add a variable in your graph that tracks the avg value of the x value.

See the modified example below.

The code adds a count and running_sum variables. The summary op is then connected to the running_sum/count operation. Evaluating the graph in the same session will maintain the state of the running_sum and count variables.

g = tf.Graph()
with g.as_default():
    tf.set_random_seed(1234)

    x = tf.random_normal([])

    count = tf.get_variable("count", initializer=tf.zeros([]), dtype=tf.float32)
    count = count.assign_add(1)

    running_sum = tf.get_variable("running_sum", initializer=tf.zeros_like(x))
    running_sum = running_sum.assign_add(x)
    avg = tf.div(running_sum, count)
    tf.scalar_summary("average", avg)

    merged = tf.merge_all_summaries()   
    sw = tf.train.SummaryWriter('.', sess.graph)
    init_op = tf.initialize_all_variables()

with tf.Session(graph=g) as sess:
    sess.run(init_op)
    x_values = []
    for i in range(10):
        value, x_value, summaries_value = sess.run([avg, x, merged])
        # Accumulate the values
        x_values.append(x_value)
        # Test it
        np_mean = np.mean(x_values)
        np.testing.assert_almost_equal(np_mean, value)
        print value, x_value     

Output:

0.325545 0.325545
0.201057 -0.124489
-0.468691 -0.669747
-0.729087 -0.260396
-0.323435 0.405652
0.263484 0.586919
0.600163 0.336679
-0.763652 -1.36382
-0.369373 0.394279
-0.934823 -0.56545

Upvotes: 1

Related Questions