Ayuda a proteger la Gran Barrera de Coral con TensorFlow en Kaggle Únete Challenge

Entrenamiento de modelos de Keras con TensorFlow Cloud

Ver en TensorFlow.org Ejecutar en Google Colab Ver fuente en GitHub Descargar cuaderno

Introducción

TensorFlow la nube es un paquete de Python que proporciona APIs para una transición fluida de la depuración local a la formación distribuida en la nube de Google. Simplifica el proceso de entrenamiento de modelos de TensorFlow en la nube en una única llamada de función simple, que requiere una configuración mínima y sin cambios en su modelo. TensorFlow Cloud maneja tareas específicas de la nube, como crear instancias de VM y estrategias de distribución para sus modelos de forma automática. Esta guía demostrará cómo interactuar con Google Cloud a través de TensorFlow Cloud y la amplia gama de funciones proporcionadas dentro de TensorFlow Cloud. Comenzaremos con el caso de uso más simple.

Configuración

Comenzaremos instalando TensorFlow Cloud e importando los paquetes que necesitaremos en esta guía.

pip install -q tensorflow_cloud
import tensorflow as tf
import tensorflow_cloud as tfc

from tensorflow import keras
from tensorflow.keras import layers
2021-07-27 22:07:16.348453: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudart.so.11.0

Descripción general de la API: un primer ejemplo de extremo a extremo

Comencemos con un script de entrenamiento del modelo Keras, como el siguiente CNN:

