Kurz: Vytvoření kanálu služby Azure Machine Learning pro klasifikaci obrázků

PLATÍ PRO:Sada Python SDK azureml v1

Poznámka

Kurz, který používá sadu SDK v2 k sestavení kanálu, najdete v tématu Kurz: Použití kanálů ML pro produkční pracovní postupy ML se sadou Python SDK v2 v Jupyter Notebook.

V tomto kurzu zjistíte, jak vytvořit kanál služby Azure Machine Learning pro přípravu dat a trénování modelu strojového učení. Kanály strojového učení optimalizují váš pracovní postup pomocí rychlosti, přenositelnosti a opakovaného použití, takže se můžete soustředit na strojové učení místo na infrastrukturu a automatizaci.

Příklad trénuje malou konvoluční neurální síť Keras ke klasifikaci obrázků v datové sadě Fashion MNIST .

V tomto kurzu provedete následující úlohy:

  • Konfigurace pracovního prostoru
  • Vytvoření experimentu pro uložení práce
  • Zřízení cílového výpočetního objektu pro práci
  • Vytvoření datové sady, do které se mají ukládat komprimovaná data
  • Vytvoření kroku kanálu pro přípravu dat pro trénování
  • Definování běhového prostředí, ve kterém se má provádět trénování
  • Vytvoření kroku kanálu pro definování neurální sítě a provedení trénování
  • Vytvoření kanálu z kroků kanálu
  • Spuštění kanálu v experimentu
  • Kontrola výstupu kroků a natrénované neurální sítě
  • Registrace modelu pro další použití

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

Požadavky

  • Pokud ještě nemáte pracovní prostor Azure Machine Learning, dokončete vytváření prostředků, abyste mohli začít .
  • Prostředí Pythonu, ve kterém jste nainstalovali balíčky i azureml-coreazureml-pipeline . Toto prostředí slouží k definování a řízení prostředků služby Azure Machine Learning a je oddělené od prostředí používaného za běhu pro trénování.

Důležité

Nejnovější kompatibilní azureml-pipeline verze Pythonu je v současné době Python 3.8. Pokud máte s instalací azureml-pipeline balíčku potíže, ujistěte se, že python --version je to kompatibilní verze. Pokyny najdete v dokumentaci správce virtuálního prostředí Pythonu (venv, condaatd.).

Spuštění interaktivní relace Pythonu

V tomto kurzu se k vytvoření a řízení kanálu Azure Machine Learning používá sada Python SDK pro Azure Machine Learning. Kurz 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 kurz je založený na poznámkovém image-classification.ipynb bloku, který python-sdk/tutorial/using-pipelines najdete v adresáři úložiště Příkladů služby Azure Machine Learning . Zdrojový kód samotných kroků je v podadresáři keras-mnist-fashion .

Typy importu

Naimportujte všechny typy služby Azure Machine Learning, které budete v tomto kurzu potřebovat:

import os
import azureml.core
from azureml.core import (
    Workspace,
    Experiment,
    Dataset,
    Datastore,
    ComputeTarget,
    Environment,
    ScriptRunConfig
)
from azureml.data import OutputFileDatasetConfig
from azureml.core.compute import AmlCompute
from azureml.core.compute_target import ComputeTargetException
from azureml.pipeline.steps import PythonScriptStep
from azureml.pipeline.core import Pipeline

# check core SDK version number
print("Azure Machine Learning SDK Version: ", azureml.core.VERSION)

Verze sady Azure Machine Learning SDK by měla být 1.37 nebo vyšší. Pokud není, upgradujte pomocí pip install --upgrade azureml-core.

Konfigurace pracovního prostoru

Vytvořte objekt pracovního prostoru z existujícího pracovního prostoru Azure Machine Learning.

workspace = Workspace.from_config()

Důležité

Tento fragment kódu očekává, že se konfigurace pracovního prostoru uloží do aktuálního adresáře nebo jeho nadřazeného adresáře. 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 najdete v tématu Vytvoření konfiguračního souboru pracovního prostoru.

Vytvoření infrastruktury pro váš kanál

Vytvořte Experiment objekt pro uložení výsledků spuštění kanálu:

exp = Experiment(workspace=workspace, name="keras-mnist-fashion")

Vytvořte objekt, ComputeTarget který představuje prostředek počítače, na kterém se bude kanál spouštět. Jednoduchá neurální síť použitá v tomto kurzu se trénuje během několika minut i na počítači založeném na procesoru. Pokud chcete k trénování použít GPU, nastavte use_gpu na True. Zřízení cílového výpočetního objektu obvykle trvá přibližně pět minut.

use_gpu = False

