Обучение моделей Keras с помощью TensorFlow Cloud

Посмотреть на TensorFlow.org Запускаем в Google Colab Посмотреть исходный код на GitHub Скачать блокнот

Введение

TensorFlow Cloud представляет собой пакет Python , который предоставляет API - интерфейсы для перехода бесшовного из локальной отладки в распределенную подготовку в Google Cloud. Он упрощает процесс обучения моделей TensorFlow в облаке в один простой вызов функции, требующий минимальной настройки и никаких изменений в вашей модели. TensorFlow Cloud автоматически решает задачи, связанные с облаком, такие как создание экземпляров виртуальных машин и стратегии распространения для ваших моделей. Это руководство продемонстрирует, как взаимодействовать с Google Cloud через TensorFlow Cloud, а также широкий спектр функций, предоставляемых в TensorFlow Cloud. Начнем с простейшего варианта использования.

Настраивать

Мы начнем с установки TensorFlow Cloud и импорта пакетов, которые нам понадобятся в этом руководстве.

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

Обзор API: первый сквозной пример

Начнем с учебного сценария модели Keras, такого как следующий 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)

Для подготовки данной модели на Google Cloud мы просто нужно добавить вызов run() в начале сценария, перед импортом:

tfc.run()

Вам не нужно беспокоиться о задачах, связанных с облаком, таких как создание экземпляров виртуальных машин и стратегии распространения при использовании TensorFlow Cloud. API включает интеллектуальные значения по умолчанию для всех параметров - все настраивается, но многие модели могут полагаться на эти значения по умолчанию.

При вызове run() , TensorFlow Облако будет:

  • Подготовьте свой сценарий Python или записную книжку для распространения.
  • Преобразуйте его в образ Docker с необходимыми зависимостями.
  • Выполните задание по обучению на виртуальной машине с графическим процессором GCP.
  • Потоковая передача соответствующих журналов и информации о вакансиях.

Конфигурация виртуальной машины по умолчанию - 1 главный и 0 рабочих с 8 ядрами ЦП и 1 графическим процессором Tesla T4.

Конфигурация Google Cloud

Чтобы облегчить правильные пути для обучения работе с облаком, вам нужно будет выполнить некоторую первоначальную настройку. Если вы новый пользователь Google Cloud, вам необходимо сделать несколько предварительных шагов:

  1. Создать проект GCP;
  2. Включить службы платформы AI;
  3. Создать учетную запись службы;
  4. Скачать ключ авторизации;
  5. Создайте корзину Cloud Storage.

Подробные инструкции по настройке первого времени можно найти в TensorFlow Cloud README , и дополнительный пример установки показана на TensorFlow Блоге .

Общие рабочие процессы и облачное хранилище

В большинстве случаев вы захотите получить свою модель после обучения в Google Cloud. Для этого крайне важно перенаправить сохранение и загрузку в облачное хранилище во время удаленного обучения. Мы можем направить TensorFlow Cloud в нашу корзину Cloud Storage для различных задач. Сегмент хранилища можно использовать для сохранения и загрузки больших наборов обучающих данных, журналов обратных вызовов или весов моделей, а также файлов обученных моделей. Для начала, давайте настроим fit() , чтобы сохранить модель в Cloud Storage, а также создать TensorBoard мониторинга для отслеживания прогресса обучения.

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

Давайте сохраним журналы TensorBoard и контрольные точки модели, созданные во время обучения, в нашей корзине облачного хранилища.

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.

Здесь мы загрузим наши данные напрямую из Keras. Как правило, лучше всего хранить набор данных в корзине облачного хранилища, однако TensorFlow Cloud также может вмещать наборы данных, хранящиеся локально. Это описано в разделе, посвященном нескольким файлам этого руководства.

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

TensorFlow Облако API , обеспечивает remote() функцию , чтобы определить , является ли код выполняется локально или на облаке. Это позволяет отдельное обозначение fit() параметров для локального и удаленного исполнения, а также предоставляет средства для облегчения отладки без перегрузки вашей локальной машины.

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>

Сохраним модель в GCS после завершения обучения.

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

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

Мы также можем использовать это ведро хранилища для создания образа Docker вместо вашего локального экземпляра Docker. Для этого просто добавьте ведро с docker_image_bucket_name параметра.

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

После обучения модели мы можем загрузить сохраненную модель и просмотреть журналы TensorBoard, чтобы отслеживать производительность.

# 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"

Масштабные проекты