(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

model = keras.Sequential(
    [
        keras.Input(shape=(28, 28)),
        # Use a Rescaling layer to make sure input values are in the [0, 1] range.
        layers.experimental.preprocessing.Rescaling(1.0 / 255),
        # The original images have shape (28, 28), so we reshape them to (28, 28, 1)
        layers.Reshape(target_shape=(28, 28, 1)),
        # Follow-up with a classic small convnet
        layers.Conv2D(32, 3, activation="relu"),
        layers.MaxPooling2D(2),
        layers.Conv2D(32, 3, activation="relu"),
        layers.MaxPooling2D(2),
        layers.Conv2D(32, 3, activation="relu"),
        layers.Flatten(),
        layers.Dense(128, activation="relu"),
        layers.Dense(10),
    ]
)

model.compile(
    optimizer=keras.optimizers.Adam(),
    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics=keras.metrics.SparseCategoricalAccuracy(),
)

model.fit(x_train, y_train, epochs=20, batch_size=128, validation_split=0.1)

Para formar este modelo en la nube de Google sólo tenemos que añadir una llamada a run() al comienzo de la secuencia de comandos, antes de que las importaciones:

tfc.run()

No necesita preocuparse por tareas específicas de la nube, como crear instancias de VM y estrategias de distribución cuando usa TensorFlow Cloud. La API incluye valores predeterminados inteligentes para todos los parámetros; todo es configurable, pero muchos modelos pueden confiar en estos valores predeterminados.

Al llamar a run() , TensorFlow nube:

  • Prepare su libreta o secuencia de comandos de Python para distribuirla.
  • Conviértalo en una imagen de Docker con las dependencias requeridas.
  • Ejecuta el trabajo de entrenamiento en una VM con GPU de GCP.
  • Transmita registros relevantes e información de trabajo.

La configuración de VM predeterminada es 1 jefe y 0 trabajadores con 8 núcleos de CPU y 1 GPU Tesla T4.

Configuración de la nube de Google

Para facilitar los caminos adecuados para la capacitación en la nube, deberá realizar una configuración inicial. Si es un nuevo usuario de Google Cloud, hay algunos pasos preliminares que deberá seguir:

  1. Crear un proyecto de GCP;
  2. habilitar los servicios de la plataforma AI;
  3. Crear una cuenta de servicio;
  4. Descargar una clave de autorización;
  5. Crea un depósito de Cloud Storage.

Las instrucciones detalladas de configuración por primera vez se pueden encontrar en el TensorFlow Nube README , y un ejemplo de configuración adicional se muestra en el Blog TensorFlow .

Flujos de trabajo comunes y almacenamiento en la nube

En la mayoría de los casos, querrá recuperar su modelo después de entrenar en Google Cloud. Para esto, es crucial redirigir el guardado y la carga a Cloud Storage mientras se entrena de forma remota. Podemos dirigir TensorFlow Cloud a nuestro depósito de Cloud Storage para una variedad de tareas. El depósito de almacenamiento se puede usar para guardar y cargar grandes conjuntos de datos de entrenamiento, almacenar registros de devolución de llamadas o pesos de modelos y guardar archivos de modelos entrenados. Para empezar, vamos a configurar fit() para guardar el modelo a un almacenamiento en la nube y la puesta en marcha TensorBoard seguimiento para seguir el progreso de entrenamiento.

def create_model():
    model = keras.Sequential(
        [
            keras.Input(shape=(28, 28)),
            layers.experimental.preprocessing.Rescaling(1.0 / 255),
            layers.Reshape(target_shape=(28, 28, 1)),
            layers.Conv2D(32, 3, activation="relu"),
            layers.MaxPooling2D(2),
            layers.Conv2D(32, 3, activation="relu"),
            layers.MaxPooling2D(2),
            layers.Conv2D(32, 3, activation="relu"),
            layers.Flatten(),
            layers.Dense(128, activation="relu"),
            layers.Dense(10),
        ]
    )

    model.compile(
        optimizer=keras.optimizers.Adam(),
        loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
        metrics=keras.metrics.SparseCategoricalAccuracy(),
    )
    return model

Guardemos los registros de TensorBoard y los puntos de control del modelo generados durante el entrenamiento en nuestro depósito de almacenamiento en la nube.

import datetime
import os

# Note: Please change the gcp_bucket to your bucket name.
gcp_bucket = "keras-examples"

checkpoint_path = os.path.join("gs://", gcp_bucket, "mnist_example", "save_at_{epoch}")

tensorboard_path = os.path.join(  # Timestamp included to enable timeseries graphs
    "gs://", gcp_bucket, "logs", datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
)

callbacks = [
    # TensorBoard will store logs for each epoch and graph performance for us.
    keras.callbacks.TensorBoard(log_dir=tensorboard_path, histogram_freq=1),
    # ModelCheckpoint will save models after each epoch for retrieval later.
    keras.callbacks.ModelCheckpoint(checkpoint_path),
    # EarlyStopping will terminate training when val_loss ceases to improve.
    keras.callbacks.EarlyStopping(monitor="val_loss", patience=3),
]

model = create_model()
2021-07-27 22:07:18.825259: I tensorflow/core/profiler/lib/profiler_session.cc:126] Profiler session initializing.
2021-07-27 22:07:18.825306: I tensorflow/core/profiler/lib/profiler_session.cc:141] Profiler session started.
2021-07-27 22:07:18.826514: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcuda.so.1
2021-07-27 22:07:19.524654: I tensorflow/core/profiler/internal/gpu/cupti_tracer.cc:1611] Profiler found 1 GPUs
2021-07-27 22:07:19.569799: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcupti.so.11.2
2021-07-27 22:07:19.574795: I tensorflow/core/profiler/lib/profiler_session.cc:159] Profiler session tear down.
2021-07-27 22:07:19.574958: I tensorflow/core/profiler/internal/gpu/cupti_tracer.cc:1743] CUPTI activity buffer flushed
2021-07-27 22:07:19.590994: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-07-27 22:07:19.592061: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1733] Found device 0 with properties: 
pciBusID: 0000:00:05.0 name: Tesla V100-SXM2-16GB computeCapability: 7.0
coreClock: 1.53GHz coreCount: 80 deviceMemorySize: 15.78GiB deviceMemoryBandwidth: 836.37GiB/s
2021-07-27 22:07:19.592100: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudart.so.11.0
2021-07-27 22:07:19.595897: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcublas.so.11
2021-07-27 22:07:19.595991: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcublasLt.so.11
2021-07-27 22:07:19.597230: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcufft.so.10
2021-07-27 22:07:19.597581: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcurand.so.10
2021-07-27 22:07:19.598756: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcusolver.so.11
2021-07-27 22:07:19.599746: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcusparse.so.11
2021-07-27 22:07:19.599930: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudnn.so.8
2021-07-27 22:07:19.600043: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-07-27 22:07:19.601088: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-07-27 22:07:19.602037: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1871] Adding visible gpu devices: 0
2021-07-27 22:07:19.602416: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 AVX512F FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2021-07-27 22:07:19.603033: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-07-27 22:07:19.604024: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1733] Found device 0 with properties: 
pciBusID: 0000:00:05.0 name: Tesla V100-SXM2-16GB computeCapability: 7.0
coreClock: 1.53GHz coreCount: 80 deviceMemorySize: 15.78GiB deviceMemoryBandwidth: 836.37GiB/s
2021-07-27 22:07:19.604096: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-07-27 22:07:19.605089: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-07-27 22:07:19.606005: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1871] Adding visible gpu devices: 0
2021-07-27 22:07:19.606052: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudart.so.11.0
2021-07-27 22:07:20.242028: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1258] Device interconnect StreamExecutor with strength 1 edge matrix:
2021-07-27 22:07:20.242067: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1264]      0 
2021-07-27 22:07:20.242076: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1277] 0:   N 
2021-07-27 22:07:20.242317: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-07-27 22:07:20.243478: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-07-27 22:07:20.244412: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-07-27 22:07:20.245277: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1418] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 14646 MB memory) -> physical GPU (device: 0, name: Tesla V100-SXM2-16GB, pci bus id: 0000:00:05.0, compute capability: 7.0)
WARNING:tensorflow:Please add `keras.layers.InputLayer` instead of `keras.Input` to Sequential model. `keras.Input` is intended to be used by Functional model.
WARNING:tensorflow:Please add `keras.layers.InputLayer` instead of `keras.Input` to Sequential model. `keras.Input` is intended to be used by Functional model.