# choose a name for your cluster
cluster_name = "gpu-cluster" if use_gpu else "cpu-cluster"

found = False
# Check if this compute target already exists in the workspace.
cts = workspace.compute_targets
if cluster_name in cts and cts[cluster_name].type == "AmlCompute":
    found = True
    print("Found existing compute target.")
    compute_target = cts[cluster_name]
if not found:
    print("Creating a new compute target...")
    compute_config = AmlCompute.provisioning_configuration(
        vm_size= "STANDARD_NC6" if use_gpu else "STANDARD_D2_V2"
        # vm_priority = 'lowpriority', # optional
        max_nodes=4,
    )

    # Create the cluster.
    compute_target = ComputeTarget.create(workspace, cluster_name, compute_config)

    # Can poll for a minimum number of nodes and for a specific timeout.
    # If no min_node_count is provided, it will use the scale settings for the cluster.
    compute_target.wait_for_completion(
        show_output=True, min_node_count=None, timeout_in_minutes=10
    )
# For a more detailed view of current AmlCompute status, use get_status().print(compute_target.get_status().serialize())

Poznámka

Dostupnost GPU závisí na kvótě vašeho předplatného Azure a na kapacitě Azure. Viz Správa a navýšení kvót pro prostředky s využitím služby Azure Machine Learning.

Vytvoření datové sady pro data uložená v Azure

Fashion-MNIST je datová sada módních obrázků rozdělených do 10 tříd. Každý obrázek má formát 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 obtížnější než klasická databáze ručně psaných číslic MNIST. Distribuuje se ve stejné komprimované binární podobě jako původní ručně psaná databáze číslic .

Pokud chcete vytvořit objekt Dataset , který odkazuje na webová data, spusťte:

data_urls = ["https://data4mldemo6150520719.blob.core.windows.net/demo/mnist-fashion"]
fashion_ds = Dataset.File.from_files(data_urls)

# list the files referenced by fashion_ds
print(fashion_ds.to_path())

Tento kód se rychle dokončí. Podkladová data zůstanou v prostředku úložiště Azure zadaném data_urls v poli.

Vytvoření kroku kanálu přípravy dat

Prvním krokem v tomto kanálu je převedení komprimovaných datových fashion_ds souborů na datovou sadu ve vašem vlastním pracovním prostoru, která se skládá ze souborů CSV připravených k použití při trénování. Po registraci v pracovním prostoru můžou vaši spolupracovníci přistupovat k datům pro vlastní analýzy, trénování atd.

datastore = workspace.get_default_datastore()
prepared_fashion_ds = OutputFileDatasetConfig(
    destination=(datastore, "outputdataset/{run-id}")
).register_on_complete(name="prepared_fashion_ds")

Výše uvedený kód určuje datovou sadu, která je založená na výstupu kroku kanálu. Podkladové zpracované soubory se umístí do úložiště objektů blob výchozího úložiště dat pracovního prostoru v cestě zadané v destination. Datová sada se zaregistruje v pracovním prostoru s názvem prepared_fashion_ds.

Vytvoření zdroje kroku kanálu

Kód, který jste zatím spustili, vytvořil a řídil prostředky Azure. Teď je čas napsat kód, který provede první krok v doméně.

Pokud budete postupovat podle příkladu v úložišti Příkladů služby Azure Machine Learning, zdrojový soubor je už k dispozici jako keras-mnist-fashion/prepare.py.

Pokud pracujete úplně od začátku, vytvořte podadresář s názvem keras-mnist-fashion/. Vytvořte nový soubor, přidejte do něj následující kód a pojmenujte ho prepare.py.

# prepare.py
# Converts MNIST-formatted files at the passed-in input path to a passed-in output path
import os
import sys

# Conversion routine for MNIST binary format
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()

# The MNIST-formatted source
mounted_input_path = sys.argv[1]
# The output directory at which the outputs will be written
mounted_output_path = sys.argv[2]

# Create the output directory
os.makedirs(mounted_output_path, exist_ok=True)

# Convert the training data
convert(
    os.path.join(mounted_input_path, "mnist-fashion/train-images-idx3-ubyte"),
    os.path.join(mounted_input_path, "mnist-fashion/train-labels-idx1-ubyte"),
    os.path.join(mounted_output_path, "mnist_train.csv"),
    60000,
)

# Convert the test data
convert(
    os.path.join(mounted_input_path, "mnist-fashion/t10k-images-idx3-ubyte"),
    os.path.join(mounted_input_path, "mnist-fashion/t10k-labels-idx1-ubyte"),
    os.path.join(mounted_output_path, "mnist_test.csv"),
    10000,
)

