Vertex AI: распределенная настройка гиперпараметров

1. Обзор

В этой лабораторной работе вы научитесь использовать Vertex AI для настройки гиперпараметров и распределенного обучения. Хотя в этой работе используется TensorFlow для кода модели, изложенные концепции применимы и к другим фреймворкам машинного обучения.

Чему вы научитесь

Вы научитесь:

  • Обучение модели с использованием распределенного обучения в пользовательском контейнере.
  • Запустите несколько итераций вашего обучающего кода для автоматической настройки гиперпараметров.

Общая стоимость запуска этой лабораторной работы в Google Cloud составляет около 6 долларов США.

2. Введение в Vertex AI

В этой лабораторной работе используется новейший продукт для искусственного интеллекта, доступный в Google Cloud. Vertex AI интегрирует предложения машинного обучения в Google Cloud в единый процесс разработки. Ранее модели, обученные с помощью AutoML, и пользовательские модели были доступны через отдельные сервисы. Новое предложение объединяет оба варианта в единый API, а также включает другие новые продукты. Вы также можете перенести существующие проекты в Vertex AI. Если у вас есть какие-либо замечания, пожалуйста, посетите страницу поддержки .

Vertex AI предлагает множество различных продуктов для поддержки комплексных рабочих процессов машинного обучения. В этой лабораторной работе мы сосредоточимся на Training и Workbench .

Обзор продукции Vertex

3. Обзор вариантов использования

В этой лабораторной работе вы используете настройку гиперпараметров для определения оптимальных параметров модели классификации изображений, обученной на наборе данных «Лошади или люди» из TensorFlow Datasets .

Настройка гиперпараметров

Настройка гиперпараметров с помощью Vertex AI Training работает путем проведения нескольких итераций обучения вашего приложения со значениями выбранных вами гиперпараметров, установленными в пределах заданных вами ограничений. Vertex AI отслеживает результаты каждой итерации и вносит корректировки для последующих итераций.

Для использования настройки гиперпараметров в программе обучения Vertex AI Training вам потребуется внести два изменения в код обучения:

  1. Определите аргумент командной строки в основном модуле обучения для каждого гиперпараметра, который вы хотите настроить.
  2. Используйте значения, переданные в этих аргументах, для установки соответствующего гиперпараметра в коде вашего приложения.

Дистанционное обучение

Если у вас всего один графический процессор, TensorFlow будет использовать этот ускоритель для ускорения обучения модели без каких-либо дополнительных усилий с вашей стороны. Однако, если вы хотите получить дополнительный прирост производительности за счет использования нескольких графических процессоров, вам потребуется использовать tf.distribute — модуль TensorFlow для выполнения вычислений на нескольких устройствах.

В этой лабораторной работе используется tf.distribute.MirroredStrategy , которую можно добавить в ваши обучающие приложения всего с несколькими изменениями в коде. Эта стратегия создает копию модели на каждом графическом процессоре вашей машины. Последующие обновления градиентов будут происходить синхронно. Это означает, что каждый графический процессор вычисляет прямые и обратные проходы через модель на разных срезах входных данных. Вычисленные градиенты из каждого из этих срезов затем агрегируются по всем графическим процессорам и усредняются в процессе, известном как all-reduce . Параметры модели обновляются с использованием этих усредненных градиентов.

Для выполнения этой лабораторной работы вам не обязательно знать все подробности, но если вы хотите узнать больше о том, как работает распределенное обучение в TensorFlow, посмотрите видео ниже:

4. Настройте свою среду.

Для выполнения этого практического задания вам потребуется проект Google Cloud Platform с включенной оплатой. Чтобы создать проект, следуйте инструкциям здесь .

Шаг 1: Включите API Compute Engine.

Перейдите в раздел Compute Engine и выберите «Включить», если эта функция еще не включена.

Шаг 2: Включите API реестра контейнеров.

Перейдите в Реестр контейнеров и выберите «Включить», если эта опция еще не включена. Это позволит создать контейнер для вашей пользовательской задачи обучения.

Шаг 3: Включите API Vertex AI

Перейдите в раздел Vertex AI в вашей облачной консоли и нажмите «Включить API Vertex AI» .

Панель мониторинга Vertex AI

Шаг 4: Создайте экземпляр Vertex AI Workbench.

В разделе Vertex AI вашей облачной консоли нажмите на Workbench:

Меню Vertex AI

Включите API для блокнотов, если он еще не включен.

Notebook_api

После включения нажмите «УПРАВЛЯЕМЫЕ ЗАПИСНЫЕ КНИЖКИ» :

Notebooks_UI

Затем выберите «Создать новый блокнот» .

новый_ноутбук

Присвойте своему блокноту имя, а затем нажмите «Дополнительные настройки» .

создать_блокнот

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

idle_timeout

В разделе «Безопасность» выберите «Включить терминал», если он еще не включен.

enable-terminal

Все остальные расширенные настройки можно оставить без изменений.

Далее нажмите «Создать» . Создание экземпляра займет несколько минут.

После создания экземпляра выберите «Открыть JupyterLab» .

open_jupyterlab

При первом использовании нового экземпляра вам будет предложено пройти аутентификацию. Для этого следуйте инструкциям в пользовательском интерфейсе.

аутентифицировать

5. Напишите код для обучения.

Для начала откройте окно Терминала в вашем ноутбуке из меню «Запуск»:

launcher_terminal

Создайте новую директорию с именем vertex-codelab и перейдите в неё с помощью команды cd.

mkdir vertex-codelab
cd vertex-codelab

Выполните следующую команду, чтобы создать директорию для кода обучения и файл Python, куда вы добавите этот код:

mkdir trainer
touch trainer/task.py

Теперь в каталоге vertex-codelab должны находиться следующие файлы:

+ trainer/
    + task.py

Далее откройте созданный вами файл task.py и вставьте в него весь приведенный ниже код.

import tensorflow as tf
import tensorflow_datasets as tfds
import argparse
import hypertune
import os

NUM_EPOCHS = 10
BATCH_SIZE = 64

def get_args():
  '''Parses args. Must include all hyperparameters you want to tune.'''

  parser = argparse.ArgumentParser()
  parser.add_argument(
      '--learning_rate',
      required=True,
      type=float,
      help='learning rate')
  parser.add_argument(
      '--momentum',
      required=True,
      type=float,
      help='SGD momentum value')
  parser.add_argument(
      '--num_units',
      required=True,
      type=int,
      help='number of units in last hidden layer')
  args = parser.parse_args()
  return args


def preprocess_data(image, label):
  '''Resizes and scales images.'''

  image = tf.image.resize(image, (150,150))
  return tf.cast(image, tf.float32) / 255., label


def create_dataset(batch_size):
  '''Loads Horses Or Humans dataset and preprocesses data.'''

  data, info = tfds.load(name='horses_or_humans', as_supervised=True, with_info=True)

  # Create train dataset
  train_data = data['train'].map(preprocess_data)
  train_data  = train_data.shuffle(1000)
  train_data  = train_data.batch(batch_size)

  # Create validation dataset
  validation_data = data['test'].map(preprocess_data)
  validation_data  = validation_data.batch(batch_size)

  return train_data, validation_data


def create_model(num_units, learning_rate, momentum):
  '''Defines and compiles model.'''

  inputs = tf.keras.Input(shape=(150, 150, 3))
  x = tf.keras.layers.Conv2D(16, (3, 3), activation='relu')(inputs)
  x = tf.keras.layers.MaxPooling2D((2, 2))(x)
  x = tf.keras.layers.Conv2D(32, (3, 3), activation='relu')(x)
  x = tf.keras.layers.MaxPooling2D((2, 2))(x)
  x = tf.keras.layers.Conv2D(64, (3, 3), activation='relu')(x)
  x = tf.keras.layers.MaxPooling2D((2, 2))(x)
  x = tf.keras.layers.Flatten()(x)
  x = tf.keras.layers.Dense(num_units, activation='relu')(x)
  outputs = tf.keras.layers.Dense(1, activation='sigmoid')(x)
  model = tf.keras.Model(inputs, outputs)
  model.compile(
      loss='binary_crossentropy',
      optimizer=tf.keras.optimizers.SGD(learning_rate=learning_rate, momentum=momentum),
      metrics=['accuracy'])
  return model


