2

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

ptamas90
  • 147
  • 3
  • 9

2 Answers2

2

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()
Y. Luo
  • 5,622
  • 1
  • 18
  • 25
  • thanks, i think i have tried this too, but with the wrong order. right now i think the solution was the combination of this answer and the previous one about the order. it works like charm – ptamas90 May 05 '18 at 17:53
  • @ptamas90 Glad you make it work. I just updated my answer with a complete code for others coming to this question in the future. – Y. Luo May 05 '18 at 22:54
1

You should fully create your graph (the loss and optimizer are part of the static graph), then you should create the session and finally, you can create a writer. Keep the right order, then it will work.

 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)
 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)
 init = tf.global_variables_initializer()
 with tf.Session() as sess:
      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()
nairouz mrabah
  • 1,177
  • 2
  • 13
  • 26
  • i tried this way using the with statement for session creation right before the training cycle like you suggested, but it returns the same error as above :( – ptamas90 May 05 '18 at 10:14
  • @ptamas90 Right order is the best and recommended practice though not required here. Nor it is the real cause of error here. Hope my answer below helps. – Y. Luo May 05 '18 at 16:26