Kód v prepare.py souboru přijímá dva argumenty příkazového řádku: první je přiřazený k mounted_input_path a druhý k mounted_output_path. Pokud tento podadresář neexistuje, vytvoří se voláním os.makedirs . Program pak převede trénovací a testovací data a vypíše soubory oddělené čárkami na mounted_output_path.

Určení kroku kanálu

Zpět v prostředí Pythonu, které používáte k určení kanálu, spusťte tento kód, který PythonScriptStep vytvoří kód pro přípravu:

script_folder = "./keras-mnist-fashion"

prep_step = PythonScriptStep(
    name="prepare step",
    script_name="prepare.py",
    # On the compute target, mount fashion_ds dataset as input, prepared_fashion_ds as output
    arguments=[fashion_ds.as_named_input("fashion_ds").as_mount(), prepared_fashion_ds],
    source_directory=script_folder,
    compute_target=compute_target,
    allow_reuse=True,
)

Volání PythonScriptStep určuje, že při spuštění kroku kanálu:

  • Všechny soubory v adresáři se nahrají script_folder do compute_target
  • Z těchto nahraných zdrojových souborů se soubor prepare.py spustí.
  • Datové fashion_ds sady a prepared_fashion_ds se připojí k compute_target a zobrazí se jako adresáře.
  • Cesta k souborům fashion_ds bude prvním argumentem pro prepare.py. V prepare.pynástroji je tento argument přiřazen k mounted_input_path
  • Cesta k bude prepared_fashion_ds druhým argumentem pro prepare.py. V prepare.pynástroji je tento argument přiřazen k mounted_output_path
  • Protože allow_reuse je True, nespustí se znovu, dokud se nezmění jeho zdrojové soubory nebo vstupy.
  • Bude PythonScriptStep mít název . prepare step

Modularita a opakované použití jsou klíčovými výhodami kanálů. Azure Machine Learning dokáže automaticky určit změny zdrojového kódu nebo datové sady. Výstup kroku, který není ovlivněn, se znovu použije bez opětovného spuštění kroků, pokud allow_reuse je True. Pokud se krok spoléhá na zdroj dat externí pro Azure Machine Learning, který se může změnit (například adresa URL obsahující prodejní data), nastavte allow_reuse na False hodnotu a krok kanálu se spustí při každém spuštění kanálu.

Vytvoření trénovacího kroku

Jakmile se data převedou z komprimovaného formátu do souborů CSV, můžete je použít k trénování konvoluční neurální sítě.

Vytvoření zdroje trénovacího kroku

U větších kanálů je vhodné umístit zdrojový kód každého kroku do samostatného adresáře (src/prepare/, src/train/atd.), ale pro účely tohoto kurzu stačí použít nebo vytvořit soubor train.py ve stejném keras-mnist-fashion/ zdrojovém adresáři.

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

import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from azureml.core import Run

# dataset object from the run
run = Run.get_context()
dataset = run.input_datasets["prepared_fashion_ds"]

# split dataset into train and test set
(train_dataset, test_dataset) = dataset.random_split(percentage=0.8, seed=111)

# load dataset into pandas dataframe
data_train = train_dataset.to_pandas_dataframe()
data_test = test_dataset.to_pandas_dataframe()

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

X = np.array(data_train.iloc[:, 1:])
y = to_categorical(np.array(data_train.iloc[:, 0]))

# here we split validation data to optimiza classifier during training
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=13)

# test data
X_test = np.array(data_test.iloc[:, 1:])
y_test = to_categorical(np.array(data_test.iloc[:, 0]))


X_train = (
    X_train.reshape(X_train.shape[0], img_rows, img_cols, 1).astype("float32") / 255
)
X_test = X_test.reshape(X_test.shape[0], img_rows, img_cols, 1).astype("float32") / 255
X_val = X_val.reshape(X_val.shape[0], img_rows, img_cols, 1).astype("float32") / 255

batch_size = 256
num_classes = 10
epochs = 10

