В предыдущих статьях мы видели, как использовать Google Cloud AI Platform для обучения модели.

В этой статье мы рассмотрим, как использовать Google Cloud AI Platform для выполнения настройки гиперпараметров.

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

Гиперпараметры содержат данные, которые регулируют сам процесс обучения.

Ваше обучающее приложение обрабатывает три категории данных при обучении вашей модели:

  • Ваши входные данные (также называемые данными обучения) - это набор отдельных записей (экземпляров), содержащих функции, важные для вашей задачи машинного обучения. Эти данные используются во время обучения для настройки вашей модели для точного прогнозирования новых экземпляров похожих данных. Однако значения в ваших входных данных никогда напрямую не становятся частью вашей модели.
  • Параметры вашей модели - это переменные, которые выбранный вами метод машинного обучения использует для адаптации к вашим данным. Например, глубокая нейронная сеть (DNN) состоит из узлов обработки (нейронов), в каждом из которых выполняется операция с данными при их перемещении по сети. Когда ваша DNN обучена, каждый узел имеет значение веса, которое сообщает вашей модели, какое влияние он оказывает на окончательный прогноз. Эти веса являются примером параметров вашей модели. Во многих отношениях параметры вашей модели являются моделью - именно они отличает вашу конкретную модель от других моделей того же типа, работающих с аналогичными данными.
  • Ваши гиперпараметры - это переменные, которые регулируют сам процесс обучения. Например, часть настройки глубокой нейронной сети заключается в том, чтобы решить, сколько скрытых слоев узлов использовать между входным и выходным слоями и сколько узлов должен использовать каждый слой. Эти переменные не имеют прямого отношения к обучающим данным. Это переменные конфигурации. Обратите внимание, что параметры меняются во время обучения, в то время как гиперпараметры обычно остаются постоянными во время работы.

Подробнее о настройке гиперпараметров можно прочитать здесь.

Пример в истории структурирован следующим образом:

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

Шаг 1. Подготовьте данные для обучения, проверки и установите переменные среды.

Мы создадим корзину и загрузим данные обучения и проверки. Также мы установим переменные окружения.

Установим переменные среды. Измените значения соответствующим образом.

REGION = '<<REGION_NAME>>'
ARTIFACT_STORE = 'gs://<<BUCKET_NAME>>'
PROJECT_ID = 'PROJECT_ID'
DATA_ROOT='{}/data'.format(ARTIFACT_STORE)
JOB_DIR_ROOT='{}/jobs'.format(ARTIFACT_STORE)
TRAINING_FILE_PATH='{}/{}/{}'.format(DATA_ROOT, 'training', 'dataset.csv')
VALIDATION_FILE_PATH='{}/{}/{}'.format(DATA_ROOT, 'validation', 'dataset.csv')

Загрузите набор данных для обучения и проверки и загрузите его в соответствующем сегменте Google Cloud Storage.

!wget https://gist.githubusercontent.com/jainsourabh2/6d929697c95484fcc13edec93243b5c0/raw/99472a73f7509c7a3e31b354ce791cf1a40f0d6f/training_dataset_custom_container.csv
!wget https://gist.githubusercontent.com/jainsourabh2/07ad8bca7caf0d02a0ca893490d59be6/raw/6707fb18fe12b7c701033c2a497030d977264d63/validation_dataset_custom_container.csv
gsutil mb gs://<<BUCKET_NAME>>/training
gsutil mb gs://<<BUCKET_NAME>>/validation
gsutil cp training_dataset_custom_container.csv gs://<<BUCKET_NAME>>/training
gsutil cp validation_dataset_custom_container.csv gs://<<BUCKET_NAME>>/validation

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

Теперь мы создадим папку и напишем полный код в файл. Затем этот файл будет использован для создания контейнера на следующем шаге.

TRAINING_APP_FOLDER = 'training_app_story'
os.makedirs(TRAINING_APP_FOLDER, exist_ok=True)

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

%%writefile {TRAINING_APP_FOLDER}/train.py
import os
import subprocess
import sys
import fire
import pickle
import numpy as np
import pandas as pd
import hypertune
from sklearn.compose import ColumnTransformer
from sklearn.linear_model import SGDClassifier
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler, OneHotEncoder
def train_evaluate(job_dir, training_dataset_path, validation_dataset_path, alpha, max_iter, hptune):
    
    df_train = pd.read_csv(training_dataset_path)
    df_validation = pd.read_csv(validation_dataset_path)
if not hptune:
        df_train = pd.concat([df_train, df_validation])
numeric_feature_indexes = slice(0, 10)
    categorical_feature_indexes = slice(10, 12)
preprocessor = ColumnTransformer(
    transformers=[
        ('num', StandardScaler(), numeric_feature_indexes),
        ('cat', OneHotEncoder(), categorical_feature_indexes) 
    ])
pipeline = Pipeline([
        ('preprocessor', preprocessor),
        ('classifier', SGDClassifier(loss='log',tol=1e-3))
    ])
