От прототипа к производству: настройка гиперпараметров

1. Обзор

В этой лабораторной работе вы будете использовать Vertex AI для настройки гиперпараметров обучающей модели Vertex AI.

Эта лабораторная работа является частью видеосерии «От прототипа к серийному производству» . Перед выполнением этой лабораторной работы обязательно пройдите предыдущую . Для получения дополнительной информации вы можете посмотреть сопутствующую серию видеороликов:

.

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

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

  • Модифицировать код обучающего приложения для автоматической настройки гиперпараметров.
  • Настройте и запустите задачу настройки гиперпараметров с помощью Python SDK от Vertex AI.

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

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

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

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

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

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

Выполните шаги в лабораторной работе «Обучение пользовательских моделей с помощью Vertex AI» , чтобы настроить среду.

4. Контейнеризация кода обучающего приложения

Для отправки задания на обучение в Vertex AI вам потребуется поместить код вашего обучающего приложения в контейнер Docker и загрузить этот контейнер в Google Artifact Registry . Используя этот подход, вы сможете обучать и настраивать модель, созданную с помощью любого фреймворка.

Для начала откройте окно терминала из меню запуска блокнота Workbench, который вы создали в предыдущих лабораторных работах.

Откройте терминал в ноутбуке.

Шаг 1: Напишите код для обучения.

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

mkdir flowers-hptune
cd flowers-hptune

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

mkdir trainer
touch trainer/task.py

Теперь в каталоге flowers-hptune/ у вас должно быть следующее:

+ trainer/
    + task.py

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

Вам нужно заменить {your-gcs-bucket} в BUCKET_ROOT на название корзины Cloud Storage, где вы хранили набор данных о цветах в лабораторной работе 1 .

import tensorflow as tf
import numpy as np
import os
import hypertune
import argparse

## Replace {your-gcs-bucket} !!
BUCKET_ROOT='/gcs/{your-gcs-bucket}'

# Define variables
NUM_CLASSES = 5
EPOCHS=10
BATCH_SIZE = 32

IMG_HEIGHT = 180
IMG_WIDTH = 180

DATA_DIR = f'{BUCKET_ROOT}/flower_photos'

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 create_datasets(data_dir, batch_size):
  '''Creates train and validation datasets.'''

  train_dataset = tf.keras.utils.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="training",
    seed=123,
    image_size=(IMG_HEIGHT, IMG_WIDTH),
    batch_size=batch_size)

  validation_dataset = tf.keras.utils.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="validation",
    seed=123,
    image_size=(IMG_HEIGHT, IMG_WIDTH),
    batch_size=batch_size)

  train_dataset = train_dataset.cache().shuffle(1000).prefetch(buffer_size=tf.data.AUTOTUNE)
  validation_dataset = validation_dataset.cache().prefetch(buffer_size=tf.data.AUTOTUNE)

  return train_dataset, validation_dataset


def create_model(num_units, learning_rate, momentum):
  '''Creates model.'''

  model = tf.keras.Sequential([
    tf.keras.layers.Resizing(IMG_HEIGHT, IMG_WIDTH),
    tf.keras.layers.Rescaling(1./255, input_shape=(IMG_HEIGHT, IMG_WIDTH, 3)),
    tf.keras.layers.Conv2D(16, 3, padding='same', activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(32, 3, padding='same', activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(64, 3, padding='same', activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(num_units, activation='relu'),
    tf.keras.layers.Dense(NUM_CLASSES, activation='softmax')
  ])

  model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=learning_rate, momentum=momentum),
              loss=tf.keras.losses.SparseCategoricalCrossentropy(),
              metrics=['accuracy'])
  
  return model

def main():
  args = get_args()
  train_dataset, validation_dataset = create_datasets(DATA_DIR, BATCH_SIZE)
  model = create_model(args.num_units, args.learning_rate, args.momentum)
  history = model.fit(train_dataset, validation_data=validation_dataset, epochs=EPOCHS)

  # 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=EPOCHS)


if __name__ == "__main__":
    main()

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

  1. Скрипт импортирует библиотеку hypertune .
  2. Функция get_args() определяет аргумент командной строки для каждого гиперпараметра, который вы хотите настроить. В этом примере настраиваются следующие гиперпараметры: скорость обучения, значение момента в оптимизаторе и количество нейронов в последнем скрытом слое модели, но вы можете поэкспериментировать и с другими. Значение, переданное в этих аргументах, затем используется для установки соответствующего гиперпараметра в коде.
  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 , но вам потребуется использовать эту строку снова позже, когда вы запустите задачу настройки гиперпараметров.

Шаг 2: Создайте Dockerfile.

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

В терминале создайте пустой Dockerfile в корневом каталоге flowers-hptune :

touch Dockerfile

Теперь в каталоге flowers-hptune/ у вас должно быть следующее:

+ Dockerfile
+ trainer/
    + task.py

Откройте Dockerfile и скопируйте в него следующее. Вы заметите, что он практически идентичен Dockerfile, который мы использовали в первой лабораторной работе, за исключением того, что теперь мы устанавливаем библиотеку cloudml-hypertune.

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

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

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

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

PROJECT_ID='your-cloud-project'

Создайте репозиторий в Artifact Registry. Мы будем использовать репозиторий, созданный в первой лабораторной работе.

REPO_NAME='flower-app'

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

IMAGE_URI=us-central1-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/flower_image_hptune:latest

Настройка Docker

gcloud auth configure-docker \
    us-central1-docker.pkg.dev

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

docker build ./ -t $IMAGE_URI

Наконец, отправьте его в Реестр артефактов:

docker push $IMAGE_URI

После загрузки контейнера в реестр артефактов вы готовы приступить к выполнению задания по обучению.

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

В этом разделе вы узнаете, как настроить и отправить задание по настройке гиперпараметров с помощью Python-API Vertex.

В панели запуска создайте блокнот TensorFlow 2.

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

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

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": 1
    },
    "replica_count": 1,
    "container_spec": {
        "image_uri": "us-central1-docker.pkg.dev/{PROJECT_ID}/flower-app/flower_image_hptune: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 , который вы задали в коде вашего обучающего приложения, а значением — цель оптимизации.

# Dictionary representing metric 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='flowers-hptune-job',
                              worker_pool_specs=worker_pool_specs,
                              staging_bucket='gs://{YOUR_BUCKET}')

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

hp_job = aiplatform.HyperparameterTuningJob(
    display_name='flowers-hptune-job',
    custom_job=my_custom_job,
    metric_spec=metric_spec,
    parameter_spec=parameter_spec,
    max_trial_count=15,
    parallel_trial_count=3)

hp_job.run()

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

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

В консоли вы сможете отслеживать ход выполнения задания.

hp_job

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

hp_results

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

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

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

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

6. Уборка

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

Остановить экземпляр

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

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