def main():
  args = get_args()

  # Create distribution strategy
  strategy = tf.distribute.MirroredStrategy()

  # Get data
  GLOBAL_BATCH_SIZE = BATCH_SIZE * strategy.num_replicas_in_sync
  train_data, validation_data = create_dataset(GLOBAL_BATCH_SIZE)

  # Wrap variable creation within strategy scope
  with strategy.scope():
    model = create_model(args.num_units, args.learning_rate, args.momentum)

  # Train model
  history = model.fit(train_data, epochs=NUM_EPOCHS, validation_data=validation_data)

  # Define metric
  hp_metric = history.history['val_accuracy'][-1]

  hpt = hypertune.HyperTune()
  hpt.report_hyperparameter_tuning_metric(
      hyperparameter_metric_tag='accuracy',
      metric_value=hp_metric,
      global_step=NUM_EPOCHS)


if __name__ == "__main__":
    main()

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

Дистанционное обучение

  1. В функции main() создается объект MirroredStrategy . Затем вы заключаете создание переменных вашей модели в область видимости стратегии. Этот шаг указывает TensorFlow, какие переменные должны быть зеркально отображены между графическими процессорами.
  2. Размер пакета увеличивается на величину num_replicas_in_sync . Масштабирование размера пакета является рекомендуемой практикой при использовании стратегий синхронного параллелизма данных в TensorFlow. Подробнее можно узнать здесь.

