Vytváření a spouštění kanálů strojového učení pomocí komponent se sadou Azure Machine Učení SDK v2

PLATÍ PRO: Python SDK azure-ai-ml v2 (aktuální)

V tomto článku se dozvíte, jak vytvořit kanál Azure Machine Učení pomocí sady Python SDK v2 k dokončení úlohy klasifikace obrázků obsahující tři kroky: přípravu dat, trénování modelu klasifikace obrázků a určení skóre modelu. Kanály strojového učení optimalizují pracovní postup rychlostí, přenositelností a opětovným použitím, abyste se mohli soustředit na strojové učení místo infrastruktury a automatizace.

Příklad trénuje malou kerasovou konvoluční neurální síť, aby klasifikovala obrázky v datové sadě Fashion MNIST . Kanál vypadá takto.

Snímek obrazovky znázorňující graf kanálu příkladu klasifikace obrázků Keras

V tomto článku dokončíte následující úlohy:

  • Příprava vstupních dat pro úlohu kanálu
  • Vytvoření tří komponent pro přípravu dat, trénování a hodnocení
  • Vytvoření kanálu z komponent
  • Získání přístupu k pracovnímu prostoru pomocí výpočetních prostředků
  • Odeslání úlohy kanálu
  • Kontrola výstupu komponent a natrénované neurální sítě
  • (Volitelné) Registrace komponenty pro další použití a sdílení v rámci pracovního prostoru

Pokud ještě nemáte předplatné Azure, vytvořte si napřed bezplatný účet. Vyzkoušejte si bezplatnou nebo placenou verzi služby Azure Machine Učení ještě dnes.

Požadavky

  • Pracovní prostor azure machine Učení – pokud ho nemáte, dokončete kurz Vytvoření prostředků.

  • Prostředí Pythonu, ve kterém jste nainstalovali sadu Azure Machine Učení Python SDK v2 – pokyny k instalaci – projděte si část Začínáme. Toto prostředí slouží k definování a řízení prostředků azure machine Učení a je oddělené od prostředí používaného za běhu pro trénování.

  • Úložiště klonování příkladů

    Pokud chcete spustit trénovací příklady, nejprve naklonujte úložiště příkladů a změňte ho do sdk adresáře:

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

Spuštění interaktivní relace Pythonu

Tento článek používá sadu Python SDK pro Azure Machine Učení k vytvoření a řízení kanálu azure machine Učení. V článku se předpokládá, že fragmenty kódu budete spouštět interaktivně v prostředí Python REPL nebo v poznámkovém bloku Jupyter.

Tento článek vychází z poznámkového bloku image_classification_keras_minist_convnet.ipynb nalezeného v sdk/python/jobs/pipelines/2e_image_classification_keras_minist_convnet adresáři úložiště Azure Machine Učení Examples.

Import požadovaných knihoven

Naimportujte všechny požadované knihovny azure machine Učení, které budete potřebovat pro tento článek:

# 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

Příprava vstupních dat pro úlohu kanálu

Potřebujete připravit vstupní data pro tento kanál klasifikace obrázků.

Fashion-MNIST je datová sada módních obrázků rozdělených do 10 tříd. Každý obrázek je 28 × 28 stupňů šedé a existuje 60 000 trénovacích a 10 000 testovacích obrázků. Jako problém klasifikace obrázků je Fashion-MNIST těžší než klasická ručně psaná databáze MNIST. Distribuuje se ve stejné komprimované binární podobě jako původní ručně psaná databáze číslic.

Importujte všechny požadované knihovny azure machine Učení, které budete potřebovat.

Definováním objektu Inputvytvoříte odkaz na umístění zdroje dat. Data zůstávají v existujícím umístění, takže se neúčtují žádné další náklady na úložiště.

Vytváření komponent pro vytváření kanálu

Úkol klasifikace obrázků je možné rozdělit do tří kroků: příprava dat, trénování modelu a určení skóre modelu.

Komponenta Azure Machine Učení je samostatná část kódu, která provádí jeden krok v kanálu strojového učení. V tomto článku vytvoříte tři komponenty pro úlohu klasifikace obrázků:

  • Příprava dat na trénování a testování
  • Trénování neurální sítě pro klasifikaci obrázků pomocí trénovacích dat
  • Určení skóre modelu pomocí testovacích dat