Aquí, cargaremos nuestros datos de Keras directamente. En general, se recomienda almacenar su conjunto de datos en su depósito de Cloud Storage; sin embargo, TensorFlow Cloud también puede admitir conjuntos de datos almacenados localmente. Eso está cubierto en la sección Multi-archivo de esta guía.

(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

El TensorFlow Nube API proporciona la remote() función para determinar si el código se ejecuta localmente o en la nube. Esto permite la designación separada de fit() parámetros para la ejecución local y remoto, y proporciona medios para facilitar la depuración sin sobrecargar la máquina local.

if tfc.remote():
    epochs = 100
    callbacks = callbacks
    batch_size = 128
else:
    epochs = 5
    batch_size = 64
    callbacks = None

model.fit(x_train, y_train, epochs=epochs, callbacks=callbacks, batch_size=batch_size)
2021-07-27 22:07:21.458608: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:176] None of the MLIR Optimization Passes are enabled (registered 2)
2021-07-27 22:07:21.459072: I tensorflow/core/platform/profile_utils/cpu_utils.cc:114] CPU Frequency: 2000170000 Hz
Epoch 1/5
2021-07-27 22:07:21.885085: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudnn.so.8
2021-07-27 22:07:23.986122: I tensorflow/stream_executor/cuda/cuda_dnn.cc:359] Loaded cuDNN version 8100
2021-07-27 22:07:29.307903: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcublas.so.11
2021-07-27 22:07:29.684317: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcublasLt.so.11
938/938 [==============================] - 12s 3ms/step - loss: 0.2065 - sparse_categorical_accuracy: 0.9374
Epoch 2/5
938/938 [==============================] - 3s 3ms/step - loss: 0.0577 - sparse_categorical_accuracy: 0.9822
Epoch 3/5
938/938 [==============================] - 3s 3ms/step - loss: 0.0415 - sparse_categorical_accuracy: 0.9868
Epoch 4/5
938/938 [==============================] - 3s 3ms/step - loss: 0.0332 - sparse_categorical_accuracy: 0.9893
Epoch 5/5
938/938 [==============================] - 3s 3ms/step - loss: 0.0275 - sparse_categorical_accuracy: 0.9915
<tensorflow.python.keras.callbacks.History at 0x7f7b0c66a390>

