¿Qué es TensorBoard?
TensorBoard es la herramienta de visualización oficial del ecosistema TensorFlow. Permite monitorizar en tiempo real el proceso de entrenamiento y depurar modelos de deep learning a través de una interfaz web.
Sus funcionalidades principales incluyen:
- Scalars: curvas de pérdida, métricas por época/paso.
- Graphs: grafo computacional del modelo.
- Histograms: distribución de pesos y sesgos a lo largo del tiempo.
- Images: visualización de imágenes de entrada o activaciones.
- Projector: visualización de embeddings en 2D/3D (PCA, t-SNE).
- Profile: análisis de rendimiento en CPU/GPU.
Configuración básica con el callback Keras
La forma más sencilla de integrar TensorBoard es usando el callback TensorBoard en model.fit():
import tensorflow as tf
import numpy as np
import datetime
# Datos de ejemplo
(X_train, y_train), (X_test, y_test) = tf.keras.datasets.mnist.load_data()
X_train = X_train / 255.0
X_test = X_test / 255.0
# Modelo
modelo = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation='softmax')
])
modelo.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
# Directorio de logs con timestamp (evita sobreescribir experimentos anteriores)
log_dir = "logs/fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
# Callback TensorBoard
tensorboard_callback = tf.keras.callbacks.TensorBoard(
log_dir=log_dir,
histogram_freq=1, # registrar histogramas de pesos cada N épocas (0 = desactivado)
write_graph=True, # guardar el grafo del modelo
write_images=True, # guardar imágenes de los pesos
update_freq='epoch', # 'epoch', 'batch' o número de batches
profile_batch=0 # desactivar profiling (o '2,5' para perfilar batches 2-5)
)
historial = modelo.fit(
X_train, y_train,
epochs=5,
validation_data=(X_test, y_test),
callbacks=[tensorboard_callback]
)
print(f"Logs guardados en: {log_dir}")
print(f"Para ver TensorBoard ejecuta: tensorboard --logdir logs/fit")
Lanzar TensorBoard desde terminal:
tensorboard --logdir logs/fit
O directamente desde Jupyter/Colab:
# En Jupyter Notebook o Google Colab
%load_ext tensorboard
%tensorboard --logdir logs/fit
Registrar scalars personalizados con tf.summary
Para registrar métricas adicionales durante el entrenamiento:
import tensorflow as tf
import numpy as np
# Crear un writer de sumarios
log_dir_custom = "logs/custom"
writer = tf.summary.create_file_writer(log_dir_custom)
# Registrar métricas personalizadas
for epoca in range(10):
perdida_simulada = 1.0 / (epoca + 1)
precision_simulada = 1 - perdida_simulada * 0.5
lr_simulado = 0.001 * (0.9 ** epoca)
with writer.as_default():
tf.summary.scalar('perdida/entrenamiento', perdida_simulada, step=epoca)
tf.summary.scalar('precision/entrenamiento', precision_simulada, step=epoca)
tf.summary.scalar('hiperparametros/learning_rate', lr_simulado, step=epoca)
writer.flush()
print(f"Sumarios guardados en {log_dir_custom}")
Registrar imágenes en TensorBoard
Útil para visualizar muestras del dataset o predicciones durante el entrenamiento:
import tensorflow as tf
import numpy as np
(X_train, y_train), _ = tf.keras.datasets.mnist.load_data()
X_train = X_train / 255.0
log_dir_imagenes = "logs/imagenes"
writer_img = tf.summary.create_file_writer(log_dir_imagenes)
# Tomar una muestra de imágenes
muestra = X_train[:25]
# TensorBoard espera shape (n, h, w, c)
muestra_4d = muestra[..., tf.newaxis] # (25, 28, 28, 1)
with writer_img.as_default():
tf.summary.image(
"Muestras MNIST",
muestra_4d,
max_outputs=25,
step=0
)
writer_img.flush()
print("Imágenes registradas.")
Registrar histogramas de pesos
import tensorflow as tf
import numpy as np
log_dir_hist = "logs/histogramas"
writer_hist = tf.summary.create_file_writer(log_dir_hist)
# Simular evolución de pesos
for paso in range(50):
pesos_simulados = np.random.normal(loc=0, scale=1.0/(paso+1), size=(128, 64))
with writer_hist.as_default():
tf.summary.histogram("capas/dense_1/kernel", pesos_simulados, step=paso)
writer_hist.flush()
print("Histogramas registrados.")
TensorBoard en bucles de entrenamiento personalizados
import tensorflow as tf
import numpy as np
# Datos
(X_train, y_train), (X_val, y_val) = tf.keras.datasets.mnist.load_data()
X_train = X_train.reshape(-1, 784).astype('float32') / 255.0
X_val = X_val.reshape(-1, 784).astype('float32') / 255.0
train_ds = tf.data.Dataset.from_tensor_slices((X_train, y_train)).batch(256)
val_ds = tf.data.Dataset.from_tensor_slices((X_val, y_val)).batch(256)
# Modelo
modelo = tf.keras.Sequential([
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax')
])
optimizer = tf.keras.optimizers.Adam(0.001)
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy()
train_loss_metric = tf.keras.metrics.Mean(name='perdida_train')
train_acc_metric = tf.keras.metrics.SparseCategoricalAccuracy(name='acc_train')
val_loss_metric = tf.keras.metrics.Mean(name='perdida_val')
val_acc_metric = tf.keras.metrics.SparseCategoricalAccuracy(name='acc_val')
# Writers separados para train y validación (aparecen en mismo gráfico)
train_writer = tf.summary.create_file_writer("logs/custom_loop/train")
val_writer = tf.summary.create_file_writer("logs/custom_loop/val")
EPOCHS = 5
for epoca in range(EPOCHS):
# Entrenamiento
for X_batch, y_batch in train_ds:
with tf.GradientTape() as tape:
predicciones = modelo(X_batch, training=True)
loss = loss_fn(y_batch, predicciones)
gradientes = tape.gradient(loss, modelo.trainable_variables)
optimizer.apply_gradients(zip(gradientes, modelo.trainable_variables))
train_loss_metric.update_state(loss)
train_acc_metric.update_state(y_batch, predicciones)
# Validación
for X_val_batch, y_val_batch in val_ds:
val_preds = modelo(X_val_batch, training=False)
val_loss = loss_fn(y_val_batch, val_preds)
val_loss_metric.update_state(val_loss)
val_acc_metric.update_state(y_val_batch, val_preds)
# Registrar en TensorBoard
with train_writer.as_default():
tf.summary.scalar('loss', train_loss_metric.result(), step=epoca)
tf.summary.scalar('accuracy', train_acc_metric.result(), step=epoca)
with val_writer.as_default():
tf.summary.scalar('loss', val_loss_metric.result(), step=epoca)
tf.summary.scalar('accuracy', val_acc_metric.result(), step=epoca)
print(f"Época {epoca+1}/{EPOCHS} | "
f"Train Loss: {train_loss_metric.result():.4f}, Acc: {train_acc_metric.result():.4f} | "
f"Val Loss: {val_loss_metric.result():.4f}, Acc: {val_acc_metric.result():.4f}")
# Resetear métricas al final de cada época
train_loss_metric.reset_state()
train_acc_metric.reset_state()
val_loss_metric.reset_state()
val_acc_metric.reset_state()
train_writer.flush()
val_writer.flush()
print("\nEntrenamiento completado. Ejecuta: tensorboard --logdir logs/custom_loop")
Comparar experimentos en TensorBoard
Una de las funcionalidades más valiosas de TensorBoard es la comparación de experimentos. Basta con guardar los logs en subdirectorios distintos:
import tensorflow as tf
import numpy as np
(X, y), _ = tf.keras.datasets.mnist.load_data()
X = X / 255.0
def entrenar_experimento(lr, dropout, nombre):
log_dir = f"logs/experimentos/{nombre}"
modelo = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(dropout),
tf.keras.layers.Dense(10, activation='softmax')
])
modelo.compile(
optimizer=tf.keras.optimizers.Adam(lr),
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
cb = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=0)
modelo.fit(X, y, epochs=3, validation_split=0.1, callbacks=[cb], verbose=0)
print(f"Experimento '{nombre}' completado. Logs en {log_dir}")
entrenar_experimento(lr=0.001, dropout=0.2, nombre="lr001_drop02")
entrenar_experimento(lr=0.01, dropout=0.2, nombre="lr01_drop02")
entrenar_experimento(lr=0.001, dropout=0.5, nombre="lr001_drop05")
print("\nComparar en TensorBoard: tensorboard --logdir logs/experimentos")
Alan Sastre
Ingeniero de Software y formador, CEO en CertiDevs
Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, TensorFlow es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.
Más tutoriales de TensorFlow
Explora más contenido relacionado con TensorFlow y continúa aprendiendo con nuestros tutoriales gratuitos.
Aprendizajes de esta lección
Configurar el callback TensorBoard en el entrenamiento con Keras. Visualizar curvas de pérdida y métricas en tiempo real. Explorar el grafo del modelo en TensorBoard. Registrar imágenes, histogramas y datos escalares personalizados. Usar tf.summary para escribir datos desde bucles de entrenamiento personalizados.