66

我已经在 TensorFlow 中使用不同的图表运行了几次培训课程。我设置的摘要在训练和验证中显示了有趣的结果。现在,我想将我保存在摘要日志中的数据进行一些统计分析,并在总体上以不同的方式绘制和查看摘要数据。是否有任何现有的方法可以轻松访问这些数据?

更具体地说,是否有任何内置方法可以将 TFEvent 记录读回 Python?

如果没有简单的方法来做到这一点,TensorFlow 声明它的所有文件格式都是 protobuf 文件。根据我对 protobufs 的理解(这是有限的),如果我有 TFEvent 协议规范,我想我可以提取这些数据。有没有简单的方法来掌握这个?非常感谢。

4

9 回答 9

60

正如 Fabrizio所说,TensorBoard 是可视化摘要日志内容的绝佳工具。但是,如果要执行自定义分析,可以使用tf.train.summary_iterator()函数循环遍历日志中的所有tf.Eventtf.Summary协议缓冲区:

for summary in tf.train.summary_iterator("/path/to/log/file"):
    # Perform custom processing in here.

更新 tf2:

from tensorflow.python.summary.summary_iterator import summary_iterator

您需要导入它,默认情况下当前未导入该模块级别。在 2.0.0-rc2 上

于 2016-05-21T05:21:49.217 回答
38

要读取 TFEvent,您可以获得产生 Event 协议缓冲区的 Python 迭代器。

# This example supposes that the events file contains summaries with a
# summary value tag 'loss'.  These could have been added by calling
# `add_summary()`, passing the output of a scalar summary op created with
# with: `tf.scalar_summary(['loss'], loss_tensor)`.
for e in tf.train.summary_iterator(path_to_events_file):
    for v in e.summary.value:
        if v.tag == 'loss' or v.tag == 'accuracy':
            print(v.simple_value)

更多信息:summary_iterator

于 2016-10-13T19:23:33.410 回答
27

您可以简单地使用:

tensorboard --inspect --event_file=myevents.out

或者,如果您想过滤图形的特定事件子集:

tensorboard --inspect --event_file=myevents.out --tag=loss

如果你想创建更多自定义的东西,你可以深入研究

/tensorflow/python/summary/event_file_inspector.py 

了解如何解析事件文件。

于 2016-05-18T17:07:02.900 回答
13

以下作品为 tensorflow 版本2.0.0-beta1

import os

import tensorflow as tf
from tensorflow.python.framework import tensor_util

summary_dir = 'tmp/summaries'
summary_writer = tf.summary.create_file_writer('tmp/summaries')

with summary_writer.as_default():
  tf.summary.scalar('loss', 0.1, step=42)
  tf.summary.scalar('loss', 0.2, step=43)
  tf.summary.scalar('loss', 0.3, step=44)
  tf.summary.scalar('loss', 0.4, step=45)


from tensorflow.core.util import event_pb2
from tensorflow.python.lib.io import tf_record

def my_summary_iterator(path):
    for r in tf_record.tf_record_iterator(path):
        yield event_pb2.Event.FromString(r)

for filename in os.listdir(summary_dir):
    path = os.path.join(summary_dir, filename)
    for event in my_summary_iterator(path):
        for value in event.summary.value:
            t = tensor_util.MakeNdarray(value.tensor)
            print(value.tag, event.step, t, type(t))

的代码my_summary_iterator是从中复制的tensorflow.python.summary.summary_iterator.py- 无法在运行时导入它。

于 2019-08-04T10:22:24.247 回答
10

这是从标量获取值的完整示例。您可以在此处查看Event protobuf 消息的消息规范

import tensorflow as tf


for event in tf.train.summary_iterator('runs/easy_name/events.out.tfevents.1521590363.DESKTOP-43A62TM'):
    for value in event.summary.value:
        print(value.tag)
        if value.HasField('simple_value'):
            print(value.simple_value)
于 2018-03-22T21:57:54.813 回答
5

您可以使用脚本serialize_tensorboard,它将接收一个 logdir 并以 json 格式写出所有数据。

您还可以将EventAccumulator用于方便的 Python API(这与 TensorBoard 使用的 API 相同)。

