"""Simple example on how to log scalars and images to tensorboard without tensor ops. | |
License: BSD License 2.0 | |
""" | |
__author__ = "Michael Gygli" | |
import tensorflow as tf | |
from StringIO import StringIO | |
import matplotlib.pyplot as plt | |
import numpy as np | |
class Logger(object): | |
"""Logging in tensorboard without tensorflow ops.""" | |
def __init__(self, log_dir): | |
"""Creates a summary writer logging to log_dir.""" | |
self.writer = tf.summary.FileWriter(log_dir) | |
def log_scalar(self, tag, value, step): | |
"""Log a scalar variable. | |
Parameter | |
---------- | |
tag : basestring | |
Name of the scalar | |
value | |
step : int | |
training iteration | |
""" | |
summary = tf.Summary(value=[tf.Summary.Value(tag=tag, | |
simple_value=value)]) | |
self.writer.add_summary(summary, step) | |
def log_images(self, tag, images, step): | |
"""Logs a list of images.""" | |
im_summaries = [] | |
for nr, img in enumerate(images): | |
# Write the image to a string | |
s = StringIO() | |
plt.imsave(s, img, format='png') | |
# Create an Image object | |
img_sum = tf.Summary.Image(encoded_image_string=s.getvalue(), | |
height=img.shape[0], | |
width=img.shape[1]) | |
# Create a Summary value | |
im_summaries.append(tf.Summary.Value(tag='%s/%d' % (tag, nr), | |
image=img_sum)) | |
# Create and write Summary | |
summary = tf.Summary(value=im_summaries) | |
self.writer.add_summary(summary, step) | |
def log_histogram(self, tag, values, step, bins=1000): | |
"""Logs the histogram of a list/vector of values.""" | |
# Convert to a numpy array | |
values = np.array(values) | |
# Create histogram using numpy | |
counts, bin_edges = np.histogram(values, bins=bins) | |
# Fill fields of histogram proto | |
hist = tf.HistogramProto() | |
hist.min = float(np.min(values)) | |
hist.max = float(np.max(values)) | |
hist.num = int(np.prod(values.shape)) | |
hist.sum = float(np.sum(values)) | |
hist.sum_squares = float(np.sum(values**2)) | |
# Requires equal number as bins, where the first goes from -DBL_MAX to bin_edges[1] | |
# See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/framework/summary.proto#L30 | |
# Thus, we drop the start of the first bin | |
bin_edges = bin_edges[1:] | |
# Add bin edges and counts | |
for edge in bin_edges: | |
hist.bucket_limit.append(edge) | |
for c in counts: | |
hist.bucket.append(c) | |
# Create and write Summary | |
summary = tf.Summary(value=[tf.Summary.Value(tag=tag, histo=hist)]) | |
self.writer.add_summary(summary, step) | |
self.writer.flush() |
This comment has been minimized.
This comment has been minimized.
This is great! |
This comment has been minimized.
This comment has been minimized.
Any chance you can add a function for text? |
This comment has been minimized.
This comment has been minimized.
Could you include a license? |
This comment has been minimized.
This comment has been minimized.
Thanks or the code it works great, found a small bug though... |
This comment has been minimized.
This comment has been minimized.
@nasimrahaman: Added copyleft |
This comment has been minimized.
This comment has been minimized.
Thank you for such a helpful tool ! I've been confused about how to write what I want into tensorboard |
This comment has been minimized.
This comment has been minimized.
Thanks! |
This comment has been minimized.
This comment has been minimized.
doesn't work because pyplot.imsave() expects a file path |
This comment has been minimized.
This comment has been minimized.
That's not true, at least for more recent versions, where it can be a "file-like" object, see: @adizhol: Maybe your version is outdated? |
This comment has been minimized.
This comment has been minimized.
Thanks! |
This comment has been minimized.
This comment has been minimized.
It works, thx! |
This comment has been minimized.
This comment has been minimized.
Great code, thanks |
This comment has been minimized.
This comment has been minimized.
excellent work, and I have to use |
This comment has been minimized.
This comment has been minimized.
Cool! Thanks |
This comment has been minimized.
This comment has been minimized.
@gyglim Maybe it is worth to add |
This comment has been minimized.
This comment has been minimized.
Thanks a lot, perfect! |
This comment has been minimized.
This comment has been minimized.
Thanks a lot Michael, this helped me today :). Cheers ! |
This comment has been minimized.
This comment has been minimized.
Are you sure this works for multiple scalars? Is flush needed? I see points showing up in tboard but they do not seem to update often enough? |
This comment has been minimized.
This comment has been minimized.
Also anyone know what to put in a step to get the scalars to look similar to the keras callback scalars? |
This comment has been minimized.
This comment has been minimized.
text summary can be a new feature |
This comment has been minimized.
This comment has been minimized.
Anyone knows how to construct text summary? |
This comment has been minimized.
This comment has been minimized.
What does 'License: Copyleft' mean? Thanks!! |
This comment has been minimized.
This comment has been minimized.
Added BSD License 2.0 |
This comment has been minimized.
This comment has been minimized.
@gyglim Thanks!! :) |
This comment has been minimized.
This comment has been minimized.
To add text summary from tensorboard.plugins.text import metadata
class Logger(object):
"""Logging in tensorboard without tensorflow ops."""
def __init__(self, log_dir):
"""Creates a summary writer logging to log_dir."""
self.writer = tf.summary.FileWriter(log_dir)
def log_text(self, tag, value, step):
"""Log string or 2D string tables. """
summary_metadata = metadata.create_summary_metadata(
display_name="text",
description="Text Summary")
summary_metadata = tf.SummaryMetadata.FromString(
summary_metadata.SerializeToString())
tensor = tf.make_tensor_proto(value, dtype=tf.string)
summary = tf.Summary(value=[tf.Summary.Value(
tag=tag,
metadata=summary_metadata,
tensor=tensor
)])
self.writer.add_summary(summary, step)
self.writer.flush() Example usage: logger = Logger('/tmp/test')
logger.log_text(tag="string", value="test", step=0)
logger.log_text(tag="table", value=[["r0c0", "r0c1"], ["r1c0", "r1c1"]], step=0) |
This comment has been minimized.
This comment has been minimized.
I get some incompatibility errors when running on tensorflow 2.0. Any plans to update this -very useful- code? |
This comment has been minimized.
This comment has been minimized.
Wonderful solution:) Why |
This comment has been minimized.
This comment has been minimized.
Very minor tweaks for xrz000's text summary for TF2 Compatibility:
Example Usage:
|
This comment has been minimized.
Example usage:
Then simpy run tensorboard:
Gives the following histogram on tensorboard (and the corresponding distribution)