Настройка гиперпараметров

  1. Скрипт импортирует библиотеку hypertune . Позже, при сборке образа контейнера, нам потребуется убедиться, что мы установили эту библиотеку.
  2. Функция get_args() определяет аргумент командной строки для каждого гиперпараметра, который вы хотите настроить. В этом примере будут настраиваться следующие гиперпараметры: скорость обучения, значение момента в оптимизаторе и количество нейронов в последнем скрытом слое модели, но вы можете поэкспериментировать и с другими. Значение, переданное в этих аргументах, затем используется для установки соответствующего гиперпараметра в коде (например, set learning_rate = args.learning_rate ).
  3. В конце функции main() используется библиотека hypertune для определения метрики, которую вы хотите оптимизировать. В TensorFlow метод model.fit в Keras возвращает объект History . Атрибут History.history содержит записи значений потерь и метрик на последовательных эпохах обучения. Если вы передаете данные валидации в model.fit , атрибут History.history будет включать также значения потерь и метрик валидации. Например, если вы обучали модель в течение трех эпох с использованием данных валидации и указали accuracy в качестве метрики, атрибут History.history будет выглядеть примерно так, как в следующем словаре.
{
 "accuracy": [
   0.7795261740684509,
   0.9471358060836792,
   0.9870933294296265
 ],
 "loss": [
   0.6340447664260864,
   0.16712145507335663,
   0.04546636343002319
 ],
 "val_accuracy": [
   0.3795261740684509,
   0.4471358060836792,
   0.4870933294296265
 ],
 "val_loss": [
   2.044623374938965,
   4.100203514099121,
   3.0728273391723633
 ]

Если вы хотите, чтобы служба настройки гиперпараметров определила значения, которые максимизируют точность валидации модели, вы определяете метрику как последнюю запись (или NUM_EPOCS - 1 ) в списке val_accuracy . Затем передайте эту метрику экземпляру HyperTune . Вы можете выбрать любую строку для параметра hyperparameter_metric_tag , но вам потребуется использовать эту строку снова позже, когда вы запустите задачу настройки гиперпараметров.

6. Контейнеризация кода

Первый шаг в контейнеризации вашего кода — создание Dockerfile. В Dockerfile вы укажете все команды, необходимые для запуска образа. Он установит все необходимые библиотеки и настроит точку входа для кода обучения.

Шаг 1: Напишите Dockerfile

В терминале убедитесь, что вы находитесь в каталоге vertex-codelab , и создайте пустой Dockerfile:

touch Dockerfile

Теперь в каталоге vertex-codelab должны находиться следующие файлы:

+ Dockerfile
+ trainer/
    + task.py

Откройте Dockerfile и скопируйте в него следующее:

FROM gcr.io/deeplearning-platform-release/tf2-gpu.2-7

WORKDIR /

# Installs hypertune library
RUN pip install cloudml-hypertune

# Copies the trainer code to the docker image.
COPY trainer /trainer

# Sets up the entry point to invoke the trainer.
ENTRYPOINT ["python", "-m", "trainer.task"]

В этом Dockerfile используется образ Docker для контейнеров глубокого обучения TensorFlow Enterprise 2.7 GPU . Контейнеры глубокого обучения в Google Cloud поставляются со множеством распространенных фреймворков для машинного обучения и анализа данных, предварительно установленных в них. После загрузки этого образа данный Dockerfile настраивает точку входа для кода обучения.

Шаг 2: Создайте контейнер

В терминале выполните следующую команду, чтобы определить переменную окружения для вашего проекта, заменив your-cloud-project на идентификатор вашего проекта:

PROJECT_ID='your-cloud-project'

Создайте переменную с URI образа вашего контейнера в реестре Google Container Registry:

IMAGE_URI="gcr.io/$PROJECT_ID/horse-human-codelab:latest"

Настройка Docker

gcloud auth configure-docker

Затем соберите контейнер, выполнив следующую команду из корневой директории вашего каталога vertex-codelab :

docker build ./ -t $IMAGE_URI

Наконец, загрузите его в реестр контейнеров Google:

docker push $IMAGE_URI

Шаг 3: Создайте сегмент облачного хранилища.

В ходе нашей учебной работы мы будем проходить по пути к посадочному ковшу.

Выполните следующую команду в терминале, чтобы создать новый бакет в вашем проекте.

BUCKET_NAME="gs://${PROJECT_ID}-hptune-bucket"
gsutil mb -l us-central1 $BUCKET_NAME

7. Запустить задачу настройки гиперпараметров.

Шаг 1: Создайте пользовательское задание обучения с настройкой гиперпараметров.

В меню запуска откройте новый блокнот TensorFlow 2.

новый_ноутбук

Импортируйте Python SDK от Vertex AI.

from google.cloud import aiplatform
from google.cloud.aiplatform import hyperparameter_tuning as hpt

Для запуска задачи настройки гиперпараметров необходимо сначала определить параметр worker_pool_specs , который задает тип машины и образ Docker. В приведенном ниже примере указана одна машина с двумя графическими процессорами NVIDIA Tesla V100.

Вам потребуется заменить {PROJECT_ID} в image_uri на название вашего проекта.

# The spec of the worker pools including machine type and Docker image
# Be sure to replace PROJECT_ID in the "image_uri" with your project.

worker_pool_specs = [{
    "machine_spec": {
        "machine_type": "n1-standard-4",
        "accelerator_type": "NVIDIA_TESLA_V100",
        "accelerator_count": 2
    },
    "replica_count": 1,
    "container_spec": {
        "image_uri": "gcr.io/{PROJECT_ID}/horse-human-codelab:latest"
    }
}]

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

Для каждого гиперпараметра необходимо определить тип, а также границы значений, которые будет использовать служба настройки. Гиперпараметры могут быть типа Double, Integer, Categorical или Discrete. Если вы выберете тип Double или Integer, вам потребуется указать минимальное и максимальное значение. А если вы выберете Categorical или Discrete, вам потребуется указать значения. Для типов Double и Integer вам также потребуется указать значение масштабирования. Подробнее о том, как выбрать оптимальное масштабирование, вы можете узнать в этом видео.

# Dictionary representing parameters to optimize.
# The dictionary key is the parameter_id, which is passed into your training
# job as a command line argument,
# And the dictionary value is the parameter specification of the metric.
parameter_spec = {
    "learning_rate": hpt.DoubleParameterSpec(min=0.001, max=1, scale="log"),
    "momentum": hpt.DoubleParameterSpec(min=0, max=1, scale="linear"),
    "num_units": hpt.DiscreteParameterSpec(values=[64, 128, 512], scale=None)
}

Последняя определяемая спецификация — это metric_spec , представляющая собой словарь, описывающий метрику для оптимизации. Ключом словаря является hyperparameter_metric_tag , который вы задали в коде вашего обучающего приложения, а значением — цель оптимизации.

# Dicionary representing metrics to optimize.
# The dictionary key is the metric_id, which is reported by your training job,
# And the dictionary value is the optimization goal of the metric.
metric_spec={'accuracy':'maximize'}

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

Вам нужно заменить {YOUR_BUCKET} на имя корзины, которую вы создали ранее.

# Replace YOUR_BUCKET
my_custom_job = aiplatform.CustomJob(display_name='horses-humans',
                              worker_pool_specs=worker_pool_specs,
                              staging_bucket='gs://{YOUR_BUCKET}')

Затем создайте и запустите задание HyperparameterTuningJob .

hp_job = aiplatform.HyperparameterTuningJob(
    display_name='horses-humans',
    custom_job=my_custom_job,
    metric_spec=metric_spec,
    parameter_spec=parameter_spec,
    max_trial_count=6,
    parallel_trial_count=2,
    search_algorithm=None)

hp_job.run()

Следует отметить несколько аргументов:

  • max_trial_count: Вам необходимо установить верхнюю границу количества испытаний, которые будет проводить сервис. Большее количество испытаний, как правило, приводит к лучшим результатам, но существует точка убывающей отдачи, после которой дополнительные испытания практически не влияют на метрику, которую вы пытаетесь оптимизировать. Рекомендуется начинать с меньшего количества испытаний и оценить, насколько значимы выбранные вами гиперпараметры, прежде чем масштабировать систему.
  • parallel_trial_count: При использовании параллельных испытаний служба выделяет несколько кластеров для обработки обучающих данных. Увеличение количества параллельных испытаний сокращает время выполнения задачи настройки гиперпараметров, однако может снизить общую эффективность задачи. Это связано с тем, что стратегия настройки по умолчанию использует результаты предыдущих испытаний для определения значений в последующих испытаниях.
  • search_algorithm: Вы можете установить алгоритм поиска на grid, random или default (None). Вариант default использует байесовскую оптимизацию для поиска в пространстве возможных значений гиперпараметров и является рекомендуемым алгоритмом. Подробнее об этом алгоритме можно узнать здесь.

После запуска задания вы сможете отслеживать его статус в пользовательском интерфейсе на вкладке « Задания по настройке гиперпараметров» .

HP_job

После завершения работы вы можете просмотреть и отсортировать результаты своих экспериментов, чтобы найти наилучшее сочетание значений гиперпараметров.

HP_результаты

🎉 Поздравляем! 🎉

Вы научились использовать Vertex AI для:

  • Запустите задачу настройки гиперпараметров с распределенным обучением.

Чтобы узнать больше о различных компонентах Vertex AI, ознакомьтесь с документацией .

8. Уборка

Поскольку мы настроили ноутбук на автоматическое завершение работы через 60 минут простоя, нам не нужно беспокоиться о выключении экземпляра. Если вы хотите выключить экземпляр вручную, нажмите кнопку «Стоп» в разделе Vertex AI Workbench в консоли. Если вы хотите полностью удалить ноутбук, нажмите кнопку «Удалить».

удалить

Чтобы удалить сегмент хранилища, воспользуйтесь меню навигации в консоли Cloud Console, перейдите в раздел «Хранилище», выберите свой сегмент и нажмите «Удалить».

Удалить хранилище