tensorflow - guide - Tensorboard keras: trama del tren y escalas de validación en una misma figura.
tensorflow guide (1)
Para manejar los registros de validación con un escritor independiente, puede escribir una devolución de llamada personalizada que se TensorBoard
métodos originales de TensorBoard
.
import os
import tensorflow as tf
from keras.callbacks import TensorBoard
class TrainValTensorBoard(TensorBoard):
def __init__(self, log_dir=''./logs'', **kwargs):
# Make the original `TensorBoard` log to a subdirectory ''training''
training_log_dir = os.path.join(log_dir, ''training'')
super(TrainValTensorBoard, self).__init__(training_log_dir, **kwargs)
# Log the validation metrics to a separate subdirectory
self.val_log_dir = os.path.join(log_dir, ''validation'')
def set_model(self, model):
# Setup writer for validation metrics
self.val_writer = tf.summary.FileWriter(self.val_log_dir)
super(TrainValTensorBoard, self).set_model(model)
def on_epoch_end(self, epoch, logs=None):
# Pop the validation logs and handle them separately with
# `self.val_writer`. Also rename the keys so that they can
# be plotted on the same figure with the training metrics
logs = logs or {}
val_logs = {k.replace(''val_'', ''''): v for k, v in logs.items() if k.startswith(''val_'')}
for name, value in val_logs.items():
summary = tf.Summary()
summary_value = summary.value.add()
summary_value.simple_value = value.item()
summary_value.tag = name
self.val_writer.add_summary(summary, epoch)
self.val_writer.flush()
# Pass the remaining logs to `TensorBoard.on_epoch_end`
logs = {k: v for k, v in logs.items() if not k.startswith(''val_'')}
super(TrainValTensorBoard, self).on_epoch_end(epoch, logs)
def on_train_end(self, logs=None):
super(TrainValTensorBoard, self).on_train_end(logs)
self.val_writer.close()
- En
__init__
, se configuran dos subdirectorios para los registros de capacitación y validación - En
set_model
, un escritorself.val_writer
se crea para los registros de validación - En
on_epoch_end
, los registros de validación se separan de los registros de entrenamiento y se escriben en un archivo conself.val_writer
Usando el conjunto de datos MNIST como ejemplo:
from keras.models import Sequential
from keras.layers import Dense
from keras.datasets import mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(60000, 784)
x_test = x_test.reshape(10000, 784)
x_train = x_train.astype(''float32'')
x_test = x_test.astype(''float32'')
x_train /= 255
x_test /= 255
model = Sequential()
model.add(Dense(64, activation=''relu'', input_shape=(784,)))
model.add(Dense(10, activation=''softmax''))
model.compile(loss=''sparse_categorical_crossentropy'', optimizer=''adam'', metrics=[''accuracy''])
model.fit(x_train, y_train, epochs=10,
validation_data=(x_test, y_test),
callbacks=[TrainValTensorBoard(write_graph=False)])
A continuación, puede visualizar las dos curvas en una misma figura en TensorBoard.
EDITAR: He modificado un poco la clase para que pueda usarse con una ejecución impaciente.
El mayor cambio es que uso tf.keras
en el siguiente código. Parece que la devolución de llamada TensorBoard
en Keras independiente aún no admite el modo ávido.
import os
import tensorflow as tf
from tensorflow.keras.callbacks import TensorBoard
from tensorflow.python.eager import context
class TrainValTensorBoard(TensorBoard):
def __init__(self, log_dir=''./logs'', **kwargs):
self.val_log_dir = os.path.join(log_dir, ''validation'')
training_log_dir = os.path.join(log_dir, ''training'')
super(TrainValTensorBoard, self).__init__(training_log_dir, **kwargs)
def set_model(self, model):
if context.executing_eagerly():
self.val_writer = tf.contrib.summary.create_file_writer(self.val_log_dir)
else:
self.val_writer = tf.summary.FileWriter(self.val_log_dir)
super(TrainValTensorBoard, self).set_model(model)
def _write_custom_summaries(self, step, logs=None):
logs = logs or {}
val_logs = {k.replace(''val_'', ''''): v for k, v in logs.items() if ''val_'' in k}
if context.executing_eagerly():
with self.val_writer.as_default(), tf.contrib.summary.always_record_summaries():
for name, value in val_logs.items():
tf.contrib.summary.scalar(name, value.item(), step=step)
else:
for name, value in val_logs.items():
summary = tf.Summary()
summary_value = summary.value.add()
summary_value.simple_value = value.item()
summary_value.tag = name
self.val_writer.add_summary(summary, step)
self.val_writer.flush()
logs = {k: v for k, v in logs.items() if not ''val_'' in k}
super(TrainValTensorBoard, self)._write_custom_summaries(step, logs)
def on_train_end(self, logs=None):
super(TrainValTensorBoard, self).on_train_end(logs)
self.val_writer.close()
La idea es la misma.
- Compruebe el código fuente de la devolución de llamada
TensorBoard
- Vea lo que hace para configurar el escritor
- Haz lo mismo en este callback personalizado.
Una vez más, puede utilizar los datos MNIST para probarlo,
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.train import AdamOptimizer
tf.enable_eager_execution()
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(60000, 784)
x_test = x_test.reshape(10000, 784)
x_train = x_train.astype(''float32'')
x_test = x_test.astype(''float32'')
x_train /= 255
x_test /= 255
y_train = y_train.astype(int)
y_test = y_test.astype(int)
model = Sequential()
model.add(Dense(64, activation=''relu'', input_shape=(784,)))
model.add(Dense(10, activation=''softmax''))
model.compile(loss=''sparse_categorical_crossentropy'', optimizer=AdamOptimizer(), metrics=[''accuracy''])
model.fit(x_train, y_train, epochs=10,
validation_data=(x_test, y_test),
callbacks=[TrainValTensorBoard(write_graph=False)])
Así que estoy usando tensorboard dentro de keras. En tensorflow, se podrían usar dos redactores de resumen diferentes para escalas de tren y validación, de modo que el tablero de tensor podría trazarlos en una misma figura. Algo así como la figura en.
TensorBoard - ¿Se representan pérdidas de entrenamiento y validación en el mismo gráfico?
¿Hay alguna manera de hacer esto en keras?
Gracias.