Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/es-419/tensorboard/scalars_and_keras.ipynb
25115 views
Kernel: Python 3
#@title Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License.

Escalares de TensorBoard: Registro de métricas de entrenamiento en Keras

Descripción general

El aprendizaje automático implica invariablemente comprender métricas clave como la pérdida y cómo cambian conforme avanza el entrenamiento. Estas métricas pueden ayudarle a entender si está sobreajustando, por ejemplo, o si está entrenando innecesariamente durante demasiado tiempo. Es posible que desee comparar estas métricas entre diferentes ejecuciones de entrenamiento para ayudar a depurar y mejorar su modelo.

El Panel de series temporales de TensorBoard le permite visualizar estas métricas utilizando una API sencilla con muy poco esfuerzo. Este tutorial presenta ejemplos muy básicos para ayudarle a aprender a utilizar estas API con TensorBoard cuando desarrolle su modelo en Keras. Aprenderá a utilizar la retrollamada de TensorBoard para Keras y las API de resumen de TensorFlow para visualizar escalares predeterminados y personalizados.

Preparación

# Load the TensorBoard notebook extension. %load_ext tensorboard
from datetime import datetime from packaging import version import tensorflow as tf from tensorflow import keras import numpy as np print("TensorFlow version: ", tf.__version__) assert version.parse(tf.__version__).release[0] >= 2, \ "This notebook requires TensorFlow 2.0 or above."
TensorFlow version: 2.8.2
# Clear any logs from previous runs !rm -rf ./logs/

Preparar los datos para una regresión simple

Ahora va a utilizar Keras para calcular una regresión, es decir, encontrar la mejor línea de ajuste para un conjunto de datos emparejados. (Aunque utilizar redes neuronales y el descenso de gradiente es excesivo para este tipo de problema, resulta un ejemplo muy fácil de comprender).

Usted va a utilizar TensorBoard para observar cómo el entrenamiento y la prueba pérdida cambian a través de las épocas. Con suerte, verá que las pérdidas en el entrenamiento y en la prueba disminuyen con el tiempo y después permanecen estables.

En primer lugar, genere 1000 puntos de datos aproximadamente a lo largo de la línea y = 0,5x + 2. Divida estos puntos de datos en conjuntos de entrenamiento y de prueba. Su esperanza es que la red neuronal aprenda esta relación.

data_size = 1000 # 80% of the data is for training. train_pct = 0.8 train_size = int(data_size * train_pct) # Create some input data between -1 and 1 and randomize it. x = np.linspace(-1, 1, data_size) np.random.shuffle(x) # Generate the output data. # y = 0.5x + 2 + noise y = 0.5 * x + 2 + np.random.normal(0, 0.05, (data_size, )) # Split into test and train pairs. x_train, y_train = x[:train_size], y[:train_size] x_test, y_test = x[train_size:], y[train_size:]

Entrenamiento del modelo y registro de las pérdidas

Ya está listo para definir, entrenar y evaluar su modelo.

Para registrar la pérdida escalar mientras entrena, hará lo siguiente:

  1. Crear la retrollamada de TensorBoard para Keras

  2. Especifique un directorio de registro

  3. Pase la retrollamada de TensorBoard a Model.fit() de Keras.

TensorBoard lee los datos de registro de la jerarquía de directorios de registro. En este bloc de notas, el directorio raíz de registro es logs/scalars, al que se le añade un subdirectorio con marca de tiempo. El subdirectorio con marca de tiempo le permite identificar y seleccionar fácilmente las ejecuciones de entrenamiento conforme utiliza TensorBoard e itera sobre su modelo.