num_features_type_map = {feature: 'float64' for feature in df_train.columns[numeric_feature_indexes]}
    df_train = df_train.astype(num_features_type_map)
    df_validation = df_validation.astype(num_features_type_map)
print('Starting training: alpha={}, max_iter={}'.format(alpha, max_iter))
    X_train = df_train.drop('Cover_Type', axis=1)
    y_train = df_train['Cover_Type']
pipeline.set_params(classifier__alpha=alpha, classifier__max_iter=max_iter)
    pipeline.fit(X_train, y_train)
if hptune:
        X_validation = df_validation.drop('Cover_Type', axis=1)
        y_validation = df_validation['Cover_Type']
        accuracy = pipeline.score(X_validation, y_validation)
        print('Model accuracy: {}'.format(accuracy))
        # Log it with hypertune
        hpt = hypertune.HyperTune()
        hpt.report_hyperparameter_tuning_metric(
          hyperparameter_metric_tag='accuracy',
          metric_value=accuracy
        )
# Save the model
    if not hptune:
        model_filename = 'model.pkl'
        with open(model_filename, 'wb') as model_file:
            pickle.dump(pipeline, model_file)
        gcs_model_path = "{}/{}".format(job_dir, model_filename)
        subprocess.check_call(['gsutil', 'cp', model_filename, gcs_model_path], stderr=sys.stdout)
        print("Saved model in: {}".format(gcs_model_path)) 
    
if __name__ == "__main__":
    fire.Fire(train_evaluate)

Важный момент приведенного выше кода:

  • Мы определили функцию, которая принимает следующие параметры:
job_dir -> GCS Path for storing the job packages & model.
training_dataset_path -> GCS path holding training dataset.
validation_dataset_path -> GCS path holding validation dataset.
alpha -> hyperparameter
max_iter -> hyperparameter
hptune -> variable to decide if hyperparameter tuning is to be done or not.
  • Мы используем пакет hypertune, чтобы сообщить метрику оптимизации точности в службу настройки гиперпараметров AI Platform.
  • Обучающий конвейер выполняет предварительную обработку данных путем стандартизации всех числовых функций с использованием sklearn.preprocessing.StandardScaler и кодирования всех категориальных функций с помощью sklearn.preprocessing.OneHotEncoder
  • Если необходимо выполнить настройку гиперпараметров, мы не создаем модель. Если этого не требуется, мы генерируем модель и копируем ее в путь GCS.

Шаг 3. Создайте собственный контейнер для обучения модели.

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

%%writefile {TRAINING_APP_FOLDER}/Dockerfile
FROM gcr.io/deeplearning-platform-release/base-cpu
RUN pip install -U fire cloudml-hypertune scikit-learn==0.20.4 pandas==0.24.2
WORKDIR /app
COPY train.py .
ENTRYPOINT ["python", "train.py"]

Теперь мы создадим контейнер, используя следующие команды.

IMAGE_NAME='trainer_image_story'
IMAGE_TAG='latest'
IMAGE_URI='gcr.io/{}/{}:{}'.format(PROJECT_ID, IMAGE_NAME, IMAGE_TAG)
!gcloud builds submit --tag $IMAGE_URI $TRAINING_APP_FOLDER

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

Шаг 4. Создайте файл конфигурации гиперпараметров.

Мы не будем создавать файл конфигурации гиперпараметров, который необходимо передавать в качестве входных данных для задания по обучению модели. На этом шаге в папке training_app_story будет создан файл hptuning_config.yaml. Здесь мы можем установить желаемую конфигурацию. Важно помнить, что нам нужно указать диапазон параметров, а не каждое из отдельных значений. Платформа AI выполнит обучение на основе результатов испытаний и установит следующий набор значений для настройки гиперпараметров. Подробнее о технических характеристиках можно прочитать здесь.

%%writefile {TRAINING_APP_FOLDER}/hptuning_config.yaml
trainingInput:
  hyperparameters:
    goal: MAXIMIZE
    maxTrials: 6
    maxParallelTrials: 3
    hyperparameterMetricTag: accuracy
    enableTrialEarlyStopping: TRUE 
    params:
    - parameterName: max_iter
      type: DISCRETE
      discreteValues: [
          200,
          500
          ]
    - parameterName: alpha
      type: DOUBLE
      minValue:  0.00001
      maxValue:  0.001
      scaleType: UNIT_LINEAR_SCALE

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

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

JOB_NAME = "JOB_{}".format(time.strftime("%Y%m%d_%H%M%S"))
JOB_DIR = "{}/{}".format(JOB_DIR_ROOT, JOB_NAME)
SCALE_TIER = "BASIC"
!gcloud ai-platform jobs submit training $JOB_NAME \
--region=$REGION \
--job-dir=$JOB_DIR \
--master-image-uri=$IMAGE_URI \
--scale-tier=$SCALE_TIER \
--config $TRAINING_APP_FOLDER/hptuning_config.yaml \
-- \
--training_dataset_path=$TRAINING_FILE_PATH \
--validation_dataset_path=$VALIDATION_FILE_PATH \
--hptune

