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


Создание и запуск конвейеров машинного обучения с помощью компонентов с пакетом 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

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 являются портами компонента, которые подключаются к другим компонентам для потоковой передачи данных

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

Теперь вы подготовили все исходные 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")

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

Примечание.

Чтобы загрузить зарегистрированные компоненты из рабочей области, необходимо сначала настроить подключение рабочей области, как описано в разделе "Получение доступа к рабочей области ". Объект 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.

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