Поделиться через


Создание и запуск конвейеров машинного обучения с помощью компонентов с пакетом SDK машинного обучения версии 2

ОБЛАСТЬ ПРИМЕНЕНИЯ: Пакет SDK для Python azure-ai-ml версии 2 (current)

В этой статье вы узнаете, как создать конвейер Машинного обучения Azure с помощью пакета SDK Python для Машинного обучения Azure версии 2 для выполнения задачи классификации изображений, содержащей три шага: подготовка данных, обучение модели классификации изображений и оценка модели. Конвейеры машинного обучения оптимизируют рабочий процесс со скоростью, переносимостью и повторное использование, чтобы сосредоточиться на машинном обучении вместо инфраструктуры и автоматизации.

Пример конвейера обучает небольшую сверточную нейронную сеть Keras для классификации изображений в наборе данных Fashion MNIST. Конвейер выглядит следующим образом:

Снимок экрана: граф конвейера примера классификации изображений.

В этой статье вы выполните следующие задачи:

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

Если у вас нет подписки Azure, создайте бесплатную учетную запись, прежде чем приступить к работе. Опробуйте бесплатную или платную версию Машинного обучения Azure уже сегодня.

Предварительные условия

  • Рабочая область Машинного обучения Azure. Если у вас нет ресурсов, выполните руководство по созданию ресурсов.

  • Среда Python, в которой вы установили пакет SDK Python для Машинного обучения Azure версии 2. Инструкции по установке см. в разделе "Начало работы". Эта среда предназначена для определения и управления ресурсами машинного обучения Azure и отличается от среды, используемой во время выполнения для обучения.

  • Клон репозитория примеров.

    Чтобы запустить учебные примеры, сначала клонируйте репозиторий примеров и перейдите в каталог sdk.

    git clone --depth 1 https://github.com/Azure/azureml-examples
    cd azureml-examples/sdk
    

Запуск интерактивного сеанса Python

В этой статье используется SDK для Python Azure Machine Learning для создания и управления конвейером машинного обучения Azure. Статья написана на основе предположения, что вы будете запускать фрагменты кода в интерактивном режиме в среде Python REPL или записной книжке Jupyter.

Эта статья основана на записной книжке image_classification_keras_minist_convnet.ipynb , которую можно найти в sdk/python/jobs/pipelines/2e_image_classification_keras_minist_convnet каталоге репозитория примеров машинного обучения Azure .

Импорт обязательных библиотек

Импортируйте все библиотеки машинного обучения Azure, необходимые для этой статьи:

# import required libraries
from azure.identity import DefaultAzureCredential, InteractiveBrowserCredential

from azure.ai.ml import MLClient
from azure.ai.ml.dsl import pipeline
from azure.ai.ml import load_component

Подготовка входных данных для задания конвейера

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

Мода MNIST — это набор данных образов моды, разделенных на 10 классов. Каждое изображение имеет размер 28 x 28 и выполнено в оттенках серого. Существует 60 000 обучающих изображений и 10 000 тестовых изображений. С точки зрения задачи классификации изображений, Fashion MNIST является более сложной, чем классический набор данных MNIST для распознавания рукописных цифр. Она распространяется в той же сжатой двоичной форме, что и исходная база данных с рукописными цифрами.

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

Создание компонентов для создания конвейера

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

Компонент Машинного обучения Azure — это автономный фрагмент кода, который выполняет один шаг в конвейере машинного обучения. В этой статье вы создадите три компонента для задачи классификации изображений:

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

Для каждого компонента необходимо выполнить следующие действия.

  1. Подготовьте скрипт Python, содержащий логику выполнения.

  2. Определите интерфейс компонента.

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

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

Создание компонента подготовки данных

Первый компонент в этом конвейере преобразует сжатые файлы данных из fashion_ds в два файла .csv: один для обучения и другой для оценки. Для определения этого компонента используется функция Python.

Если вы используете пример в репозитории машинного обучения Azure, исходные файлы уже доступны в папке prep . Эта папка содержит два файла для создания компонента: prep_component.pyкоторый определяет компонент и conda.yamlопределяет среду выполнения компонента.

Определение компонента с помощью функции Python

Используя command_component() функцию в качестве декоратора, можно легко определить интерфейс компонента, его метаданные и код, выполняемый из функции Python. Каждая декорированная функция Python будет преобразована в одну статическую спецификацию (YAML), которая обрабатывается потоковой службой.

# Converts MNIST-formatted files at the passed-in input path to training data output path and test data output path
import os
from pathlib import Path
from mldesigner import command_component, Input, Output


@command_component(
    name="prep_data",
    version="1",
    display_name="Prep Data",
    description="Convert data to CSV file, and split to training and test data",
    environment=dict(
        conda_file=Path(__file__).parent / "conda.yaml",
        image="mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04",
    ),
)
def prepare_data_component(
    input_data: Input(type="uri_folder"),
    training_data: Output(type="uri_folder"),
    test_data: Output(type="uri_folder"),
):
    convert(
        os.path.join(input_data, "train-images-idx3-ubyte"),
        os.path.join(input_data, "train-labels-idx1-ubyte"),
        os.path.join(training_data, "mnist_train.csv"),
        60000,
    )
    convert(
        os.path.join(input_data, "t10k-images-idx3-ubyte"),
        os.path.join(input_data, "t10k-labels-idx1-ubyte"),
        os.path.join(test_data, "mnist_test.csv"),
        10000,
    )


def convert(imgf, labelf, outf, n):
    f = open(imgf, "rb")
    l = open(labelf, "rb")
    o = open(outf, "w")

    f.read(16)
    l.read(8)
    images = []

    for i in range(n):
        image = [ord(l.read(1))]
        for j in range(28 * 28):
            image.append(ord(f.read(1)))
        images.append(image)

    for image in images:
        o.write(",".join(str(pix) for pix in image) + "\n")
    f.close()
    o.close()
    l.close()

Предыдущий код определяет компонент с отображаемым именем Prep Data с помощью @command_component декоратора:

  • name — уникальный идентификатор компонента.

  • version — текущая версия компонента. Компонент может иметь несколько версий.

  • display_name — понятное отображаемое имя компонента для пользовательского интерфейса. Это не уникально.

  • description обычно описывает задачу, которую компонент может выполнить.

  • environment указывает среду выполнения компонента. Среда этого компонента указывает образ Docker и ссылается на conda.yaml файл.

    Файл conda.yaml содержит все пакеты, используемые для компонента:

    name: imagekeras_prep_conda_env
    channels:
      - defaults
    dependencies:
      - python=3.7.11
      - pip=20.0
      - pip:
        - mldesigner==0.1.0b4
    
  • Функция prepare_data_component определяет один элемент входных данных для input_data и два элемента выходных данных для training_data и test_data. input_data — это путь к входным данным. training_data и test_data — пути к выходным данным для данных обучения и тестовых данных.

  • Компонент преобразует данные из input_data в training_data .csv для обучения и test_data .csv для тестирования.

Это то, как выглядит компонент в пользовательском интерфейсе студии:

  • Компонент представляет собой блок в графе конвейера.
  • input_data, training_dataи test_data являются портами компонента, которые подключаются к другим компонентам для потоковой передачи данных.

Снимок экрана компонента подготовки данных в пользовательском интерфейсе и коде.

Теперь вы подготовили все исходные Prep Data файлы для компонента.

Создание компонента обучения модели

В этом разделе вы создадите компонент для обучения модели классификации изображений в функции Python, как и в компоненте Prep Data .

Так как логика обучения сложнее, вы поместите код обучения в отдельный файл Python.

Исходные файлы этого компонента находятся в папке train в репозитории Azure Machine Learning. Эта папка содержит три файла для создания компонента:

  • train.py содержит логику для обучения модели.
  • train_component.py определяет интерфейс компонента и импортирует функцию, которая находится в train.py.
  • conda.yaml определяет среду выполнения компонента.

Получите скрипт, содержащий логику

Файл train.py содержит обычную функцию Python, которая выполняет логику обучения нейронной сети Keras для классификации изображений. Чтобы просмотреть код, ознакомьтесь с файлом train.py на GitHub.

Определение компонента с помощью функции Python

После определения функции обучения можно использовать @command_component в пакете SDK машинного обучения Azure версии 2 для упаковки функции в качестве компонента, который можно использовать в конвейерах машинного обучения Azure:

import os
from pathlib import Path
from mldesigner import command_component, Input, Output


@command_component(
    name="train_image_classification_keras",
    version="1",
    display_name="Train Image Classification Keras",
    description="train image classification with keras",
    environment=dict(
        conda_file=Path(__file__).parent / "conda.yaml",
        image="mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04",
    ),
)
def keras_train_component(
    input_data: Input(type="uri_folder"),
    output_model: Output(type="uri_folder"),
    epochs=10,
):
    # avoid dependency issue, execution logic is in train() func in train.py file
    from train import train

    train(input_data, output_model, epochs)

Предыдущий код определяет компонент, имеющий отображаемое имя Train Image Classification Keras с помощью @command_component.

  • Функция keras_train_component определяет один вход input_data для исходных обучающих данных, один вход epochs, который указывает количество эпох, используемых во время обучения, и один выход, output_model, который задает выходной путь для файла модели. Значение по умолчанию для параметра epochs — 10. Логика этого компонента основывается на train() функции в train.py.

Компонент обучающей модели имеет немного более сложную конфигурацию, чем компонент подготовки данных. Выглядит conda.yaml следующим образом:

name: imagekeras_train_conda_env
channels:
  - defaults
dependencies:
  - python=3.8
  - pip=20.2
  - pip:
    - mldesigner==0.1.0b12
    - azureml-mlflow==1.50.0
    - tensorflow==2.7.0
    - numpy==1.21.4
    - scikit-learn==1.0.1
    - pandas==1.3.4
    - matplotlib==3.2.2
    - protobuf==3.20.0

Теперь вы подготовили все исходные файлы для Train Image Classification Keras компонента.

Создание компонента оценки модели

В этом разделе описано, как создать компонент для оценки обученной модели с помощью спецификации YAML и скрипта.

Если вы используете пример в репозитории машинного обучения Azure, исходные файлы уже доступны в папке score . Эта папка содержит три файла для создания компонента:

  • score.py содержит исходный код компонента.
  • score.yaml определяет интерфейс и другие сведения о компоненте.
  • conda.yaml определяет среду выполнения компонента.

Получите скрипт, содержащий логику

Файл score.py содержит обычную функцию Python, которая выполняет логику модели обучения:

from tensorflow import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras.layers import BatchNormalization
from tensorflow.keras.utils import to_categorical
from keras.callbacks import Callback
from keras.models import load_model

import argparse
from pathlib import Path
import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
import mlflow


def get_file(f):

    f = Path(f)
    if f.is_file():
        return f
    else:
        files = list(f.iterdir())
        if len(files) == 1:
            return files[0]
        else:
            raise Exception("********This path contains more than one file*******")


def parse_args():
    # setup argparse
    parser = argparse.ArgumentParser()

    # add arguments
    parser.add_argument(
        "--input_data", type=str, help="path containing data for scoring"
    )
    parser.add_argument(
        "--input_model", type=str, default="./", help="input path for model"
    )

    parser.add_argument(
        "--output_result", type=str, default="./", help="output path for model"
    )

    # parse args
    args = parser.parse_args()

    # return args
    return args


def score(input_data, input_model, output_result):

    test_file = get_file(input_data)
    data_test = pd.read_csv(test_file, header=None)

    img_rows, img_cols = 28, 28
    input_shape = (img_rows, img_cols, 1)

    # Read test data
    X_test = np.array(data_test.iloc[:, 1:])
    y_test = to_categorical(np.array(data_test.iloc[:, 0]))
    X_test = (
        X_test.reshape(X_test.shape[0], img_rows, img_cols, 1).astype("float32") / 255
    )

    # Load model
    files = [f for f in os.listdir(input_model) if f.endswith(".h5")]
    model = load_model(input_model + "/" + files[0])

    # Log metrics of the model
    eval = model.evaluate(X_test, y_test, verbose=0)

    mlflow.log_metric("Final test loss", eval[0])
    print("Test loss:", eval[0])

    mlflow.log_metric("Final test accuracy", eval[1])
    print("Test accuracy:", eval[1])

    # Score model using test data
    y_predict = model.predict(X_test)
    y_result = np.argmax(y_predict, axis=1)

    # Output result
    np.savetxt(output_result + "/predict_result.csv", y_result, delimiter=",")


def main(args):
    score(args.input_data, args.input_model, args.output_result)


# run script
if __name__ == "__main__":
    # parse args
    args = parse_args()

    # call main function
    main(args)

Код в score.py принимает три аргумента командной строки: input_data, input_model и output_result. Программа оценивает входную модель с помощью входных данных, а затем выводит результат.

Определение компонента с помощью YAML

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

  • Метаданные. Имя, отображаемое имя, версия, тип и т. д.
  • Интерфейс. Входные и выходные данные.
  • Команды, код и среда. Команда, код и среда, используемая для запуска компонента.
$schema: https://azuremlschemas.azureedge.net/latest/commandComponent.schema.json
type: command

name: score_image_classification_keras
display_name: Score Image Classification Keras
inputs:
  input_data: 
    type: uri_folder
  input_model:
    type: uri_folder
outputs:
  output_result:
    type: uri_folder
code: ./
command: python score.py --input_data ${{inputs.input_data}} --input_model ${{inputs.input_model}} --output_result ${{outputs.output_result}}
environment:
  conda_file: ./conda.yaml
  image: mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04
  • name — уникальный идентификатор компонента. Его отображаемое имя — Score Image Classification Keras.
  • Этот компонент содержит два элемента входных данных и один элемент выходных данных.
  • Путь к исходному коду определен в секции code. При запуске компонента в облаке все файлы из указанного пути будут загружены как снимок состояния компонента.
  • В command разделе указывается команда, выполняемая при запуске компонента.
  • В environment разделе содержится образ Docker и файл CONDA YAML. Исходный файл находится в репозитории с примерами.

Теперь у вас есть все исходные файлы для компонента оценки модели.

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

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

Следующий код импортирует prepare_data_component() и keras_train_component() функции из prep_component.py файла в prep папке и train_component файл в папке train соответственно.

%load_ext autoreload
%autoreload 2

# load component function from component python file
from prep.prep_component import prepare_data_component
from train.train_component import keras_train_component

# print hint of components
help(prepare_data_component)
help(keras_train_component)

Функцию load_component() можно использовать для загрузки компонента оценки, определенного YAML.

# load component function from yaml
keras_score_component = load_component(source="./score/score.yaml")

Создание конвейера

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

Примечание.

Чтобы использовать бессерверные вычисления, добавьте from azure.ai.ml.entities import ResourceConfiguration в начало файла. Затем замените:

  • default_compute=cpu_compute_target с default_compute="serverless".
  • train_node.compute = gpu_compute_target с train_node.resources = "ResourceConfiguration(instance_type="Standard_NC6s_v3",instance_count=2).
# define a pipeline containing 3 nodes: Prepare data node, train node, and score node
@pipeline(
    default_compute=cpu_compute_target,
)
def image_classification_keras_minist_convnet(pipeline_input_data):
    """E2E image classification pipeline with keras using python sdk."""
    prepare_data_node = prepare_data_component(input_data=pipeline_input_data)

    train_node = keras_train_component(
        input_data=prepare_data_node.outputs.training_data
    )
    train_node.compute = gpu_compute_target

    score_node = keras_score_component(
        input_data=prepare_data_node.outputs.test_data,
        input_model=train_node.outputs.output_model,
    )


# create a pipeline
pipeline_job = image_classification_keras_minist_convnet(pipeline_input_data=mnist_ds)

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

Конвейер имеет входные данные на уровне конвейера pipeline_input_data. При отправке задания на конвейере можно присвоить значение входным данным.

Конвейер содержит три узла: prepare_data_node, train_nodeи score_node.

  • Элемент input_data в узле prepare_data_node использует значение pipeline_input_data.

  • train_node Результатом input_data является training_data вывод prepare_data_node.

  • Результатом input_datascore_node является test_data результат prepare_data_node, и input_model является output_modeltrain_node.

  • Так как train_node обучает модель CNN, вы можете указать ее вычисления в качестве gpu_compute_target. Это может повысить производительность обучения.

Отправьте задание конвейера

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

Получение доступа к рабочей области

Настройка учетных данных

Вы будете использовать DefaultAzureCredential для получения доступа к рабочей области. DefaultAzureCredential должен поддерживать большинство сценариев проверки подлинности пакета SDK для Azure.

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

try:
    credential = DefaultAzureCredential()
    # Check if given credential can get token successfully.
    credential.get_token("https://management.azure.com/.default")
except Exception as ex:
    # Fall back to InteractiveBrowserCredential in case DefaultAzureCredential not work
    credential = InteractiveBrowserCredential()

Получение дескриптора для рабочей области, имеющей вычислительные ресурсы

MLClient Создайте объект для управления службами Машинного обучения Azure. Если вы используете бессерверные вычисления, вам не нужно создавать эти вычисления.

# Get a handle to workspace
ml_client = MLClient.from_config(credential=credential)

# Retrieve an already attached Azure Machine Learning Compute.
cpu_compute_target = "cpu-cluster"
print(ml_client.compute.get(cpu_compute_target))
gpu_compute_target = "gpu-cluster"
print(ml_client.compute.get(gpu_compute_target))

Внимание

Этот фрагмент кода ожидает, что JSON-файл конфигурации рабочей области будет сохранен в текущем каталоге или родительском каталоге. Дополнительные сведения о создании рабочей области см. в разделе Создание ресурсов рабочей области. Дополнительные сведения о сохранении конфигурации в файл см. в разделе "Создание файла конфигурации рабочей области".

Отправьте задание конвейера в рабочую область

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

pipeline_job = ml_client.jobs.create_or_update(
    pipeline_job, experiment_name="pipeline_samples"
)
pipeline_job

Предыдущий код отправляет это задание конвейера классификации изображений в эксперимент с именем pipeline_samples. Он автоматически создает эксперимент, если он не существует. pipeline_input_data использует fashion_ds.

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

Эксперимент Имя. Тип Состояние Страница сведений
pipeline_samples sharp_pipe_4gvqx6h1fb конвейер Подготовка Ссылка на Студию машинного обучения Azure.

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

# wait until the job completes
ml_client.jobs.stream(pipeline_job.name)

Внимание

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

Проверка выходных данных и отладка конвейера в пользовательском интерфейсе

Вы можете выбрать Link to Azure Machine Learning studio, которая является страницей сведений о задании в вашем конвейере. Вы увидите граф конвейера:

Снимок экрана страницы сведений о задании конвейера.

Журналы и выходные данные каждого компонента можно проверить, щелкнув компонент правой кнопкой мыши или выбрав компонент, чтобы открыть ее область сведений. Дополнительные сведения об отладке конвейера в пользовательском интерфейсе см. в статье "Использование Студии машинного обучения Azure" для отладки сбоев конвейера.

(Необязательно) Зарегистрировать компоненты в рабочей области

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

try:
    # try get back the component
    prep = ml_client.components.get(name="prep_data", version="1")
except:
    # if not exists, register component using following code
    prep = ml_client.components.create_or_update(prepare_data_component)

# list all components registered in workspace
for c in ml_client.components.list():
    print(c)

Вы можете использовать ml_client.components.get() для получения зарегистрированного компонента по имени и версии. Можно использовать ml_client.components.create_or_update() для регистрации компонента, который ранее был загружен из функции Python или YAML.

Следующие шаги