Создание и запуск конвейеров машинного обучения с помощью компонентов с пакетом SDK Машинное обучение Azure версии 2
ОБЛАСТЬ ПРИМЕНЕНИЯ: Пакет SDK для Python azure-ai-ml версии 2 (current)
Из этой статьи вы узнаете, как создать конвейер Машинного обучения Azure с помощью пакета SDK для Python версии 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 для создания и управления конвейером Машинное обучение Azure. В этой статье предполагается, что вы будете запускать фрагменты кода в интерактивном режиме в среде Python REPL или в записной книжке Jupyter.
Эта статья основана на записной книжке image_classification_keras_minist_convnet.ipynb, найденной в sdk/python/jobs/pipelines/2e_image_classification_keras_minist_convnet
каталоге репозитория Машинное обучение Azure Examples.
Импорт обязательных библиотек
Импортируйте все библиотеки Машинного обучения 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
Подготовка входных данных для задания конвейера
Вам необходимо подготовить входные данные для этого конвейера классификации изображений.
Fashion-MNIST — это набор изображений объектов моды, разделенный на 10 классов. Каждое изображение представляет собой изображение в оттенках серого 28x28, и имеется 60 000 обучающих и 10 000 тестовых изображений. С точки зрения классификации изображений, Fashion-MNIST сложнее, чем классическая база данных MNIST с рукописными цифрами. Она распространяется в той же сжатой двоичной форме, что и исходная база данных с рукописными цифрами.
Импортируйте все необходимые Машинное обучение Azure необходимые библиотеки.
Определяя Input
, вы создаете ссылку на расположение источника данных. Данные хранятся только в исходном расположении, а значит не потребуется лишних расходов на хранение.
Создание компонентов для сборки конвейера
Задача классификации изображений может быть разделена на три этапа: подготовка данных, обучение модели и оценка модели.
Компонент Машинного обучения Azure — это автономный фрагмент кода, выполняющий один шаг в конвейере машинного обучения. В этой статье вы создадите три компонента для задачи классификации изображений:
- Подготовка данных для обучения и тестирования
- Обучение нейронной сети для классификации изображений с помощью обучающих данных
- Оценка модели с использованием тестовых данных
Для каждого компонента необходимо подготовить следующее:
Подготовка скрипта Python, содержащего логику выполнения
Определение интерфейса компонента
Добавление других метаданных компонента, включая среду выполнения, команду для запуска компонента и т. д.
В следующем разделе показано, как создать компоненты двумя разными способами: первые два компонента с помощью функции Python и третьего компонента с помощью определения YAML.
Создание компонента подготовки данных
Первый компонент в этом конвейере преобразует сжатые файлы данных fashion_ds
в два CSV-файла. Первый 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
в CSV-файл для данных обученияtraining_data
и в CSV-файл для тестовых данныхtest_data
.
Ниже показано, как выглядит компонент в пользовательском интерфейсе Студии.
- Компонент представляет собой блок в графе конвейера.
input_data
,training_data
иtest_data
— порты компонента, который подключается к другим компонентам для потоковой передачи данных.
Теперь вы подготовили все исходные файлы для компонента Prep Data
.
Создание компонента обучения модели
В этом разделе вы создадите компонент для обучения модели классификации изображений в функции Python, такой как Prep Data
компонент.
Разница заключается в том, что так как логика обучения сложнее, исходный код обучения можно поместить в отдельный файл Python.
Исходные файлы этого компонента находятся train/
в папке в репозитории Машинное обучение Azure. Эта папка содержит три файла для создания компонента:
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. В этом файле указывается следующая информация.
- Метаданные: имя, display_name, версия, тип и так далее.
- Интерфейс: входные и выходные данные
- Команда, код и среда: команда, код и среда, используемая для запуска компонента
$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 и файл YAML conda. Исходный файл находится в репозитории с примерами.
Теперь у вас есть все исходные файлы для компонента оценки модели.
Загрузка компонентов для создания конвейера
Для компонента подготовки данных и компонента модели обучения, определенного функцией 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)
Для загрузки компонента оценки, определенного с помощью YAML, можно использовать функцию load_component()
.
# 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
.Элемент
input_data
в узлеtrain_node
заполняется на основе выходных данныхtraining_data
узла prepare_data_node.Элемент
input_data
в узле score_node заполняется на основе элемента выходных данныхtest_data
в узле prepare_data_node, и элементinput_model
заполняется на основе элементаoutput_model
в узле train_node.Так как узел
train_node
будет обучать модель CNN, вы можете указать его вычислительные ресурсы в качестве параметра gpu_compute_target, что может повысить производительность обучения.
Отправка задания конвейера
Теперь вы создали конвейер и можете отправить его в рабочую область. Чтобы отправить задание, сначала необходимо подключиться к рабочей области.
Получение доступа к рабочей области
Настройка учетных данных
Мы будем использовать DefaultAzureCredential
для получения доступа к рабочей области. DefaultAzureCredential
должен поддерживать большинство сценариев проверки подлинности пакета SDK для Azure.
Если этот вариант вам не подходит, попробуйте использовать другие доступные учетные данные: пример настройки учетных данных, справочная документация по удостоверениям Azure.
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_job
имеют следующий вид:
Вызов submit
Experiment
завершается быстро и создает выходные данные примерно следующим образом:
Эксперимент | Имя. | Тип | Состояние | Страница сведений |
---|---|---|---|---|
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
, на которой приведены сведения о задании для конвейера. Вы увидите граф конвейера, похожий на приведенный ниже.
Вы можете проверить журналы и выходные данные каждого компонента, щелкнув компонент правой кнопкой мыши или выбрав компонент, чтобы открыть область сведений. Дополнительные сведения о отладке конвейера в пользовательском интерфейсе см. в статье "Использование сбоя конвейера отладки".
(Необязательно) Регистрация компонентов в рабочей области
В предыдущем разделе вы создали конвейер, используя три компонента, чтобы выполнить задачу классификации изображений, используя E2E. Вы также можете зарегистрировать компоненты в рабочей области, чтобы их можно было совместно и повторно использовать в рабочей области. Ниже приведен пример регистрации компонента подготовки данных.
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.
Следующие шаги
- Дополнительные примеры создания конвейеров с помощью пакета SDK для машинного обучения см. в репозитории примеров.
- Сведения об отправке и отладке конвейера с помощью пользовательского интерфейса Студии см. в разделе Создание конвейеров с помощью компонента в пользовательском интерфейсе.
- Сведения о создании компонентов и конвейеров с помощью CLI Машинного обучения Azure см. в разделе Создание конвейеров с использованием компонента с помощью CLI.
- Сведения о развертывании конвейеров в рабочей среде с помощью конечных точек пакетной службы см. в статье о развертывании конвейеров с помощью конечных точек пакетной службы.