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

PLATÍ PRO:Python SDK azureml v1

V tomto kurzu se dozvíte, jak vytvořit kanál Azure Machine Learning pro přípravu dat a trénování modelu strojového učení. 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íť pro 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í computeTargetu pro provedení práce
  • 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í prostředí runtime, ve kterém se má trénování provádět
  • 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

  • Dokončete rychlý start: Začněte se službou Azure Machine Learning , pokud ještě nemáte pracovní prostor Azure Machine Learning.
  • Prostředí Pythonu, ve kterém jste nainstalovali balíčky azureml-core i azureml-pipeline balíčky. Toto prostředí slouží k definování a řízení prostředků Azure Machine Learning a je oddělené od prostředí používaného za běhu pro trénování.

Důležité

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

Spuštění interaktivní relace Pythonu

Tento kurz používá sadu Python SDK pro Azure ML k vytvoření a řízení kanálu Azure Machine Learning. V tomto kurzu se předpokládá, že budete spouštět fragmenty kódu interaktivně v prostředí Python REPL nebo v poznámkovém bloku Jupyter.

  • Tento kurz je založený na image-classification.ipynb poznámkovém bloku, který najdete v python-sdk/tutorial/using-pipelines adresáři úložiště AzureML Examples . Zdrojový kód pro samotné kroky je v keras-mnist-fashion podadresáři.

Typy importu

Naimportujte všechny typy služby Azure Machine Learning, které budete potřebovat pro účely tohoto kurzu:

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 ML SDK Version: ", azureml.core.VERSION)

Verze sady Azure ML SDK by měla být 1.37 nebo vyšší. Pokud tomu tak není, proveďte upgrade pomocí pip install --upgrade azureml-core.

Konfigurace pracovního prostoru

Vytvořte objekt pracovního prostoru z existujícího pracovního prostoru Služby 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 nadřazeného adresáře. Další informace o vytvář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

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

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

Vytvořte prostředek ComputeTarget 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 na use_gpuTruehodnotu . 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 zvýšení kvót pro prostředky pomocí 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 je obrázek ve stupních šedé 28x28 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á ručně psaná číslicová databáze MNIST. Distribuuje se ve stejném komprimovaném binárním formátu jako původní rukou psaná databáze číslic .

Pokud chcete vytvořit odkaz Dataset na webová data, spusťte příkaz:

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í krok v tomto kanálu převede komprimované datové soubory fashion_ds do datové sady 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ýzu, 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 založenou na výstupu kroku kanálu. Podkladové zpracované soubory se umístí do výchozího úložiště objektů blob úložiště dat pracovního prostoru na 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 provedli, obsahuje vytváření a řízení prostředků Azure. Teď je čas napsat kód, který provede první krok v doméně.

Pokud sledujete příklad v úložišti Příkladů AzureML, zdrojový soubor je již 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 má prepare.py dva argumenty příkazového řádku: první je přiřazen a mounted_input_path druhý k mounted_output_path. Pokud tento podadresář neexistuje, volání, které os.makedirs ho vytvoří. Program pak převede trénovací a testovací data a vypíše soubory oddělené čárkami na mounted_output_path.

Zadání kroku kanálu

Zpátky v prostředí Pythonu, které používáte k zadání kanálu, spusťte tento kód a vytvořte pro přípravný PythonScriptStep kód:

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í, které určuje PythonScriptStep , že při spuštění kroku kanálu:

  • Všechny soubory v script_folder adresáři se nahrají do složky compute_target
  • Mezi nahranými zdrojovými soubory se soubor prepare.py spustí.
  • prepared_fashion_ds Datové fashion_ds sady se připojí k compute_target adresářům a zobrazí se jako adresáře.
  • Cesta k fashion_ds souborům bude prvním argumentem prepare.py. V prepare.pytomto argumentu je přiřazen mounted_input_path
  • Cesta k této cestě prepared_fashion_ds bude druhým argumentem prepare.py. V prepare.pytomto argumentu je přiřazen mounted_output_path
  • Protože allow_reuse ano True, nebude se znovu spustí, dokud se nezmění jeho zdrojové soubory nebo vstupy.
  • Bude PythonScriptStep pojmenováno. prepare step