于 2016-05-24T10:55:56.407 回答
1

有 2 种本地方式来读取本文中提到的事件文件

  1. 事件累加器

    >>> from tensorboard.backend.event_processing.event_accumulator import EventAccumulator
    >>> event_acc = EventAccumulator(event_file)
    >>> event_acc.Reload() 
    <tensorboard.backend.event_processing.event_accumulator.EventAccumulator object at ...>
    >>> print(event_acc.Tags())
    {'images': [], 'audio': [], 'histograms': [], 'scalars': ['y=2x'], 'distributions': [], 'tensors': [], 'graph': False, 'meta_graph': False, 'run_metadata': []}
    >>> for e in event_acc.Scalars('y=2x'):
    ...   print(e.step, e.value)
    0 0.0
    1 2.0
    2 4.0
    3 6.0
    4 8.0
    
  2. 摘要迭代器

    >>> import tensorflow as tf
    >>> from tensorflow.python.summary.summary_iterator import summary_iterator
    >>> for e in summary_iterator(event_file):
    ...   for v in e.summary.value:
    ...     if v.tag == 'y=2x':
    ...       print(e.step, v.simple_value)
    0 0.0
    1 2.0
    2 4.0
    3 6.0
    4 8.0
    

对于多个事件文件或其他事件类型(例如,直方图),您可以使用tbparse将事件日志解析为 pandas DataFrame 并在本地进行处理。如果您在解析过程中遇到任何问题,您可以打开一个问题。(我是tbparse的作者)

注意:仅当您将事件日志上传到TensorBoard.dev ( source ) 时,TensorBoard 才能将事件日志解析为 DataFrame,目前无法离线/本地使用它。

于 2021-12-01T13:11:18.150 回答
0

我一直在用这个。它假定您只想查看多次记录的标签,其值为浮动,并将结果作为pd.DataFrame. 只要打电话metrics_df = parse_events_file(path)

from collections import defaultdict
import pandas as pd
import tensorflow as tf

def is_interesting_tag(tag):
    if 'val' in tag or 'train' in tag:
        return True
    else:
        return False


def parse_events_file(path: str) -> pd.DataFrame:
    metrics = defaultdict(list)
    for e in tf.train.summary_iterator(path):
        for v in e.summary.value:

            if isinstance(v.simple_value, float) and is_interesting_tag(v.tag):
                metrics[v.tag].append(v.simple_value)
            if v.tag == 'loss' or v.tag == 'accuracy':
                print(v.simple_value)
    metrics_df = pd.DataFrame({k: v for k,v in metrics.items() if len(v) > 1})
    return metrics_df
于 2019-04-24T05:01:26.247 回答
0

TensorFlow 和 TensorFlow Datasets 的 2020 年末版本推荐了一种不同的方法。使用tf.data.TFRecordDatasetevent_pb2

from os import path, listdir
from operator import contains
from functools import partial
from itertools import chain
from json import loads

import numpy as np
import tensorflow as tf
from tensorflow.core.util import event_pb2

# From https://github.com/Suor/funcy/blob/0ee7ae8/funcy/funcs.py#L34-L36
def rpartial(func, *args):
    """Partially applies last arguments."""
    return lambda *a: func(*(a + args))


tensorboard_logdir = "/tmp"


# Or you could just glob… for *tfevents*:
list_dir = lambda p: map(partial(path.join, p), listdir(p))

for event in filter(rpartial(contains, "tfevents"),
                    chain.from_iterable(
                        map(list_dir,
                            chain.from_iterable(
                                map(list_dir,
                                    filter(rpartial(contains, "_epochs_"),
                                           list_dir(tensorboard_logdir))))))):
    print(event)
    for raw_record in tf.data.TFRecordDataset(event):
        for value in event_pb2.Event.FromString(raw_record.numpy()).summary.value:
            print("value: {!r} ;".format(value))
            if value.tensor.ByteSize():
                t = tf.make_ndarray(value.tensor)
                if hasattr(event, "step"):
                    print(value.tag, event.step, t, type(t))
                elif type(t).__module__ == np.__name__:
                    print("t: {!r} ;".format(np.vectorize(loads)(t)))
    print()
于 2020-12-30T14:14:25.007 回答