# construct neuron network
model = Sequential()
model.add(
    Conv2D(
        32,
        kernel_size=(3, 3),
        activation="relu",
        kernel_initializer="he_normal",
        input_shape=input_shape,
    )
)
model.add(MaxPooling2D((2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), activation="relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(128, (3, 3), activation="relu"))
model.add(Dropout(0.4))
model.add(Flatten())
model.add(Dense(128, activation="relu"))
model.add(Dropout(0.3))
model.add(Dense(num_classes, activation="softmax"))

model.compile(
    loss=keras.losses.categorical_crossentropy,
    optimizer=keras.optimizers.Adam(),
    metrics=["accuracy"],
)

# start an Azure ML run
run = Run.get_context()


class LogRunMetrics(Callback):
    # callback at the end of every epoch
    def on_epoch_end(self, epoch, log):
        # log a value repeated which creates a list
        run.log("Loss", log["loss"])
        run.log("Accuracy", log["accuracy"])


history = model.fit(
    X_train,
    y_train,
    batch_size=batch_size,
    epochs=epochs,
    verbose=1,
    validation_data=(X_val, y_val),
    callbacks=[LogRunMetrics()],
)

score = model.evaluate(X_test, y_test, verbose=0)

# log a single value
run.log("Final test loss", score[0])
print("Test loss:", score[0])

run.log("Final test accuracy", score[1])
print("Test accuracy:", score[1])

plt.figure(figsize=(6, 3))
plt.title("Fashion MNIST with Keras ({} epochs)".format(epochs), fontsize=14)
plt.plot(history.history["accuracy"], "b-", label="Accuracy", lw=4, alpha=0.5)
plt.plot(history.history["loss"], "r--", label="Loss", lw=4, alpha=0.5)
plt.legend(fontsize=12)
plt.grid(True)

# log an image
run.log_image("Loss v.s. Accuracy", plot=plt)

# create a ./outputs/model folder in the compute target
# files saved in the "./outputs" folder are automatically uploaded into run history
os.makedirs("./outputs/model", exist_ok=True)

# serialize NN architecture to JSON
model_json = model.to_json()
# save model JSON
with open("./outputs/model/model.json", "w") as f:
    f.write(model_json)
# save model weights
model.save_weights("./outputs/model/model.h5")
print("model saved in ./outputs/model folder")

Většinu tohoto kódu by měli znát vývojáři ML:

  • Data jsou rozdělená na trénovací a ověřovací sadu pro trénování a samostatnou testovací podmnožinu pro konečné bodování.
  • Vstupní obrazec je 28 × 28 × 1 (pouze 1, protože vstup je ve stupních šedé), v dávce bude 256 vstupů a existuje 10 tříd.
  • Počet epoch trénování bude 10.
  • Model má tři konvoluční vrstvy s maximálním sdružováním a dropoutem, následované hustou vrstvou a hlavou softmax.
  • Model se hodí pro 10 epoch a pak se vyhodnotí.
  • Architektura modelu se zapisuje do outputs/model/model.json a váhy do outputs/model/model.h5

Část kódu je ale specifická pro Azure Machine Learning. run = Run.get_context() Načte Run objekt, který obsahuje aktuální kontext služby. Zdroj train.py používá tento run objekt k načtení vstupní datové sady prostřednictvím jejího názvu (alternativu k kódu, prepare.py který načetl datovou sadu prostřednictvím argv pole argumentů skriptu).

Objekt se run také používá k protokolování průběhu trénování na konci každé epochy a na konci trénování k protokolování grafu ztrát a přesnosti v průběhu času.

Vytvoření kroku trénovacího kanálu

Trénovací krok má trochu složitější konfiguraci než přípravný krok. Přípravný krok používal pouze standardní knihovny Pythonu. Častěji budete muset upravit běhové prostředí, ve kterém běží váš zdrojový kód.

Vytvořte soubor conda_dependencies.yml s následujícím obsahem:

dependencies:
- python=3.7
- pip:
  - azureml-core
  - azureml-dataset-runtime
  - keras==2.4.3
  - tensorflow==2.4.3
  - numpy
  - scikit-learn
  - pandas
  - matplotlib

Třída Environment představuje běhové prostředí, ve kterém běží úloha strojového učení. Výše uvedenou specifikaci přidružte k trénovacímu kódu pomocí:

keras_env = Environment.from_conda_specification(
    name="keras-env", file_path="./conda_dependencies.yml"
)

train_cfg = ScriptRunConfig(
    source_directory=script_folder,
    script="train.py",
    compute_target=compute_target,
    environment=keras_env,
)

K vytvoření samotného trénovacího kroku se použije kód podobný kódu použitému k vytvoření přípravného kroku:

train_step = PythonScriptStep(
    name="train step",
    arguments=[
        prepared_fashion_ds.read_delimited_files().as_input(name="prepared_fashion_ds")
    ],
    source_directory=train_cfg.source_directory,
    script_name=train_cfg.script,
    runconfig=train_cfg.run_config,
)

Vytvoření a spuštění kanálu

Teď, když jste zadali datové vstupy a výstupy a vytvořili kroky kanálu, můžete je sestavit do kanálu a spustit:

pipeline = Pipeline(workspace, steps=[prep_step, train_step])
run = exp.submit(pipeline)

Objekt Pipeline , který vytvoříte, se spustí v a workspace skládá se z kroků přípravy a trénování, které jste zadali.

Poznámka

Tento kanál má jednoduchý graf závislostí: trénovací krok závisí na přípravném kroku a krok přípravy závisí na fashion_ds datové sadě. Produkční kanály budou mít často mnohem složitější závislosti. Kroky můžou záviset na několika upstreamových krocích, změna zdrojového kódu v počátečním kroku může mít dalekosáhlé důsledky atd. Azure Machine Learning tyto obavy sleduje za vás. Stačí předat pole steps a Azure Machine Learning se postará o výpočet grafu provádění.

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

Submitted PipelineRun 5968530a-abcd-1234-9cc1-46168951b5eb
Link to Azure Machine Learning Portal: https://ml.azure.com/runs/abc-xyz...

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

run.wait_for_completion(show_output=True)

Důležité

První spuštění kanálu trvá přibližně 15 minut. Je potřeba stáhnout všechny závislosti, vytvořit image Dockeru a zřídit a vytvořit prostředí Pythonu. Opětovné spuštění kanálu trvá výrazně kratší dobu, protože tyto prostředky se místo vytváření znovu používají. Celková doba běhu kanálu ale závisí na zatížení vašich skriptů a procesech, které běží v jednotlivých krocích kanálu.

Po dokončení kanálu můžete načíst metriky, které jste zaznamenali v kroku trénování:

run.find_step_run("train step")[0].get_metrics()

Pokud jste s metrikami spokojení, můžete model zaregistrovat ve svém pracovním prostoru:

run.find_step_run("train step")[0].register_model(
    model_name="keras-model",
    model_path="outputs/model/",
    datasets=[("train test data", fashion_ds)],
)

Vyčištění prostředků

Tuto část nedokončíte, pokud plánujete spustit další kurzy služby Azure Machine Learning.

Zastavení výpočetní instance

Pokud jste použili výpočetní instanci, zastavte virtuální počítač, když ho nepoužíváte, abyste snížili náklady.

  1. V pracovním prostoru vyberte Compute.

  2. V seznamu vyberte název výpočetní instance.

  3. Vyberte Zastavit.

  4. Až budete připraveni server znovu použít, vyberte Spustit.

Odstranit všechno

Pokud vytvořené prostředky neplánujete používat, odstraňte je, aby se vám neúčtovaly žádné poplatky:

  1. V Azure Portal v nabídce vlevo vyberte Skupiny prostředků.
  2. V seznamu skupin prostředků vyberte skupinu prostředků, kterou jste vytvořili.
  3. Vyberte Odstranit skupinu prostředků.
  4. Zadejte název skupiny prostředků. Pak vyberte Odstranit.

Můžete také zachovat skupinu prostředků, ale odstranit jeden pracovní prostor. Zobrazte vlastnosti pracovního prostoru a pak vyberte Odstranit.

Další kroky

V tomto kurzu jste použili následující typy:

  • Představuje Workspace váš pracovní prostor Azure Machine Learning. Obsahoval:
    • Hodnota Experiment , která obsahuje výsledky trénovacích spuštění vašeho kanálu
    • Objekt Dataset , který líně načetl data uložená v úložišti dat Fashion-MNIST
    • Představuje ComputeTarget počítače, na kterých se spouští kroky kanálu.
    • To Environment je běhové prostředí, ve kterém se spouští kroky kanálu.
    • Objekt Pipeline , který složí PythonScriptStep kroky do celku
    • Hodnota Model , kterou jste zaregistrovali po spokojenosti s procesem trénování

Objekt Workspace obsahuje odkazy na další prostředky (poznámkové bloky, koncové body atd.), které se v tomto kurzu nepoužívaly. Další informace najdete v tématu Co je pracovní prostor služby Azure Machine Learning.

Zvýší OutputFileDatasetConfig se výstup spuštění na souborovou datovou sadu. Další informace o datových sadách a práci s daty najdete v tématu Jak získat přístup k datům.

Další informace o cílových výpočetních objektech a prostředích najdete v tématech Co jsou výpočetní cíle ve službě Azure Machine Learning? a Co jsou prostředí Azure Machine Learning?

Ke zdrojovým souborům Pythonu přidruží ScriptRunConfigComputeTarget a Environment . Objekt PythonScriptStep to ScriptRunConfig přebírá a definuje své vstupy a výstupy, které v tomto kanálu byly souborovou datovou sadou sestavenou objektem OutputFileDatasetConfig.

Další příklady vytváření kanálů pomocí sady SDK pro strojové učení najdete v ukázkovém úložišti.