Обзор
Главная особенность TensorBoard - интерактивный графический интерфейс. Однако пользователи иногда хотят программно читать журналы данных, хранящиеся в TensorBoard, для таких целей, как выполнение апостериорного анализа и создание настраиваемых визуализаций данных журнала.
TensorBoard 2.3 поддерживает этот вариант использования с tensorboard.data.experimental.ExperimentFromDev()
. Он обеспечивает программный доступ к скалярным журналам TensorBoard. Эта страница демонстрирует базовое использование этого нового API.
Настроить
Чтобы использовать программный API, убедитесь, что вы установили pandas
вместе с tensorboard
.
Мы будем использовать matplotlib
и seaborn
для пользовательских графиков в этом руководстве, но вы можете выбрать предпочтительный инструмент для анализа и визуализации DataFrame
s.
pip install tensorboard pandas
pip install matplotlib seaborn
from packaging import version
import pandas as pd
from matplotlib import pyplot as plt
import seaborn as sns
from scipy import stats
import tensorboard as tb
major_ver, minor_ver, _ = version.parse(tb.__version__).release
assert major_ver >= 2 and minor_ver >= 3, \
"This notebook requires TensorBoard 2.3 or later."
print("TensorBoard version: ", tb.__version__)
TensorBoard version: 2.3.0a20200626
Загрузка скаляров TensorBoard как pandas.DataFrame
Как только лог-каталог TensorBoard загружен в TensorBoard.dev, он становится тем, что мы называем экспериментом . У каждого эксперимента есть уникальный идентификатор, который можно найти в URL-адресе эксперимента TensorBoard.dev. Для нашей демонстрации ниже мы будем использовать эксперимент TensorBoard.dev по адресу: https://tensorboard.dev/experiment/c1KCv3X3QvGwaXfgX1c4tg.
experiment_id = "c1KCv3X3QvGwaXfgX1c4tg"
experiment = tb.data.experimental.ExperimentFromDev(experiment_id)
df = experiment.get_scalars()
df
df
- это pandas.DataFrame
, содержащий все скалярные журналы эксперимента.
Столбцы DataFrame
:
-
run
: каждый запуск соответствует подкаталогу исходного каталога журнала. В этом эксперименте каждый запуск основан на полном обучении сверточной нейронной сети (CNN) на наборе данных MNIST с заданным типом оптимизатора (обучающий гиперпараметр). ЭтотDataFrame
содержит несколько таких запусков, которые соответствуют повторяющимся обучающим запускам с разными типами оптимизатора. -
tag
: описывает, что означаетvalue
в той же строке, то есть какую метрику представляет значение в строке. В этом эксперименте у нас есть только два уникальныхepoch_accuracy
:epoch_accuracy
иepoch_loss
для показателей точности и потерь соответственно. -
step
: это номер, который отражает порядковый номер соответствующей строки в ее прогоне. Здесьstep
фактически относится к номеру эпохи. Если вы хотите получить отметки времени в дополнение к значениямstep
, вы можете использовать аргумент ключевого словаinclude_wall_time=True
при вызовеget_scalars()
. -
value
: это действительное числовое значение, представляющее интерес. Как описано выше, каждоеvalue
в этом конкретномDataFrame
является либо потерей, либо точностью, в зависимости отtag
строки.
print(df["run"].unique())
print(df["tag"].unique())
['adam,run_1/train' 'adam,run_1/validation' 'adam,run_2/train' 'adam,run_2/validation' 'adam,run_3/train' 'adam,run_3/validation' 'adam,run_4/train' 'adam,run_4/validation' 'adam,run_5/train' 'adam,run_5/validation' 'rmsprop,run_1/train' 'rmsprop,run_1/validation' 'rmsprop,run_2/train' 'rmsprop,run_2/validation' 'rmsprop,run_3/train' 'rmsprop,run_3/validation' 'rmsprop,run_4/train' 'rmsprop,run_4/validation' 'rmsprop,run_5/train' 'rmsprop,run_5/validation' 'sgd,run_1/train' 'sgd,run_1/validation' 'sgd,run_2/train' 'sgd,run_2/validation' 'sgd,run_3/train' 'sgd,run_3/validation' 'sgd,run_4/train' 'sgd,run_4/validation' 'sgd,run_5/train' 'sgd,run_5/validation'] ['epoch_accuracy' 'epoch_loss']
Получение развернутого (широкоформатного) DataFrame
В нашем эксперименте два epoch_loss
( epoch_loss
и epoch_accuracy
) присутствуют на одном и том же наборе шагов при каждом запуске. Это позволяет получить DataFrame
«широкой формы» непосредственно из get_scalars()
с помощью аргумента ключевого слова pivot=True
. В широкоформатном DataFrame
все теги включены как столбцы DataFrame, что в некоторых случаях, в том числе и с этим, более удобно для работы.
Однако имейте в виду, что если условие наличия единых наборов значений шага для всех тегов во всех прогонах не выполняется, использование pivot=True
приведет к ошибке.
dfw = experiment.get_scalars(pivot=True)
dfw
Обратите внимание, что вместо одного столбца «значения» широкоформатный DataFrame включает в себя два тега (метрики) в качестве своих столбцов: epoch_accuracy
и epoch_loss
.
Сохранение DataFrame как CSV
pandas.DataFrame
хорошо взаимодействует с CSV . Вы можете сохранить его как локальный CSV-файл и загрузить его позже. Например:
csv_path = '/tmp/tb_experiment_1.csv'
dfw.to_csv(csv_path, index=False)
dfw_roundtrip = pd.read_csv(csv_path)
pd.testing.assert_frame_equal(dfw_roundtrip, dfw)
Выполнение пользовательской визуализации и статистического анализа
# Filter the DataFrame to only validation data, which is what the subsequent
# analyses and visualization will be focused on.
dfw_validation = dfw[dfw.run.str.endswith("/validation")]
# Get the optimizer value for each row of the validation DataFrame.
optimizer_validation = dfw_validation.run.apply(lambda run: run.split(",")[0])
plt.figure(figsize=(16, 6))
plt.subplot(1, 2, 1)
sns.lineplot(data=dfw_validation, x="step", y="epoch_accuracy",
hue=optimizer_validation).set_title("accuracy")
plt.subplot(1, 2, 2)
sns.lineplot(data=dfw_validation, x="step", y="epoch_loss",
hue=optimizer_validation).set_title("loss")
Text(0.5, 1.0, 'loss')
На графиках выше показаны временные рамки точности валидации и потери валидации. Каждая кривая показывает среднее значение по 5 прогонам для определенного типа оптимизатора. Благодаря встроенной функции seaborn.lineplot()
каждая кривая также отображает ± 1 стандартное отклонение от среднего, что дает нам четкое представление об изменчивости этих кривых и значимости различий между тремя типами оптимизаторов. Эта визуализация изменчивости еще не поддерживается в графическом интерфейсе TensorBoard.
Мы хотим изучить гипотезу о том, что минимальные потери при проверке значительно различаются между оптимизаторами «adam», «rmsprop» и «sgd». Итак, мы извлекаем DataFrame для минимальной потери валидации для каждого из оптимизаторов.
Затем мы делаем коробчатую диаграмму, чтобы визуализировать разницу в минимальных потерях при проверке.
adam_min_val_loss = dfw_validation.loc[optimizer_validation=="adam", :].groupby(
"run", as_index=False).agg({"epoch_loss": "min"})
rmsprop_min_val_loss = dfw_validation.loc[optimizer_validation=="rmsprop", :].groupby(
"run", as_index=False).agg({"epoch_loss": "min"})
sgd_min_val_loss = dfw_validation.loc[optimizer_validation=="sgd", :].groupby(
"run", as_index=False).agg({"epoch_loss": "min"})
min_val_loss = pd.concat([adam_min_val_loss, rmsprop_min_val_loss, sgd_min_val_loss])
sns.boxplot(data=min_val_loss, y="epoch_loss",
x=min_val_loss.run.apply(lambda run: run.split(",")[0]))
<matplotlib.axes._subplots.AxesSubplot at 0x7f5e017c8150>
# Perform pairwise comparisons between the minimum validation losses
# from the three optimizers.
_, p_adam_vs_rmsprop = stats.ttest_ind(
adam_min_val_loss["epoch_loss"],
rmsprop_min_val_loss["epoch_loss"])
_, p_adam_vs_sgd = stats.ttest_ind(
adam_min_val_loss["epoch_loss"],
sgd_min_val_loss["epoch_loss"])
_, p_rmsprop_vs_sgd = stats.ttest_ind(
rmsprop_min_val_loss["epoch_loss"],
sgd_min_val_loss["epoch_loss"])
print("adam vs. rmsprop: p = %.4f" % p_adam_vs_rmsprop)
print("adam vs. sgd: p = %.4f" % p_adam_vs_sgd)
print("rmsprop vs. sgd: p = %.4f" % p_rmsprop_vs_sgd)
adam vs. rmsprop: p = 0.0244 adam vs. sgd: p = 0.9749 rmsprop vs. sgd: p = 0.0135
Следовательно, при уровне значимости 0,05 наш анализ подтверждает нашу гипотезу о том, что минимальные потери при проверке значительно выше (т. Е. Хуже) в оптимизаторе среднеквадратичного отклонения по сравнению с двумя другими оптимизаторами, включенными в наш эксперимент.
Таким образом, в этом руководстве представлен пример того, как получить доступ к скалярным данным как panda.DataFrame
из TensorBoard.dev. Он демонстрирует гибкий и мощный анализ и визуализацию, которые вы можете выполнять с помощью DataFrame
.