Во многих случаях ваш проект, содержащий модель Keras, может включать более одного скрипта Python или может включать внешние данные или определенные зависимости. TensorFlow Cloud полностью гибок для крупномасштабного развертывания и предоставляет ряд интеллектуальных функций для поддержки ваших проектов.

Точки входа: поддержка скриптов Python и записных книжек Jupyter

Ваш призыв к run() API не всегда будут содержаться внутри того же сценария Python как ваша модель обучения кода. Для этой цели мы предлагаем entry_point параметр. entry_point параметр может быть использован , чтобы указать скрипт на Python или ноутбук , в котором ваши модели обучения код жизни. При вызове run() из того же сценария в качестве модели, используйте entry_point значения по умолчанию None .

pip зависимости

Если ваши звонки проекта на дополнительных pip зависимостей, можно указать дополнительные необходимые библиотеки, включив requirements.txt файл. Просто поместите в этот файл список всех необходимых зависимостей, и TensorFlow Cloud выполнит их интеграцию в вашу облачную сборку.

Блокноты Python

TensorFlow Cloud также можно запускать из записных книжек Python. Кроме того, указанный Вами entry_point может быть ноутбук , если это необходимо. Следует помнить о двух ключевых отличиях между TensorFlow Cloud на ноутбуках и скриптами:

  • При вызове run() изнутри ноутбука, ведро Облачного хранилища должно быть указано для создания и хранения вашей Docker изображения.
  • Аутентификация GCloud происходит полностью с помощью вашего ключа аутентификации, без спецификации проекта. Пример рабочего процесса с использованием TensorFlow Cloud из записной книжки приведен в разделе «Собираем все вместе» этого руководства.

Многофайловые проекты

Если ваша модель зависит от дополнительных файлов, вам нужно только убедиться, что эти файлы находятся в том же каталоге (или подкаталоге) указанной точки входа. Каждый файл , который хранится в том же каталоге, что и указанный entry_point будут включены в образ Докер, а также любые файлы , хранящиеся в поддиректории , прилегающих к entry_point . Это также верно и для зависимостей , вам может понадобиться , которые не могут быть приобретены через pip

Для примера пользовательского ввода точки и проекта многостраничных файлов с дополнительными зависимостями семечковых, посмотрите на это мульти-файл , например на TensorFlow Cloud Repository . Для краткости мы будем просто включить в качестве примера в run() вызов:

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

Конфигурация машины и распределенное обучение

Для обучения модели может потребоваться широкий спектр различных ресурсов в зависимости от размера модели или набора данных. При учете конфигураций с несколькими графическими процессорами, становится важно выбрать фитинг стратегию распределения . Здесь мы обрисовываем несколько возможных конфигураций:

Распределение нескольких сотрудников

Здесь мы можем использовать COMMON_MACHINE_CONFIGS для обозначения 1 главных графических процессоров CPU и 4 работника.

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']
)

По умолчанию, TensorFlow Cloud выбирает оптимальную стратегию распределения для вашей конфигурации машины с простой формулой , используя chief_config , worker_config и worker_count параметры при условии.

Распределение TPU

Обучим ту же модель на TPU, как показано:

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"]
)

Стратегия индивидуального распространения

Для того, чтобы определить стратегию распространения пользовательского, форматирования кода обычно , как если бы в соответствии с распределенным руководство учебного и множества distribution_strategy в None . Ниже мы укажем нашу собственную стратегию распространения для той же модели 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
)

Пользовательские образы Docker

По умолчанию, TensorFlow Cloud использует Docker базовый образ , поставляемый Google и соответствующий текущей версии TensorFlow. Однако при необходимости вы также можете указать собственный образ Docker в соответствии с вашими требованиями к сборке. В этом примере мы укажем образ Docker из более старой версии TensorFlow:

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

Дополнительные метрики

Возможно, вам будет полезно пометить свои облачные задания определенными метками или передать журналы вашей модели в потоковом режиме во время облачного обучения. Хорошая практика - поддерживать надлежащую маркировку всех заданий в облаке для ведения учета. Для этого run() принимает словарь меток до 64 пар ключ-значение, которые видны из журналов сборки Облако. Журналы , такие как производительность эпохи и сохранение модели внутренности можно получить используя ссылки, выполнив tfc.run или напечатанных на локальный терминал , используя stream_logs флаг.

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
)

Собираем все вместе

Для углубленного Colab , который использует многие из функций , описанных в данном руководстве, следовать этому пример , чтобы подготовить модель внедренной признать породы собак из фотографий с помощью выделения признаков.