Modularita a opakované použití jsou klíčovými výhodami kanálů. Azure Machine Learning může automaticky určit zdrojový kód nebo změny 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 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), nastaví allow_reuse se na False a krok kanálu se spustí při každém spuštění kanálu.

Vytvoření kroku trénování

Po převodu dat z komprimovaného formátu na soubory CSV je možné 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 jednotlivých kroků do samostatného adresáře (src/prepare/src/train/atd.), ale pro účely tohoto kurzu ho použijte nebo vytvořte 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šina tohoto kódu by měla být pro vývojáře strojového učení známá:

  • Data jsou rozdělená do trénovacích a ověřovacích sad pro trénování a samostatnou testovací podmnožinu pro konečné vyhodnocování.
  • Vstupní obrazec je 28x28x1 (pouze 1, protože vstup je stupně šedé), v dávce bude 256 vstupů a existuje 10 tříd.
  • Počet epoch školení bude 10
  • Model má tři konvoluční vrstvy s maximálním sdružováním a výpadkem následovaným hustou vrstvou a softmax head
  • Model je vybaven 10 epoch a následně vyhodnocen
  • Architektura modelu se zapisuje do outputs/model/model.json a závaží do outputs/model/model.h5

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

Objekt run se 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áty 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ž je krok přípravy. Přípravný krok používal pouze standardní knihovny Pythonu. Častěji budete muset upravit prostředí runtime, ve kterém se spouští zdrojový kód.

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

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

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

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

Vytvoření samotného trénovacího kroku používá 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 vstupy a výstupy dat a vytvořili kroky kanálu, můžete je vytvořit do kanálu a spustit ho:

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

Objekt Pipeline , který vytvoříte, se workspace skládá 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 kroku přípravy závisí na fashion_ds datové sadě. Produkční kanály budou často mít 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 raném kroku může mít dalekosáhlé důsledky a tak dále. Azure Machine Learning sleduje tyto obavy za vás. Potřebujete předat pouze pole steps a Azure Machine Learning se postará o výpočet grafu provádění.

Volání dokončení submitExperiment rychle 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 otevřením odkazu nebo blokováním, dokud se kanál neskonče dokončí spuštěním:

run.wait_for_completion(show_output=True)

Důležité

První spuštění kanálu trvá přibližně 15 minut. Všechny závislosti je nutné stáhnout, vytvořit 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 tyto prostředky se znovu používají místo vytvoření. Celková doba běhu kanálu ale závisí na úloze skriptů a procesech spuštěných v jednotlivých krocích kanálu.

Po dokončení kanálu můžete načíst metriky, které jste protokolovali 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ů

Pokud plánujete spustit další kurzy služby Azure Machine Learning, tento oddíl nedokončíte.

Zastavení výpočetní instance

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

  1. V pracovním prostoru vyberte Compute.

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

  3. Vyberte Zastavit.

  4. Až budete chtít server znovu použít, vyberte Spustit.

Odstranit vše

Pokud nechcete používat prostředky, které jste vytvořili, odstraňte je, takže vám nebudou účtovány žá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 služby Azure Machine Learning. Obsahuje:
    • Obsahuje Experiment výsledky trénovacích běhů kanálu.
    • Líně Dataset načetla data uložená v úložišti dat Fashion-MNIST.
    • To ComputeTarget představuje počítače, na kterých se spouští kroky kanálu.
    • Toto Environment je prostředí runtime, ve kterém se spouští kroky kanálu.
    • To Pipeline kompozizuje PythonScriptStep kroky do celku
    • To Model , co jste zaregistrovali po splnění procesu trénování

Objekt Workspace obsahuje odkazy na jiné 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?.

Podporuje OutputFileDatasetConfig výstup spuštění do datové sady založené na souborech. 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 prostředcích a prostředích najdete v tématu Co jsou výpočetní cíle ve službě Azure Machine Learning? a Co jsou prostředí Azure Machine Learning?

Přidruží ScriptRunConfig zdrojové soubory Pythonu ComputeTarget a Environment k němu. Vezme PythonScriptStep to ScriptRunConfig a definuje jeho vstupy a výstupy, které v tomto kanálu byly souborovou datovou sadou vytvořenou OutputFileDatasetConfig.

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