Guardemos el modelo en GCS después de completar el entrenamiento.

save_path = os.path.join("gs://", gcp_bucket, "mnist_example")

if tfc.remote():
    model.save(save_path)

También podemos usar este depósito de almacenamiento para la creación de imágenes de Docker, en lugar de su instancia local de Docker. Para ello, basta con añadir su cubo a la docker_image_bucket_name parámetro.

# docs_infra: no_execute
tfc.run(docker_image_bucket_name=gcp_bucket)

Después de entrenar el modelo, podemos cargar el modelo guardado y ver nuestros registros de TensorBoard para monitorear el rendimiento.

# docs_infra: no_execute
model = keras.models.load_model(save_path)
#docs_infra: no_execute
tensorboard dev upload --logdir "gs://keras-examples-jonah/logs/fit" --name "Guide MNIST"

Proyectos a gran escala

En muchos casos, su proyecto que contiene un modelo de Keras puede abarcar más de un script de Python o puede involucrar datos externos o dependencias específicas. TensorFlow Cloud es completamente flexible para la implementación a gran escala y proporciona una serie de funcionalidades inteligentes para ayudar en sus proyectos.

Puntos de entrada: soporte para scripts Python y cuadernos Jupyter

Su llamada al run() de la API no se encontrará siempre dentro de la misma secuencia de comandos Python como su código de modelo de formación. Para este fin, se proporciona una entry_point parámetro. El entry_point parámetro se puede utilizar para especificar la secuencia de comandos Python o cuaderno en el que su modelo de código de la formación vidas. Cuando se llama a run() desde el mismo guión que su modelo, utilice el entry_point predeterminado de None .

pip dependencias

Si sus llamadas de proyectos adicionales en pip dependencias, es posible especificar las bibliotecas necesarias adicionales mediante la inclusión de un requirements.txt archivo. En este archivo, simplemente coloque una lista de todas las dependencias requeridas y TensorFlow Cloud se encargará de integrarlas en su compilación en la nube.

Cuadernos de Python

TensorFlow Cloud también se puede ejecutar desde cuadernos de Python. Además, su especificada entry_point puede ser un cuaderno si es necesario. Hay dos diferencias clave a tener en cuenta entre TensorFlow Cloud en notebooks y scripts:

  • Cuando se llama a run() desde dentro de un cuaderno, un cubo de almacenamiento en la nube debe especificarse para la construcción y el almacenamiento de la imagen del estibador.
  • La autenticación de GCloud ocurre completamente a través de su clave de autenticación, sin especificación de proyecto. En la sección "Poner todo junto" de esta guía, se proporciona un flujo de trabajo de ejemplo con TensorFlow Cloud desde una computadora portátil.

Proyectos de varios archivos

Si su modelo depende de archivos adicionales, solo necesita asegurarse de que estos archivos se encuentren en el mismo directorio (o subdirectorio) del punto de entrada especificado. Cada archivo que se almacena en el mismo directorio que el especificado entry_point será incluido en la imagen del estibador, así como todos los archivos almacenados en subdirectorios adyacentes a la de entry_point . Esto también es cierto para las dependencias que pueda necesitar que no pueden ser adquiridos a través pip

Para un ejemplo de un proyecto de varios archivos de punto de entrada y personalizado con dependencias de imágenes incrustadas, echar un vistazo a este ejemplo de varios archivos en el TensorFlow Nube Repositorio . Por razones de brevedad, sólo tendremos que incluimos el ejemplo de run() llamada:

tfc.run(
    docker_image_bucket_name=gcp_bucket,
    entry_point="train_model.py",
    requirements="requirements.txt"
)