Pro každou komponentu je potřeba připravit následující:

  1. Příprava skriptu Pythonu obsahujícího logiku spouštění

  2. Definování rozhraní komponenty

  3. Přidejte další metadata komponenty, včetně prostředí za běhu, příkazu ke spuštění komponenty atd.

V další části se zobrazí komponenty vytvoření dvěma různými způsoby: první dvě komponenty používající funkci Pythonu a třetí komponentu pomocí definice YAML.

Vytvoření komponenty pro přípravu dat

První komponenta v tomto kanálu převede komprimované datové soubory fashion_ds ze dvou souborů CSV, jeden pro trénování a druhý pro bodování. K definování této komponenty použijete funkci Pythonu.

Pokud sledujete společně s příkladem v úložišti azure Machine Učení příklady, zdrojové soubory už jsou ve složce dostupnéprep/. Tato složka obsahuje dva soubory pro vytvoření komponenty: prep_component.py, která definuje komponentu a conda.yaml, která definuje prostředí za běhu komponenty.

Definování komponenty pomocí funkce Pythonu

Pomocí command_component() funkce jako dekorátoru můžete snadno definovat rozhraní komponenty, metadata a kód, které se mají spouštět z funkce Pythonu. Každá zdobená funkce Pythonu se transformuje na jednu statickou specifikaci (YAML), kterou může služba kanálu zpracovat.

# 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()

Výše uvedený kód definuje komponentu se zobrazovaným názvem Prep Data pomocí @command_component dekorátoru:

  • name je jedinečný identifikátor komponenty.

  • version je aktuální verze komponenty. Komponenta může mít více verzí.

  • display_name je popisný zobrazovaný název komponenty v uživatelském rozhraní, který není jedinečný.

  • description obvykle popisuje, jakou úlohu může tato komponenta dokončit.

  • environment určuje prostředí za běhu pro tuto komponentu. Prostředí této komponenty určuje image Dockeru a odkazuje na conda.yaml soubor.

    Soubor conda.yaml obsahuje všechny balíčky používané pro komponentu, například následující:

    name: imagekeras_prep_conda_env
    channels:
      - defaults
    dependencies:
      - python=3.7.11
      - pip=20.0
      - pip:
        - mldesigner==0.1.0b4
    
  • Funkce prepare_data_component definuje jeden vstup pro input_data a dva výstupy pro training_data a test_data. input_data je vstupní cesta k datům. training_data a test_data jsou výstupní datové cesty pro trénovací data a testovací data.

  • Tato komponenta převede data z input_data trénovacích dat do training_data souboru CSV s testovacími daty do souboru CSV s test_datatestovacími daty .

Následuje, jak komponenta vypadá v uživatelském rozhraní studia.

  • Komponenta je blok v grafu kanálu.
  • training_data Jsou input_datato test_data porty komponenty, které se připojují k dalším komponentám pro streamování dat.

Snímek obrazovky komponenty Prep Data v uživatelském rozhraní a kódu

Teď jste připravili všechny zdrojové soubory pro komponentu Prep Data .

Vytvoření komponenty train-model

V této části vytvoříte komponentu pro trénování modelu klasifikace obrázků ve funkci Pythonu, jako je tato komponenta Prep Data .

Rozdíl je v tom, že vzhledem k tomu, že je logika trénování složitější, můžete původní trénovací kód vložit do samostatného souboru Pythonu.

Zdrojové soubory této komponenty jsou ve train/ složce v úložišti Azure Machine Učení příklady. Tato složka obsahuje tři soubory pro vytvoření komponenty:

  • train.py: obsahuje skutečnou logiku pro trénování modelu.
  • train_component.py: definuje rozhraní komponenty a importuje funkci v train.py.
  • conda.yaml: definuje běhové prostředí komponenty.

Získání skriptu obsahujícího logiku spouštění

Soubor train.py obsahuje normální funkci Pythonu, která provádí logiku trénovacího modelu pro trénování neurální sítě Keras pro klasifikaci obrázků. Pokud chcete kód zobrazit, podívejte se na soubor train.py na GitHubu.

Definování komponenty pomocí funkce Pythonu

Po úspěšném definování trénovací funkce můžete pomocí @command_component sady Azure Machine Učení SDK v2 zabalit funkci jako součást, kterou je možné použít v kanálech Azure Machine Učení.

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)

