1. Обзор
В этой лабораторной работе вы узнаете, как использовать Vertex AI для настройки гиперпараметров и распределенного обучения. Хотя в этой лабораторной работе для кода модели используется TensorFlow, эти концепции применимы и к другим платформам машинного обучения.
Что вы узнаете
Вы узнаете, как:
- Обучение модели с помощью распределенного обучения в пользовательском контейнере
- Запустите несколько испытаний вашего обучающего кода для автоматической настройки гиперпараметров.
Общая стоимость запуска этой лаборатории в Google Cloud составляет около 6 долларов США.
2. Знакомство с Vertex AI
В этой лаборатории используются новейшие продукты искусственного интеллекта, доступные в Google Cloud. Vertex AI интегрирует предложения машинного обучения в Google Cloud в единый процесс разработки. Раньше модели, обученные с помощью AutoML, и пользовательские модели были доступны через отдельные сервисы. Новое предложение объединяет оба API в одном API, а также другие новые продукты. Вы также можете перенести существующие проекты на Vertex AI. Если у вас есть какие-либо отзывы, пожалуйста, посетите страницу поддержки .
Vertex AI включает в себя множество различных продуктов для поддержки комплексных рабочих процессов машинного обучения. Эта лабораторная работа будет сосредоточена на обучении и рабочих средах .
3. Обзор вариантов использования
В этой лабораторной работе вы будете использовать настройку гиперпараметров, чтобы обнаружить оптимальные параметры для модели классификации изображений, обученной на наборе данных лошадей или людей из TensorFlow Datasets .
Настройка гиперпараметров
Настройка гиперпараметров с помощью Vertex AI Training осуществляется путем запуска нескольких испытаний вашего приложения обучения со значениями выбранных вами гиперпараметров, установленных в указанных вами пределах. Vertex AI отслеживает результаты каждого испытания и вносит коррективы для последующих испытаний.
Чтобы использовать настройку гиперпараметров с Vertex AI Training, вам необходимо внести два изменения в свой обучающий код:
- Определите аргумент командной строки в основном обучающем модуле для каждого гиперпараметра, который вы хотите настроить.
- Используйте значение, переданное в этих аргументах, чтобы установить соответствующий гиперпараметр в коде вашего приложения.
Распределенное обучение
Если у вас один графический процессор, 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 в облачной консоли и нажмите «Включить Vertex AI API» .
Шаг 4. Создайте экземпляр Vertex AI Workbench.
В разделе Vertex AI облачной консоли нажмите Workbench:
Включите API ноутбуков, если это еще не сделано.
После включения нажмите «УПРАВЛЯЕМЫЕ НОУТБУКЫ» :
Затем выберите НОВЫЙ НОУТБУК .
Дайте записной книжке имя и нажмите «Дополнительные настройки» .
В разделе «Дополнительные настройки» включите выключение в режиме ожидания и установите количество минут, равное 60. Это означает, что ваш ноутбук будет автоматически отключаться, когда он не используется, поэтому вы не несете ненужных затрат.
В разделе «Безопасность» выберите «Включить терминал», если он еще не включен.
Все остальные дополнительные настройки вы можете оставить как есть.
Далее нажмите Создать . Подготовка экземпляра займет пару минут.
После создания экземпляра выберите «Открыть JupyterLab» .
При первом использовании нового экземпляра вам будет предложено пройти аутентификацию. Для этого следуйте инструкциям в пользовательском интерфейсе.
5. Напишите обучающий код
Для начала в меню Launcher откройте окно терминала в экземпляре вашего ноутбука:
Создайте новый каталог с именем vertex-codelab
и перейдите в него.
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()
Давайте более подробно рассмотрим код и рассмотрим компоненты, специфичные для распределенного обучения и настройки гиперпараметров.
Распределенное обучение
- В функции
main()
создается объектMirroredStrategy
. Затем вы переносите создание переменных модели в область действия стратегии. Этот шаг сообщает TensorFlow, какие переменные следует зеркально отображать на графических процессорах. - Размер пакета увеличивается с помощью
num_replicas_in_sync
. Масштабирование размера пакета — лучшая практика при использовании стратегий параллелизма синхронных данных в TensorFlow. Вы можете узнать больше здесь.
Настройка гиперпараметров
- Скрипт импортирует библиотеку
hypertune
. Позже, когда мы создадим образ контейнера, нам нужно будет убедиться, что мы установили эту библиотеку. - Функция
get_args()
определяет аргумент командной строки для каждого гиперпараметра, который вы хотите настроить. В этом примере гиперпараметрами, которые будут настроены, являются скорость обучения, значение импульса в оптимизаторе и количество единиц в последнем скрытом слое модели, но вы можете экспериментировать с другими. Значение, переданное в этих аргументах, затем используется для установки соответствующего гиперпараметра в коде (например, setlearning_rate = args.learning_rate
). - В конце функции
main()
библиотекаhypertune
используется для определения метрики, которую вы хотите оптимизировать. В TensorFlow метод Kerasmodel.fit
возвращает объект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 GPU контейнера глубокого обучения TensorFlow Enterprise 2.7 . Контейнеры глубокого обучения в Google Cloud поставляются со многими предустановленными стандартными платформами машинного обучения и обработки данных. После загрузки этого образа этот Dockerfile устанавливает точку входа для обучающего кода.
Шаг 2. Создайте контейнер.
В своем терминале выполните следующую команду, чтобы определить переменную env для вашего проекта, обязательно заменяя your-cloud-project
идентификатором вашего проекта:
PROJECT_ID='your-cloud-project'
Определите переменную с URI вашего образа контейнера в реестре контейнеров Google:
IMAGE_URI="gcr.io/$PROJECT_ID/horse-human-codelab:latest"
Настроить Докер
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.
Импортируйте Vertex AI Python 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": 2
},
"replica_count": 1,
"container_spec": {
"image_uri": "gcr.io/{PROJECT_ID}/horse-human-codelab:latest"
}
}]
Затем определите parameter_spec
— словарь, определяющий параметры, которые вы хотите оптимизировать. Ключ словаря — это строка, которую вы назначили аргументу командной строки для каждого гиперпараметра, а значение словаря — это спецификация параметра.
Для каждого гиперпараметра необходимо определить тип, а также границы значений, которые будет использовать служба настройки. Гиперпараметры могут иметь тип Double, Integer, Категориальный или Дискретный. Если вы выберете тип Double или Integer, вам потребуется указать минимальное и максимальное значение. И если вы выберете Категориальный или Дискретный, вам нужно будет указать значения. Для типов 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: вы можете установить алгоритм поиска по сетке, случайный или по умолчанию (Нет). Опция по умолчанию применяет байесовскую оптимизацию для поиска в пространстве возможных значений гиперпараметра и является рекомендуемым алгоритмом. Подробнее об этом алгоритме можно узнать здесь.
Как только задание начнется, вы сможете отслеживать его статус в пользовательском интерфейсе на вкладке ЗАДАНИЯ НАСТРОЙКИ ГИПЕРПАРАМЕТРОВ .
После завершения задания вы можете просмотреть и отсортировать результаты испытаний, чтобы найти наилучшее сочетание значений гиперпараметров.
🎉Поздравляем! 🎉
Вы узнали, как использовать Vertex AI, чтобы:
- Запустите задание по настройке гиперпараметров с распределенным обучением.
Чтобы узнать больше о различных частях Vertex AI, ознакомьтесь с документацией .
8. Очистка
Поскольку мы настроили блокнот на тайм-аут после 60 минут простоя, нам не нужно беспокоиться об отключении экземпляра. Если вы хотите вручную завершить работу экземпляра, нажмите кнопку «Стоп» в разделе консоли Vertex AI Workbench. Если вы хотите полностью удалить блокнот, нажмите кнопку «Удалить».
Чтобы удалить сегмент хранилища, в меню навигации облачной консоли перейдите к разделу «Хранилище», выберите сегмент и нажмите «Удалить»: