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


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

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

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

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

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

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

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

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

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

  • Рабочая область Машинного обучения Azure. Если у вас нет ресурсов, выполните руководство по созданию ресурсов.
  • Среда Python с установленной версией 2 Azure Machine Learning Python SDK. Инструкции по установке см. в разделе "Начало работы". Эта среда предназначена для определения и управления ресурсами машинного обучения 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 Machine Learning.

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

Импортируйте все библиотеки машинного обучения 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 тестовых изображений.

import urllib3
import shutil
import gzip
import os
from pathlib import Path
from azure.ai.ml import Input

base_url = "https://azureopendatastorage.blob.core.windows.net/mnist/"
base_dir = Path("mnist")
if not base_dir.exists():
    base_dir.mkdir(parents=True)

c = urllib3.PoolManager()
for target_file in [
    "train-images-idx3-ubyte.gz",
    "train-labels-idx1-ubyte.gz",
    "t10k-images-idx3-ubyte.gz",
    "t10k-labels-idx1-ubyte.gz",
]:
    if (base_dir / target_file[:-3]).exists():
        continue
    with c.request("GET", base_url + target_file, preload_content=False) as resp, open(
        base_dir / target_file, "wb"
    ) as out_file:
        shutil.copyfileobj(resp, out_file)
        resp.release_conn()
    with gzip.open(base_dir / target_file, "rb") as f_in, open(
        base_dir / target_file[:-3], "wb"
    ) as f_out:
        shutil.copyfileobj(f_in, f_out)
    os.unlink(base_dir / target_file)

mnist_ds = Input(path=base_dir.as_posix())

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

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

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

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

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

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

  1. Подготовьте скрипт Python, содержащий логику выполнения.
  2. Определите интерфейс компонента.
  3. Добавьте другие метаданные компонента, включая среду выполнения и команду для запуска компонента.

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

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

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

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

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

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

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 указывает среду выполнения для компонента с помощью 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_datatraining_data файла .csv для обучающих данных и test_data файла .csv для тестовых данных

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

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

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

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

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

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

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

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

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

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

Файл 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

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

В этом разделе описано, как создать компонент для оценки обученной модели с помощью спецификации и скрипта 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")

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

Примечание.

Чтобы загрузить зарегистрированные компоненты из рабочей области, сначала настройте подключение рабочей области, как описано в разделе "Получение доступа к рабочей области ". Объект ml_client требуется для следующих операций.

Если у вас есть компоненты, которые уже зарегистрированы в рабочей области, их можно загрузить непосредственно с помощью ml_client.components.get() метода. Этот подход полезен, если требуется повторно использовать компоненты, которые вы ранее зарегистрировали или предоставили другим участникам команды общий доступ.

# Load a registered component by name and version
registered_component = ml_client.components.get(
    name="my_registered_component", 
    version="1.0.0"
)

# Load the latest version of a registered component
latest_component = ml_client.components.get(
    name="my_registered_component"
)

Вы можете перечислить все доступные компоненты в рабочей области, чтобы найти нужные компоненты:

# List all components in the workspace
components = ml_client.components.list()
for component in components:
    print(f"Name: {component.name}, Version: {component.version}")

После загрузки их можно использовать зарегистрированные компоненты в конвейере точно так же, как компоненты, загруженные из локальных файлов или функций Python.

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

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

Примечание.

Чтобы использовать бессерверные вычисления, добавьте 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
  • input_data train_node является training_data выходом prepare_data_node
  • Результатом input_data является score_node вывод test_data, и prepare_data_node является результатом input_modeloutput_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.