如何编辑现有的 Tensorboard Training Loss 摘要?
Posted
技术标签:
【中文标题】如何编辑现有的 Tensorboard Training Loss 摘要?【英文标题】:How do you edit an existing Tensorboard Training Loss summary? 【发布时间】:2020-05-21 14:16:32 【问题描述】:我已经训练了我的网络并生成了一些训练/验证损失,我通过以下代码示例保存了这些损失(仅作为训练损失示例,验证完全等效):
valid_summary_writer = tf.summary.create_file_writer("/path/to/logs/")
with train_summary_writer.as_default():
tf.summary.scalar('Training Loss', data=epoch_loss, step=current_step)
训练后,我想使用 Tensorboard 查看损失曲线。但是,因为我将损失曲线保存在名称“Training Loss”和“Validation Loss”下,所以这些曲线绘制在单独的图表上。我知道我应该将名称更改为简单的“损失”以解决此问题,以便将来写入日志目录。但是如何编辑我现有的训练/验证损失日志文件来解决这个问题?
我尝试修改以下帖子的解决方案:https://***.com/a/55061404 编辑日志文件的步骤并重新写入文件;我的版本涉及更改文件中的标签。但我在这方面没有成功。它还需要通过 'tf.compat.v1' 导入较旧的 Tensorflow 代码。有没有办法实现这一点(可能在 TF 2.X 中)?
我曾想过简单地从包含损失的每个日志目录中获取损失和步长值,然后通过我以前的工作方法将它们写入新的日志文件,但我只设法获得了步长,而不是损失值本身。有人在这里取得过成功吗?
---=== 编辑 ===---
我设法使用来自@jhedesa 的代码解决了这个问题
我不得不稍微改变调用函数“rename_events_dir”的方式,因为我在 Google Colab Notebook 中协同使用 Tensorflow。为此,我更改了代码的最后部分:
if __name__ == '__main__':
if len(sys.argv) != 5:
print(f'sys.argv[0] <input dir> <output dir> <old tags> <new tag>',
file=sys.stderr)
sys.exit(1)
input_dir, output_dir, old_tags, new_tag = sys.argv[1:]
old_tags = old_tags.split(';')
rename_events_dir(input_dir, output_dir, old_tags, new_tag)
print('Done')
阅读本文:
rootpath = '/path/to/model/'
dirlist = [dirname for dirname in os.listdir(rootpath) if dirname not in ['train', 'valid']]
for dirname in dirlist:
rename_events_dir(rootpath + dirname + '/train', rootpath + '/train', 'Training Loss', 'loss')
rename_events_dir(rootpath + dirname + '/valid', rootpath + '/valid', 'Validation Loss', 'loss')
请注意,我调用了“rename_events_dir”两次,一次用于编辑训练损失的标签,一次用于验证损失标签。我可以通过设置“old_tags = 'Training Loss;Validation Loss'”并使用“old_tags = old_tags.split(';')”来拆分标签来使用之前调用代码的方法。我使用我的方法只是为了理解代码以及它如何处理数据。
【问题讨论】:
【参考方案1】:正如How to load selected range of samples in Tensorboard 中提到的,TensorBoard 事件实际上是存储的记录文件,因此您可以读取并处理它们。这是一个与那里发布的脚本类似的脚本,但用于重命名事件,并更新为在 TF 2.x 中工作。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# rename_events.py
import sys
from pathlib import Path
import os
# Use this if you want to avoid using the GPU
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
import tensorflow as tf
from tensorflow.core.util.event_pb2 import Event
def rename_events(input_path, output_path, old_tags, new_tag):
# Make a record writer
with tf.io.TFRecordWriter(str(output_path)) as writer:
# Iterate event records
for rec in tf.data.TFRecordDataset([str(input_path)]):
# Read event
ev = Event()
ev.MergeFromString(rec.numpy())
# Check if it is a summary
if ev.summary:
# Iterate summary values
for v in ev.summary.value:
# Check if the tag should be renamed
if v.tag in old_tags:
# Rename with new tag name
v.tag = new_tag
writer.write(ev.SerializeToString())
def rename_events_dir(input_dir, output_dir, old_tags, new_tag):
input_dir = Path(input_dir)
output_dir = Path(output_dir)
# Make output directory
output_dir.mkdir(parents=True, exist_ok=True)
# Iterate event files
for ev_file in input_dir.glob('**/*.tfevents*'):
# Make directory for output event file
out_file = Path(output_dir, ev_file.relative_to(input_dir))
out_file.parent.mkdir(parents=True, exist_ok=True)
# Write renamed events
rename_events(ev_file, out_file, old_tags, new_tag)
if __name__ == '__main__':
if len(sys.argv) != 5:
print(f'sys.argv[0] <input dir> <output dir> <old tags> <new tag>',
file=sys.stderr)
sys.exit(1)
input_dir, output_dir, old_tags, new_tag = sys.argv[1:]
old_tags = old_tags.split(';')
rename_events_dir(input_dir, output_dir, old_tags, new_tag)
print('Done')
你会这样使用它:
> python rename_events.py my_log_dir renamed_log_dir "Training Loss;Validation Loss" loss
【讨论】:
感谢您的建议。它主要用于解决我的问题,但是我不得不将“writer.write(ev.SerializeToString())”行缩进到第一个 if 语句的同一级别,因为它只是将最后一个“ev”条目写入文件我的日志。 此外,在 Tensorboard 中显示训练/验证损失曲线时,它确实给我带来了一些问题。由于它将曲线在不同日期的开始/结束时期连接在一起,我认为它还尝试根据我训练网络的时间和时期来显示 x 轴。我会发布一些 imgur 链接以供参考。 imgur.com/s1Dn97zimgur.com/RcfM79M你有什么建议吗? @AlexP 你是对的,那一行的缩进是错误的,感谢您指出这一点。避免曲线,我在过去看到过……您是否在train
和 validation
目录中同时写了“训练损失”和“验证损失”摘要(与仅在 @987654329 中的“训练损失”相反@ 和“验证丢失”仅在 validation
)?我猜不是,但这可以解释 TensorBoard 在重命名后会如此混乱......
我之前以以下方式保存了每个日志文件:“main_logdir/date/train”,所以如果我运行培训课程 5 次,就会有 5 个“日期”文件夹(我从那以后更改它,因为如果我只想将所有曲线显示为一个,它就不是一个很好的存储结构)。我还设法解决了额外的曲线/奇怪线问题;在我在这里发布之前,我正在测试在我当前的文件结构中存储新创建的日志,我忘记清除一个旧的 tfevents 文件,因此删除它可以解决问题。再次感谢您的帮助,您为我节省了很多时间!
感谢您的脚本,@jdehesa。我对其进行了调整以直接修改文件并仅在单个输入文件上工作,因此现在可以将其提供给find
,例如:find . -name "*.tfevents*" -exec tb-rename-events.py "iteration-time" "iteration-time/iteration-time" \;
脚本是here。以上是关于如何编辑现有的 Tensorboard Training Loss 摘要?的主要内容,如果未能解决你的问题,请参考以下文章
keras 在train_on_batch中启用tensorboard
TensorFlow 2.0 Keras:如何为TensorBoard编写图像摘要