Closed sumanthratna closed 4 years ago
Can’t know for sure without seeing the event file, but it looks like
what’s happening is that e.summary.value[0]
is raising on the first
iteration, where e.summary.value
is empty, but it would have actually
worked on the second iteration if the code had gotten there. It’s
expected that e.summary.value.tag
should raise, because value
is a
repeated field, represented as a Python sequence (list
-like object).
Using e.summary.value[i].tag
should work as long as the index i
is
within bounds.
Off the top of my head (untested), try something like the following?
from tensorflow.python.summary.summary_iterator import summary_iterator
si = summary_iterator(
"snowy/snowy1/events.out.tfevents.1577067052.snowy.1378.5.v2")
count = 0
for event in si:
for value in event.summary.value:
count += 1
print(str(count) + ': ' + str(value))
Please note that this is all doubly unsupported: tensorflow.python.*
is a private namespace, and summary_iterator
is deprecated. There
aren’t any officially supported ways to read the event files by hand.
Also, this is really more of a question about how to use the Python APIs
for protocol buffers. I’m happy to provide some ad hoc support where
it’s feasible, but we don’t promise to maintain forward compatibility
such that any scripts that you write will necessarily work with data
written in the future.
Thanks for the help, your script worked. Here's what I'm running:
import tensorflow as tf
from tensorflow.python.summary.summary_iterator import summary_iterator
si = summary_iterator(
"snowy/snowy1/events.out.tfevents.1577067052.snowy.1378.5.v2")
count = 0
for event in si:
for value in event.summary.value:
count += 1
data = tf.io.decode_raw(value.metadata.plugin_data.content, tf.float64)
tf.print(data)
and I'm getting tensorflow.python.framework.errors_impl.InvalidArgumentError: Input to DecodeRaw has length 989 that is not a multiple of 8, the size of double [Op:DecodeRaw]
Changing it to data = tf.io.decode_raw(value.metadata.plugin_data.content, tf.uint8)
results in [18 218 7 ... 121 110 99]
which is great but my data includes decimals.
Changing it to data = tf.compat.as_str_any(value.metadata.plugin_data.content)
results in UnicodeDecodeError: 'utf-8' codec can't decode byte 0xda in position 1: invalid continuation byte
.
Here's the log file in case you need it to help me: https://gofile.io/?c=kYoD4c. Thanks again!
The decode_raw
raw is used to deserialize a sequence of packed values,
like this:
>>> tf.io.decode_raw(b"\x34\x12\x78\x56", out_type="int16").numpy()
array([ 4660, 22136], dtype=int16)
>>> [0x1234, 0x5678]
[4660, 22136]
But the contents of an hparams metadata.plugin_data.content
are an
encoded HParamsPluginData
protocol buffer, which should be
deserialized with HParamsPluginData.FromString(bytestring)
. Something
like:
import tensorflow as tf
from tensorflow.python.summary.summary_iterator import summary_iterator
from tensorboard.plugins.hparams import plugin_data_pb2
si = summary_iterator(
"snowy/snowy1/events.out.tfevents.1577067052.snowy.1378.5.v2"
)
count = 0
for event in si:
for value in event.summary.value:
count += 1
proto_bytes = value.metadata.plugin_data.content
plugin_data = plugin_data_pb2.HParamsPluginData.FromString(proto_bytes)
if plugin_data.HasField("experiment"):
print(
"Got experiment metadata with %d hparams and %d metrics"
% (
len(plugin_data.experiment.hparam_infos),
len(plugin_data.experiment.metric_infos),
),
)
elif plugin_data.HasField("session_start_info"):
print(
"Got session start info with concrete hparam values: %r"
% (dict(plugin_data.session_start_info.hparams),)
)
(Again, a quick check shows that this appears to work with latest
tf-nightly
on my machine, but we don’t officially support these
reading APIs.)
Thanks again for the help, your script does work. It turns out that the hparams data isn't just stored in the "main" file; in each run log, there's data that says which hparams were used (I didn't know this).
Also, to be honest, I don't care about compatibility in the future because I'm at a point where I just want the data.
Thanks for all your help and patience with this and other issues.
Yep, exactly. In a typical hparams logdir structure, the top-level directory has the experiment description, and each run has its own events file with the concrete hparams values used for that run.
Also, to be honest, I don't care about compatibility in the future because I'm at a point where I just want the data.
Yep, totally reasonable. :-)
Thanks for all your help and patience with this and other issues.
My pleasure.
This worked great until a few days ago (I think). To anybody looking for a way to parse HParams log files, they changed the API:
module 'tensorflow_core._api.v2.io.gfile' has no attribute 'get_filesystem'
Hi there - I used the code mentioned here by @wchargin and am able to export all the HParams hyperparameters from the "session_start_info" but can't find any of the actual 'experiment' results. Basically, using the code provided by @wchargin and inserting an event file name from a 'run-???' folder into the 'si' statement, the 'if' statement below has not been true when I've run it against over 1000 event files. Any suggestion would be greatly appreciated!
if plugin_data.HasField("**experiment**"):
print(
"Got experiment metadata with %d hparams and %d metrics"
% (
len(plugin_data.experiment.hparam_infos),
len(plugin_data.experiment.metric_infos),
),
@sumanthratna: I’m not sure off the top of my head why that might be,
sorry. The summary_iterator
module still exists at head.
@JimAva: The top-level experiment
metadata will only be set if you
used the hp.hparams_config
summary function, and will appear in
the logdir to which that summary was written. Typically, this is a
logdir one level above all the runs, so if your directory structure
includes runs like logs/mnist/lr=1,fc=2
then logs/mnist
is probably
the directory that contains the relevant events file.
Thank you @wchargin - another question, is it possible to 'only' generate/log the HParams hyperparameters & metrics? I have thousands of hyperparameters combination that I'd to run and need to speed the process up.
I got it figured out. I was logging too much stuff and I changed these parameters to FALSE: write_graph=False, write_grads=False, write_images=False.
I also have a hard time parsing hparams
events. I wrote a small python package recently (tbparse) that parses the hparams
events for you and store it inside a pandas DataFrame
for later use:
from tbparse import SummaryReader
log_dir = "<PATH_TO_EVENT_FILE_OR_DIRECTORY>"
reader = SummaryReader(log_dir)
hp = reader.hparams
print(hp)
I also wrote some documentation that provides examples for different use cases.
Environment information (required)
Diagnostics
Diagnostics output
`````` --- check: autoidentify Traceback (most recent call last): File "Next steps
No action items identified.
Issue description
I want to export all of my hyperparameters data to a CSV file. Since #3060 won't be merged into TensorBoard for a while, I decided I'd use
tensorflow.python.summary.summary_iterator.summary_iterator
to manually export to a CSV. Here's a very simple script:It outputs:
I don't really care about the first (empty) list that's printed, but the second list has what I want. Printing
e.summary.value.tag
ande.summary.value.metadata
both result inAttributeError: 'google.protobuf.pyext._message.RepeatedCompositeCo' object has no attribute
.e.summary.value[0]
ande.summary.value[1]
result inIndexError: list index out of range
.According to summary.proto it looks like
metadata
andtag
should both be valid attributes.NOTE: this looks like this should be for Stack Overflow but at the beginning of the output I get:
Maybe a method was removed because of deprecation and this altered the functionality of
summary_iterator
?