Search code examples
tensorflowtensorboardfilewritersummaryscalar

Can't write Tensorflow scalar summary to event log


i'm trying to learn how to write tensorflow code on my own, but i'm stuck with this very basic issue: During learning steps i can't write any scalar summary to the event file, which is needed for Tensorboard. Here is my code:

import tensorflow as tf
import numpy as np
WORKDIR = "/content/log"

x = tf.constant([[1], [2], [3], [4]], dtype=tf.float32)
y_true = tf.constant([[0], [-1], [-2], [-3]], dtype=tf.float32)

linear_model = tf.layers.Dense(units=1)

y_pred = linear_model(x)

sess = tf.Session()
init = tf.global_variables_initializer()
with tf.name_scope("TRAIN"):
  loss = tf.losses.mean_squared_error(labels=y_true, predictions=y_pred)
  optimizer = tf.train.GradientDescentOptimizer(0.01)
  train = optimizer.minimize(loss)

writer = tf.summary.FileWriter(WORKDIR + "/tmp/5", graph=sess.graph)

sess.run(init)

for i in range(1000):
  _, loss_value = sess.run((train, loss))
  if i % 50 == 0:
    writer.add_summary(summary=loss_value, global_step=i)
    print(str(i)+" step: "+str(loss_value))
    writer.flush()
writer.close()

the error i get:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-7-732ee0fb1e1c> in <module>()
     27   _, loss_value = sess.run((train, loss))
     28   if i % 50 == 0:
---> 29     writer.add_summary(summary=loss_value, global_step=i)
     30     print(str(i)+" step: "+str(loss_value))
     31     writer.flush()

/usr/local/lib/python3.6/dist- 
packages/tensorflow/python/summary/writer/writer.py in add_summary(self, 
 summary, global_step)
    123     # to save space - we just store the metadata on the first value 
with a
    124     # specific tag.
--> 125     for value in summary.value:
    126       if not value.metadata:
    127         continue

AttributeError: 'numpy.float32' object has no attribute 'value'

Pls help me correct my code, because i have read a lot of issues around the topic but never encountered this specific problem. Thanks


Solution

  • A scalar summary or any summaries in general are collected by summary operations. Another way to think about this is to wrap the element you want to summary by summary op rather than record the element directly. This wrapping will create "a Tensor containsing a Summary protobuf", which is the acceptable format of add_summary.

    In detail, you will create a summary op by:

    loss_summ = tf.summary.scalar('loss', loss)
    

    Then run this op to get the tensor/value:

    _, loss_value, loss_summ_val = sess.run((train, loss, loss_summ))
    

    Finally, add the returned tensor/value rather then your actual loss_value to summary:

    writer.add_summary(summary=loss_summ_val, global_step=i)
    

    With minimum necessary changes, the following code will work. However, as "nairouz mrabah" suggested in the other answer, the structure of the code could be improved.

    import tensorflow as tf
    import numpy as np
    WORKDIR = "/content/log"
    
    x = tf.constant([[1], [2], [3], [4]], dtype=tf.float32)
    y_true = tf.constant([[0], [-1], [-2], [-3]], dtype=tf.float32)
    
    linear_model = tf.layers.Dense(units=1)
    
    y_pred = linear_model(x)
    
    sess = tf.Session()
    init = tf.global_variables_initializer()
    with tf.name_scope("TRAIN"):
      loss = tf.losses.mean_squared_error(labels=y_true, predictions=y_pred)
      loss_summ = tf.summary.scalar('loss', loss)
      optimizer = tf.train.GradientDescentOptimizer(0.01)
      train = optimizer.minimize(loss)
    
    writer = tf.summary.FileWriter(WORKDIR + "/tmp/5", graph=sess.graph)
    
    sess.run(init)
    
    for i in range(1000):
      # _, loss_value = sess.run((train, loss))
      _, loss_value, loss_summ_val = sess.run((train, loss, loss_summ))
      if i % 50 == 0:
        # writer.add_summary(summary=loss_value, global_step=i)
        writer.add_summary(summary=loss_summ_val, global_step=i)
        print(str(i)+" step: "+str(loss_value))
        writer.flush()
    writer.close()