Výše uvedený kód definuje komponentu se zobrazovaným názvem Train Image Classification Keras pomocí @command_component:

  • Funkce keras_train_component definuje jeden vstup input_data , ze kterého trénovací data pocházejí, jeden vstup epochs určující epochy během trénování a jeden výstup output_model , ve kterém se vypíše soubor modelu. Výchozí hodnota epochs je 10. Logika provádění této komponenty je z train() funkce výše train.py .

Komponenta modelu trénování má o něco složitější konfiguraci než komponenta prep-data. Vypadá to conda.yaml takto:

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

Teď jste připravili všechny zdrojové soubory pro komponentu Train Image Classification Keras .

Vytvoření komponenty modelu výkonnostních metrik

V této části, kromě předchozích komponent, vytvoříte komponentu pro určení skóre natrénovaného modelu pomocí specifikace a skriptu Yaml.

Pokud sledujete společně s příkladem v úložišti azure Machine Učení příklady, zdrojové soubory už jsou ve složce dostupnéscore/. Tato složka obsahuje tři soubory pro vytvoření komponenty:

  • score.py: obsahuje zdrojový kód komponenty.
  • score.yaml: definuje rozhraní a další podrobnosti komponenty.
  • conda.yaml: definuje běhové prostředí komponenty.

Získání skriptu obsahujícího logiku spouštění

Soubor score.py obsahuje normální funkci Pythonu, která provádí logiku trénovacího modelu.

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)

Kód v score.py přebírá tři argumenty příkazového řádku: input_datainput_model a output_result. Program vyhodnotuje vstupní model pomocí vstupních dat a pak vypíše výsledek vyhodnocování.

Definování komponenty přes Yaml

V této části se dozvíte, jak vytvořit specifikaci komponenty v platném formátu specifikace komponenty YAML. Tento soubor určuje následující informace:

  • Metadata: název, display_name, verze, typ atd.
  • Rozhraní: vstupy a výstupy
  • Příkaz, kód a prostředí: Příkaz, kód a prostředí použité ke spuštění komponenty
$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 je jedinečný identifikátor komponenty. Jeho zobrazovaný název je Score Image Classification Keras.
  • Tato komponenta má dva vstupy a jeden výstup.
  • Cesta ke zdrojovému kódu je definovaná v code části a při spuštění komponenty v cloudu se všechny soubory z této cesty nahrají jako snímek této komponenty.
  • Část command určuje příkaz, který se má spustit při spuštění této komponenty.
  • Tato environment část obsahuje image Dockeru a soubor conda yaml. Zdrojový soubor je v ukázkovém úložišti.

Teď máte všechny zdrojové soubory pro komponentu modelu skóre.

Načtení součástí do kanálu buildu

Pro komponentu prep-data a komponentu train-model definovanou funkcí Pythonu můžete importovat stejně jako běžné funkce Pythonu.

V následujícím kódu importujete prepare_data_component() a keras_train_component() budete pracovat ze prep_component.py souboru ve prep složce a train_component souboru ve train složce.

%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)

Pro komponentu skóre definovanou yaml můžete použít load_component() funkci k načtení.

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

Vytvoření kanálu

Teď, když jste vytvořili a načetli všechny komponenty a vstupní data pro sestavení kanálu. Můžete je vytvořit do kanálu:

Poznámka:

Pokud chcete používat bezserverové výpočetní prostředky, přidejte from azure.ai.ml.entities import ResourceConfiguration je na začátek. Potom nahraďte:

  • default_compute=cpu_compute_target, S default_compute="serverless",
  • train_node.compute = gpu_compute_target S 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)

Kanál má výchozí výpočetní prostředky cpu_compute_target, což znamená, že pokud neurčíte výpočetní prostředky pro konkrétní uzel, tento uzel se spustí na výchozím výpočetním prostředí.

Kanál má vstup pipeline_input_datana úrovni kanálu . Při odesílání úlohy kanálu můžete přiřadit hodnotu vstupu kanálu.

Kanál obsahuje tři uzly, prepare_data_node, train_node a score_node.

  • Hodnota input_dataprepare_data_node .pipeline_input_data

  • Hodnota input_datatrain_node je z training_data výstupu prepare_data_node.

  • Score_node input_data je z test_data výstupu prepare_data_node a input_model je z output_model train_node.

  • Vzhledem k tomu train_node , že model CNN vytrénuje, můžete jeho výpočetní prostředky zadat jako gpu_compute_target, což může zlepšit výkon trénování.

Odeslání úlohy kanálu

Teď jste vytvořili kanál, můžete ho odeslat do svého pracovního prostoru. Pokud chcete odeslat úlohu, musíte se nejprve připojit k pracovnímu prostoru.

Získání přístupu k pracovnímu prostoru

Konfigurace přihlašovacích údajů

K získání přístupu k pracovnímu prostoru použijeme DefaultAzureCredential . DefaultAzureCredential měla by být schopná zpracovat většinu scénářů ověřování sady Azure SDK.

Referenční informace k dalším dostupným přihlašovacím údajům, pokud pro vás nefungují: konfigurace příkladu přihlašovacích údajů, referenční dokumentace k azure-identitě.

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()

Získání popisovače pracovního prostoru pomocí výpočetních prostředků

Vytvořte MLClient objekt pro správu služeb Azure Machine Učení. Pokud používáte bezserverové výpočetní prostředky , není potřeba tyto výpočty vytvářet.

# 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))

Důležité

Tento fragment kódu očekává, že soubor JSON konfigurace pracovního prostoru se uloží do aktuálního adresáře nebo nadřazeného souboru. Další informace o vytvoření pracovního prostoru najdete v tématu Vytvoření prostředků pracovního prostoru. Další informace o uložení konfigurace do souboru naleznete v tématu Vytvoření konfiguračního souboru pracovního prostoru.

Odeslání úlohy kanálu do pracovního prostoru

Teď máte ke svému pracovnímu prostoru popisovač, můžete odeslat úlohu kanálu.

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

Výše uvedený kód odešle tuto úlohu kanálu klasifikace obrázků do experimentu s názvem pipeline_samples. Pokud experiment neexistuje, automaticky se vytvoří. fashion_dsPoužití pipeline_input_data .

Volání, které vytvoří pipeline_jobvýstup podobný následujícímu:

Volání dokončení submitExperiment se rychle dokončí a vytvoří výstup podobný následujícímu:

Experiment Name Type Stav Stránka podrobností
pipeline_samples sharp_pipe_4gvqx6h1fb Potrubí Příprava Odkaz na studio Azure Machine Learning

Spuštění kanálu můžete monitorovat tak, že odkaz otevřete nebo ho můžete zablokovat, dokud se nespustí spuštěním příkazu:

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

Důležité

První spuštění kanálu trvá přibližně 15 minut. Všechny závislosti se musí stáhnout, vytvoří se image Dockeru a prostředí Pythonu se zřídí a vytvoří. Opětovné spuštění kanálu trvá výrazně méně času, protože se tyto prostředky znovu používají místo vytvoření. Celková doba běhu kanálu ale závisí na úloze vašich skriptů a procesech spuštěných v jednotlivých krocích kanálu.

Rezervace výstupů a ladění kanálu v uživatelském rozhraní

Můžete otevřít Link to Azure Machine Learning studiostránku podrobností úlohy kanálu. Zobrazí se následující graf kanálu.

Snímek obrazovky se stránkou podrobností úlohy kanálu

Protokoly a výstupy jednotlivých komponent můžete zkontrolovat tak, že kliknete pravým tlačítkem na komponentu nebo vyberete komponentu a otevřete její podokno podrobností. Další informace o ladění kanálu v uživatelském rozhraní najdete v tématu Použití selhání kanálu ladění.

(Volitelné) Registrace komponent do pracovního prostoru

V předchozí části jste vytvořili kanál, který používá tři komponenty k dokončení úlohy klasifikace obrázků E2E. Do pracovního prostoru můžete také zaregistrovat komponenty, aby je bylo možné sdílet a znovu sdílet v rámci pracovního prostoru. Následuje příklad registrace komponenty prep-data.

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)

Pomocí ml_client.components.get(), můžete získat zaregistrovanou komponentu podle názvu a verze. Pomocí ml_client.components.create_or_update(), můžete zaregistrovat komponentu dříve načtenou z funkce Pythonu nebo yaml.

Další kroky