Вышеупомянутый шаг отправит задание с выводом ниже. Приведенные ниже выходные данные показывают, что задание было успешно отправлено в задания платформы AI. Вы можете перейти к заданию AI Platform Jobs и проверить его.

Job [JOB_20200809_181711] submitted successfully.
Your job is still active. You may view the status of your job with the command

  $ gcloud ai-platform jobs describe JOB_20200809_181711

or continue streaming the logs with the command

  $ gcloud ai-platform jobs stream-logs JOB_20200809_181711
jobId: JOB_20200809_181711
state: QUEUED

Мы можем контролировать работу, используя команду ниже.

!gcloud ai-platform jobs describe $JOB_NAME

Результат будет аналогичен приведенному ниже. Это займет несколько минут, так как всего будет проведено 6 испытаний с 3 параллельными. После завершения задания состояние изменится с ВЫПОЛНЯЕТСЯ на УСПЕШНО. Переходите к следующим шагам только после их успешного завершения.

createTime: '2020-08-09T18:17:13Z'
etag: bI3ZLmws8Ek=
jobId: JOB_20200809_181711
startTime: '2020-08-09T18:17:15Z'
state: RUNNING
trainingInput:
  args:
  - --training_dataset_path=gs://bucket/data/training/training_dataset_custom_container.csv
  - --validation_dataset_path=gs://bucket/data/validation/validation_dataset_custom_container.csv
  - --hptune
  hyperparameters:
    enableTrialEarlyStopping: true
    goal: MAXIMIZE
    hyperparameterMetricTag: accuracy
    maxParallelTrials: 3
    maxTrials: 6
    params:
    - discreteValues:
      - 200.0
      - 500.0
      parameterName: max_iter
      type: DISCRETE
    - maxValue: 0.001
      minValue: 1e-05
      parameterName: alpha
      scaleType: UNIT_LINEAR_SCALE
      type: DOUBLE
  jobDir: gs://bucket/jobs/JOB_20200809_181711
  masterConfig:
    imageUri: gcr.io/project_id/trainer_image_story:latest
  region: region
trainingOutput:
  hyperparameterMetricTag: accuracy
  isHyperparameterTuningJob: true

View job in the Cloud Console at:
https://console.cloud.google.com/mlengine/jobs/JOB_20200809_181711?project=project_id

View logs at:
https://console.cloud.google.com/logs?resource=ml.googleapis.com%2Fjob_id%2FJOB_20200809_181711&project=project_id

Шаг 6. Получите наиболее оптимизированную пробную версию задания по обучению модели гиперпараметров.

Теперь мы получим значения alpha и max_tier, для которых мы получили оптимизированную цель, то есть максимальную точность.

ml = discovery.build('ml', 'v1')
job_id = 'projects/{}/jobs/{}'.format(PROJECT_ID, JOB_NAME)
request = ml.projects().jobs().get(name=job_id)
try:
    response = request.execute()
except errors.HttpError as err:
    print(err)
except:
    print("Unexpected error")
    
response

Приведенный выше скрипт получит вывод задания. Возвращенные результаты выполнения сортируются по значению показателя оптимизации. Лучшее выполнение - это первый элемент в возвращаемом списке. Давайте получим то же самое, выполнив следующие команды.

response['trainingOutput']['trials'][0]
alpha = response['trainingOutput']['trials'][0]['hyperparameters']['alpha']
max_iter = response['trainingOutput']['trials'][0]['hyperparameters']['max_iter']

Шаг 7. Отправьте задание на обучение, используя указанное выше значение гиперпараметров.

Теперь мы запустим обучение модели с использованием этих конкретных параметров. Модель вывода будет доступна в пути GCS, совместно используемом при отправке задания.

JOB_NAME = "JOB_{}".format(time.strftime("%Y%m%d_%H%M%S"))
JOB_DIR = "{}/{}".format(JOB_DIR_ROOT, JOB_NAME)
SCALE_TIER = "BASIC"
!gcloud ai-platform jobs submit training $JOB_NAME \
--region=$REGION \
--job-dir=$JOB_DIR \
--master-image-uri=$IMAGE_URI \
--scale-tier=$SCALE_TIER \
-- \
--training_dataset_path=$TRAINING_FILE_PATH \
--validation_dataset_path=$VALIDATION_FILE_PATH \
--alpha=$alpha \
--max_iter=$max_iter \
--nohptune

Я надеюсь, что это дало вам краткое введение в использование настройки гиперпараметров на платформе Google Cloud AI.

Пример кода приведен по следующему URL-адресу:

Https://github.com/GoogleCloudPlatform/mlops-on-gcp/blob/master/workshops/kfp-caip-sklearn/lab-01-caip-containers/lab-01.ipynb