logdir = "logs/scalars/" + datetime.now().strftime("%Y%m%d-%H%M%S") tensorboard_callback = keras.callbacks.TensorBoard(log_dir=logdir) model = keras.models.Sequential([ keras.layers.Dense(16, input_dim=1), keras.layers.Dense(1), ]) model.compile( loss='mse', # keras.losses.mean_squared_error optimizer=keras.optimizers.SGD(learning_rate=0.2), ) print("Training ... With default parameters, this takes less than 10 seconds.") training_history = model.fit( x_train, # input y_train, # output batch_size=train_size, verbose=0, # Suppress chatty output; use Tensorboard instead epochs=100, validation_data=(x_test, y_test), callbacks=[tensorboard_callback], ) print("Average test loss: ", np.average(training_history.history['loss']))
Training ... With default parameters, this takes less than 10 seconds. Average test loss: 0.042797307365108284

Examinar la pérdida mediante TensorBoard

Ahora, inicie TensorBoard, y especifique el directorio raíz de registro que utilizó anteriormente.

Espere unos segundos a que la interfaz de usuario de TensorBoard se ponga en marcha.

%tensorboard --logdir logs/scalars

Es posible que vea que TensorBoard muestra el mensaje "No hay cuadros de mando activos para el conjunto de datos actual". Esto se debe a que los datos de registro iniciales aún no se han guardado. Conforme avance el entrenamiento, el modelo de Keras empezará a registrar datos. TensorBoard se actualizará periódicamente y le mostrará sus métricas escalares. Si está impaciente, puede tocar la flecha Actualizar situada en la parte superior derecha.

A medida que observa el progreso del entrenamiento, observe cómo tanto la pérdida de entrenamiento como la de validación disminuyen rápidamente y después permanecen estables. De hecho, podría haber dejado de entrenar después de 25 épocas, porque el entrenamiento no mejoró mucho después de ese punto.

Pase el ratón por encima del gráfico para ver puntos de datos específicos. También puede intentar ampliarlos con el ratón o seleccionar parte de ellos para ver más detalles.

Observe el selector "Corridas" situado a la izquierda. Una "corrida" representa un conjunto de registros de una ronda de entrenamiento, en este caso el resultado de Model.fit(). Los desarrolladores normalmente tienen muchas, muchas corridas, ya que experimentan y desarrollan su modelo a lo largo del tiempo.

Utilice el selector de ejecuciones para elegir ejecuciones específicas, o elija entre sólo entrenamiento o validación. Comparar las ejecuciones le ayudará a evaluar qué versión de su código está resolviendo mejor su problema.

Bien, el gráfico de pérdidas de TensorBoard demuestra que la pérdida disminuyó consistentemente tanto para el entrenamiento como para la validación y después se estabilizó. ¡Eso significa que las métricas del modelo son probablemente muy buenas! Ahora veamos cómo se comporta realmente el modelo en la vida real.

Con los datos de entrada (60, 25, 2), la recta y = 0,5x + 2 debería dar (32, 14,5, 3). ¿Está de acuerdo el modelo?

print(model.predict([60, 25, 2])) # True values to compare predictions against: # [[32.0] # [14.5] # [ 3.0]]
[[32.148884 ] [14.562463 ] [ 3.0056725]]

¡No está nada mal!

Registro de escalares personalizados

¿Y si desea registrar valores personalizados, como una tasa de aprendizaje dinámico? Para ello, debe utilizar la API de resumen de TensorFlow.

Vuelva a entrenar el modelo de regresión y registre una tasa de aprendizaje personalizada. A continuación le explicamos como hacerlo:

  1. Cree un escritor de archivos, utilizando tf.summary.create_file_writer().

  2. Defina una función de tasa de aprendizaje personalizada. Esto se pasará a la retrollamada de Keras LearningRateScheduler.

  3. Dentro de la función de la tasa de aprendizaje, utilice tf.summary.scalar() para registrar la tasa de aprendizaje personalizada.

  4. Pase la retrollamada de LearningRateScheduler a Model.fit().

En general, para registrar un escalar personalizado, necesita utilizar tf.summary.scalar() con un escritor de archivos. El escritor de archivos es responsable de escribir los datos de esta ejecución en el directorio especificado y se utiliza implícitamente cuando se recurre al tf.summary.scalar().

logdir = "logs/scalars/" + datetime.now().strftime("%Y%m%d-%H%M%S") file_writer = tf.summary.create_file_writer(logdir + "/metrics") file_writer.set_as_default() def lr_schedule(epoch): """ Returns a custom learning rate that decreases as epochs progress. """ learning_rate = 0.2 if epoch > 10: learning_rate = 0.02 if epoch > 20: learning_rate = 0.01 if epoch > 50: learning_rate = 0.005 tf.summary.scalar('learning rate', data=learning_rate, step=epoch) return learning_rate lr_callback = keras.callbacks.LearningRateScheduler(lr_schedule) tensorboard_callback = keras.callbacks.TensorBoard(log_dir=logdir) model = keras.models.Sequential([ keras.layers.Dense(16, input_dim=1), keras.layers.Dense(1), ]) model.compile( loss='mse', # keras.losses.mean_squared_error optimizer=keras.optimizers.SGD(), ) training_history = model.fit( x_train, # input y_train, # output batch_size=train_size, verbose=0, # Suppress chatty output; use Tensorboard instead epochs=100, validation_data=(x_test, y_test), callbacks=[tensorboard_callback, lr_callback], )

Echemos un vistazo de nuevo a TensorBoard.

%tensorboard --logdir logs/scalars

Utilizando el selector "Corridas" de la izquierda, observe que tiene una corrida <timestamp>/metrics. Al seleccionar esta ejecución aparece un gráfico de "tasa de aprendizaje" que le permite verificar la progresión de la tasa de aprendizaje durante esta ejecución.

También puede comparar las curvas de pérdidas de entrenamiento y validación de esta ejecución con sus ejecuciones anteriores. También puede notar que la programación de la tasa de aprendizaje devolvió valores discretos, dependiendo de la época, pero el gráfico de la tasa de aprendizaje puede parecer liso. TensorBoard tiene un parámetro de alisamiento que quizás tenga que bajar a cero para ver los valores no alisados.

¿Cómo funciona este modelo?

print(model.predict([60, 25, 2])) # True values to compare predictions against: # [[32.0] # [14.5] # [ 3.0]]
[[31.958094 ] [14.482997 ] [ 2.9993598]]

Registro a nivel de lote

Primero carguemos el conjunto de datos MNIST, normalicemos los datos y escribamos una función que cree un modelo sencillo de Keras para clasificar las imágenes en 10 clases.

mnist = tf.keras.datasets.mnist (x_train, y_train),(x_test, y_test) = mnist.load_data() x_train, x_test = x_train / 255.0, x_test / 255.0 def create_model(): return tf.keras.models.Sequential([ tf.keras.layers.Flatten(input_shape=(28, 28)), tf.keras.layers.Dense(512, activation='relu'), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(10, activation='softmax') ])
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz 11493376/11490434 [==============================] - 0s 0us/step 11501568/11490434 [==============================] - 0s 0us/step

Registro instantáneo a nivel de lote

El registro instantáneo de las métricas a nivel de lote puede mostrarnos el nivel de fluctuación entre lotes durante el entrenamiento en cada época, lo que puede ser útil para la depuración.

Configuración de un escritor de resúmenes en un directorio de registro diferente:

log_dir = 'logs/batch_level/' + datetime.now().strftime("%Y%m%d-%H%M%S") + '/train' train_writer = tf.summary.create_file_writer(log_dir)

Para habilitar el registro por lotes, se deben definir métricas tf.summary personalizadas anulando train_step() en la definición de clase del Modelo y encerrarlas en un contexto de escritor de resúmenes. Esto puede hacerse simplemente combinando en definiciones de Modelo subclase o puede extenderse para editar nuestro anterior Modelo API Funcional, como se muestra a continuación:

class MyModel(tf.keras.Model): def __init__(self, model): super().__init__() self.model = model def train_step(self, data): x, y = data with tf.GradientTape() as tape: y_pred = self.model(x, training=True) loss = self.compiled_loss(y, y_pred) mse = tf.keras.losses.mean_squared_error(y, K.max(y_pred, axis=-1)) self.optimizer.minimize(loss, self.trainable_variables, tape=tape) with train_writer.as_default(step=self._train_counter): tf.summary.scalar('batch_loss', loss) tf.summary.scalar('batch_mse', mse) return self.compute_metrics(x, y, y_pred, None) def call(self, x): x = self.model(x) return x # Adds custom batch-level metrics to our previous Functional API model model = MyModel(create_model()) model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

Defina nuestra retrollamada TensorBoard para registrar tanto las métricas a nivel de época como a nivel de lote en nuestro directorio de registro y llame a model.fit() con nuestro batch_size seleccionado:

tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir) model.fit(x=x_train, y=y_train, epochs=5, batch_size=500, validation_data=(x_test, y_test), callbacks=[tensorboard_callback])
Epoch 1/5 120/120 [==============================] - 5s 36ms/step - loss: 0.4379 - accuracy: 0.8788 - val_loss: 0.2041 - val_accuracy: 0.9430 Epoch 2/5 120/120 [==============================] - 4s 31ms/step - loss: 0.1875 - accuracy: 0.9471 - val_loss: 0.1462 - val_accuracy: 0.9591 Epoch 3/5 120/120 [==============================] - 3s 27ms/step - loss: 0.1355 - accuracy: 0.9613 - val_loss: 0.1170 - val_accuracy: 0.9670 Epoch 4/5 120/120 [==============================] - 3s 27ms/step - loss: 0.1058 - accuracy: 0.9694 - val_loss: 0.0954 - val_accuracy: 0.9723 Epoch 5/5 120/120 [==============================] - 3s 27ms/step - loss: 0.0872 - accuracy: 0.9752 - val_loss: 0.0843 - val_accuracy: 0.9749
<keras.callbacks.History at 0x7fce165a2fd0>

Abra TensorBoard con el nuevo directorio de registro y vea tanto las métricas a nivel de época como a nivel de lote:

%tensorboard --logdir logs/batch_level

Registro acumulativo a nivel de lote

El registro a nivel de lote también puede implementarse de forma acumulativa, promediando las métricas de cada lote con las de los lotes anteriores y dando como resultado una curva de entrenamiento más suave al registrar las métricas a nivel de lote.

Configuración de un escritor de resúmenes en un directorio de registro diferente:

log_dir = 'logs/batch_avg/' + datetime.now().strftime("%Y%m%d-%H%M%S") + '/train' train_writer = tf.summary.create_file_writer(log_dir)

Cree métricas de estado que puedan registrarse por lote:

batch_loss = tf.keras.metrics.Mean('batch_loss', dtype=tf.float32) batch_accuracy = tf.keras.metrics.SparseCategoricalAccuracy('batch_accuracy')

Como en el caso anterior, incorpore las métricas personalizadas tf.summary en el método anulado train_step. Para que el registro a nivel de lote sea acumulativo, utilice las métricas de estado que definimos para calcular el resultado acumulativo teniendo en cuenta los datos de cada paso del entrenamiento.

class MyModel(tf.keras.Model): def __init__(self, model): super().__init__() self.model = model def train_step(self, data): x, y = data with tf.GradientTape() as tape: y_pred = self.model(x, training=True) loss = self.compiled_loss(y, y_pred) self.optimizer.minimize(loss, self.trainable_variables, tape=tape) batch_loss(loss) batch_accuracy(y, y_pred) with train_writer.as_default(step=self._train_counter): tf.summary.scalar('batch_loss', batch_loss.result()) tf.summary.scalar('batch_accuracy', batch_accuracy.result()) return self.compute_metrics(x, y, y_pred, None) def call(self, x): x = self.model(x) return x # Adds custom batch-level metrics to our previous Functional API model model = MyModel(create_model()) model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

Como ya hicimos antes, definimos nuestra retrollamada de TensorBoard y llamamos a model.fit() con nuestro batch_size seleccionado:

tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir) model.fit(x=x_train, y=y_train, epochs=5, batch_size=500, validation_data=(x_test, y_test), callbacks=[tensorboard_callback])
Epoch 1/5 120/120 [==============================] - 4s 27ms/step - loss: 0.4266 - accuracy: 0.8813 - val_loss: 0.2055 - val_accuracy: 0.9415 Epoch 2/5 120/120 [==============================] - 3s 26ms/step - loss: 0.1864 - accuracy: 0.9476 - val_loss: 0.1417 - val_accuracy: 0.9613 Epoch 3/5 120/120 [==============================] - 3s 27ms/step - loss: 0.1352 - accuracy: 0.9614 - val_loss: 0.1148 - val_accuracy: 0.9665 Epoch 4/5 120/120 [==============================] - 3s 26ms/step - loss: 0.1066 - accuracy: 0.9702 - val_loss: 0.0932 - val_accuracy: 0.9716 Epoch 5/5 120/120 [==============================] - 3s 27ms/step - loss: 0.0859 - accuracy: 0.9749 - val_loss: 0.0844 - val_accuracy: 0.9754
<keras.callbacks.History at 0x7fce15c39f50>

Abra TensorBoard con el nuevo directorio de registro y vea tanto las métricas a nivel de época como a nivel de lote:

%tensorboard --logdir logs/batch_avg

Eso es todo. Ahora ya sabe cómo crear métricas de entrenamiento personalizadas en TensorBoard para una amplia variedad de casos de uso.