Configuración de máquinas y entrenamiento distribuido

El entrenamiento de modelos puede requerir una amplia gama de recursos diferentes, según el tamaño del modelo o el conjunto de datos. Al contabilizar para configuraciones con múltiples GPU, se convierte en fundamental para elegir un ajuste de la estrategia de distribución . Aquí, describimos algunas configuraciones posibles:

Distribución multitrabajador

Aquí, podemos utilizar COMMON_MACHINE_CONFIGS para designar 1 CPU y GPU 4 trabajador principales.

tfc.run(
    docker_image_bucket_name=gcp_bucket,
    chief_config=tfc.COMMON_MACHINE_CONFIGS['CPU'],
    worker_count=2,
    worker_config=tfc.COMMON_MACHINE_CONFIGS['T4_4X']
)

Por defecto, TensorFlow Nube elige la mejor estrategia de distribución para la configuración de la máquina con una fórmula sencilla utilizando el chief_config , worker_config y worker_count parámetros proporcionada.

Distribución de TPU

Entrenemos el mismo modelo en TPU, como se muestra:

tfc.run(
    docker_image_bucket_name=gcp_bucket,
    chief_config=tfc.COMMON_MACHINE_CONFIGS["CPU"],
    worker_count=1,
    worker_config=tfc.COMMON_MACHINE_CONFIGS["TPU"]
)

Estrategia de distribución personalizada

Para especificar una estrategia de distribución personalizada, formatear su código normalmente como lo haría de acuerdo con la guía de capacitación distribuida y conjunto distribution_strategy a None . A continuación, especificaremos nuestra propia estrategia de distribución para el mismo modelo MNIST.

(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

mirrored_strategy = tf.distribute.MirroredStrategy()
with mirrored_strategy.scope():
  model = create_model()

if tfc.remote():
    epochs = 100
    batch_size = 128
else:
    epochs = 10
    batch_size = 64
    callbacks = None

model.fit(
    x_train, y_train, epochs=epochs, callbacks=callbacks, batch_size=batch_size
)

tfc.run(
    docker_image_bucket_name=gcp_bucket,
    chief_config=tfc.COMMON_MACHINE_CONFIGS['CPU'],
    worker_count=2,
    worker_config=tfc.COMMON_MACHINE_CONFIGS['T4_4X'],
    distribution_strategy=None
)

Imágenes de Docker personalizadas

Por defecto, TensorFlow Nube utiliza una imagen de base acoplable suministrado por Google y que corresponde a la versión actual TensorFlow. Sin embargo, también puede especificar una imagen de Docker personalizada que se ajuste a sus requisitos de compilación, si es necesario. Para este ejemplo, especificaremos la imagen de Docker de una versión anterior de TensorFlow:

tfc.run(
    docker_image_bucket_name=gcp_bucket,
    base_docker_image="tensorflow/tensorflow:2.1.0-gpu"
)

Métricas adicionales

Puede resultarle útil etiquetar sus trabajos en la nube con etiquetas específicas o transmitir los registros de su modelo durante el entrenamiento en la nube. Es una buena práctica mantener un etiquetado adecuado en todos los trabajos en la nube, para el mantenimiento de registros. Para este propósito, run() acepta un diccionario de etiquetas de hasta 64 pares de valores clave, que son visibles a partir de los registros de generación de la nube. Registros tales como el rendimiento y el ahorro de época internos modelo se puede acceder a través del enlace proporcionado por la ejecución de tfc.run o impreso a su terminal local utilizando el stream_logs bandera.

job_labels = {"job": "mnist-example", "team": "keras-io", "user": "jonah"}

tfc.run(
    docker_image_bucket_name=gcp_bucket,
    job_labels=job_labels,
    stream_logs=True
)

Poniendolo todo junto

Para una profundidad en Colab que utiliza muchas de las características descritas en esta guía, sigue a lo largo de este ejemplo para entrenar un modelo de estado de la técnica para reconocer las razas de perro a partir de imágenes utilizando la extracción de características.