如何在 Tensorboard 中加载选定范围的样本
How to load selected range of samples in Tensorboard
我有一个包含 500 万个样本的 Tensorboard 日志文件。 Tensorboard 在加载时对其进行降采样,这样我就不会 运行 内存不足,但可以使用 --samples_per_plugin
覆盖此行为并加载所有这些行为。如果我这样做,我将 运行 内存不足。假设我想加载 first 1000 个样本 而无需下采样 (例如,如果我对开始时我的网络发生的事情的详细信息感兴趣的培训)。
有没有办法让 Tensorboard 仅加载指定的样本子集?我认为截至目前还没有命令行参数,但也许有办法编辑日志文件或 Tensorboard 代码或其他一些解决方法?
我认为没有任何方法可以让 TensorBoard 做到这一点,但可以 "slice" 事件文件。这些文件原来是记录文件(只有事件数据而不是示例),因此您可以将它们阅读为TFRecordDataset
。显然,有第一条记录指示文件版本号,但除此之外它应该是直截了当的。假设你只有你想要切片的事件,你可以使用这样的函数(TF 1.x,尽管它在 2.x 中大致相同):
import tensorflow as tf
def slice_events(input_path, output_path, skip, take):
with tf.Graph().as_default():
ds = tf.data.TFRecordDataset([str(input_path)])
rec_first = ds.take(1).make_one_shot_iterator().get_next()
ds_data = ds.skip(skip + 1).take(take)
rec_data = ds_data.batch(1000).make_one_shot_iterator().get_next()
with tf.io.TFRecordWriter(str(output_path)) as writer, tf.Session() as sess:
writer.write(sess.run(rec_first))
while True:
try:
for ev in sess.run(rec_data):
writer.write(ev)
except tf.errors.OutOfRangeError: break
这会根据现有文件创建一个新的事件文件,其中第一个 skip
个事件被丢弃,然后 take
个事件被保存。您可以使用其他 Dataset
操作来选择要保留的数据。例如,下采样可以这样完成:
ds_data = ds.skip(1).window(1, 5).unbatch() # Takes one in five events
你可以制作一个脚本,把一个目录下的所有事件文件切片,然后保存到另一个具有相同结构的文件中,例如:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# slice_events.py
import sys
import os
from pathlib import Path
os.environ['CUDA_VISIBLE_DEVICES'] = '-1' # Not necessary to use GPU
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' # Avoid log messages
def slice_events(input_path, output_path, skip, take):
# Import here to avoid loading on error
import tensorflow as tf
# Code from before...
def slice_events_dir(input_dir, output_dir, skip, take):
input_dir = Path(input_dir)
output_dir = Path(output_dir)
output_dir.mkdir(parents=True, exist_ok=True)
for ev_file in input_dir.glob('**/*.tfevents*'):
out_file = Path(output_dir, ev_file.relative_to(input_dir))
out_file.parent.mkdir(parents=True, exist_ok=True)
slice_events(ev_file, out_file, skip, take)
if __name__ == '__main__':
if len(sys.argv) != 5:
print(f'{sys.argv[0]} <input dir> <output dir> <skip> <take>', file=sys.stderr)
sys.exit(1)
input_dir, output_dir, skip, take = sys.argv[1:]
skip = int(skip)
take = int(take)
slice_events_dir(input_dir, output_dir, skip, take)
然后你会用它作为
$ python slice_events.py log log_sliced 100 1000
请注意,这假设了一个简单的情况,即您只有一系列类似的事件需要切片。如果您有其他类型的事件(例如图形本身),或者同一文件中有多种类型的交错事件,或者其他东西,那么您需要根据需要调整逻辑。
我有一个包含 500 万个样本的 Tensorboard 日志文件。 Tensorboard 在加载时对其进行降采样,这样我就不会 运行 内存不足,但可以使用 --samples_per_plugin
覆盖此行为并加载所有这些行为。如果我这样做,我将 运行 内存不足。假设我想加载 first 1000 个样本 而无需下采样 (例如,如果我对开始时我的网络发生的事情的详细信息感兴趣的培训)。
有没有办法让 Tensorboard 仅加载指定的样本子集?我认为截至目前还没有命令行参数,但也许有办法编辑日志文件或 Tensorboard 代码或其他一些解决方法?
我认为没有任何方法可以让 TensorBoard 做到这一点,但可以 "slice" 事件文件。这些文件原来是记录文件(只有事件数据而不是示例),因此您可以将它们阅读为TFRecordDataset
。显然,有第一条记录指示文件版本号,但除此之外它应该是直截了当的。假设你只有你想要切片的事件,你可以使用这样的函数(TF 1.x,尽管它在 2.x 中大致相同):
import tensorflow as tf
def slice_events(input_path, output_path, skip, take):
with tf.Graph().as_default():
ds = tf.data.TFRecordDataset([str(input_path)])
rec_first = ds.take(1).make_one_shot_iterator().get_next()
ds_data = ds.skip(skip + 1).take(take)
rec_data = ds_data.batch(1000).make_one_shot_iterator().get_next()
with tf.io.TFRecordWriter(str(output_path)) as writer, tf.Session() as sess:
writer.write(sess.run(rec_first))
while True:
try:
for ev in sess.run(rec_data):
writer.write(ev)
except tf.errors.OutOfRangeError: break
这会根据现有文件创建一个新的事件文件,其中第一个 skip
个事件被丢弃,然后 take
个事件被保存。您可以使用其他 Dataset
操作来选择要保留的数据。例如,下采样可以这样完成:
ds_data = ds.skip(1).window(1, 5).unbatch() # Takes one in five events
你可以制作一个脚本,把一个目录下的所有事件文件切片,然后保存到另一个具有相同结构的文件中,例如:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# slice_events.py
import sys
import os
from pathlib import Path
os.environ['CUDA_VISIBLE_DEVICES'] = '-1' # Not necessary to use GPU
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' # Avoid log messages
def slice_events(input_path, output_path, skip, take):
# Import here to avoid loading on error
import tensorflow as tf
# Code from before...
def slice_events_dir(input_dir, output_dir, skip, take):
input_dir = Path(input_dir)
output_dir = Path(output_dir)
output_dir.mkdir(parents=True, exist_ok=True)
for ev_file in input_dir.glob('**/*.tfevents*'):
out_file = Path(output_dir, ev_file.relative_to(input_dir))
out_file.parent.mkdir(parents=True, exist_ok=True)
slice_events(ev_file, out_file, skip, take)
if __name__ == '__main__':
if len(sys.argv) != 5:
print(f'{sys.argv[0]} <input dir> <output dir> <skip> <take>', file=sys.stderr)
sys.exit(1)
input_dir, output_dir, skip, take = sys.argv[1:]
skip = int(skip)
take = int(take)
slice_events_dir(input_dir, output_dir, skip, take)
然后你会用它作为
$ python slice_events.py log log_sliced 100 1000
请注意,这假设了一个简单的情况,即您只有一系列类似的事件需要切片。如果您有其他类型的事件(例如图形本身),或者同一文件中有多种类型的交错事件,或者其他东西,那么您需要根据需要调整逻辑。