Partager via


Tutoriel : Créer un pipeline Azure Machine Learning pour la classification d’images

S’APPLIQUE À : SDK Python azureml v1

Remarque

Pour accéder à un tutoriel qui utilise le Kit de développement logiciel (SDK) v2 pour générer un pipeline, consultez Tutoriel : Utiliser des pipelines ML pour des flux de travail ML de production avec le Kit de développement logiciel (SDK) Python v2 dans un Jupyter Notebook.

Dans ce tutoriel, vous allez apprendre à créer un pipeline Azure Machine Learning pour préparer des données et entraîner un modèle Machine Learning. Les pipelines Machine Learning optimisent votre workflow à divers niveaux : vitesse, portabilité et réutilisation. Ainsi, vous pouvez vous concentrer sur le Machine Learning, plutôt que sur l’infrastructure et l’automatisation.

L’exemple entraîne un petit réseau neuronal convolutif Keras pour classifier les images dans le jeu de données Fashion MNIST.

Dans ce tutoriel, vous allez effectuer les tâches suivantes :

  • Configurer l’espace de travail
  • Créer une expérience pour conserver votre travail
  • Provisionner un ComputeTarget pour faire le travail
  • Créer un jeu de données dans lequel stocker les données compressées
  • Créer une étape de pipeline afin de préparer les données pour l’entraînement
  • Définir un environnement d’exécution dans lequel effectuer l’entraînement
  • Créer une étape de pipeline pour définir le réseau neuronal et effectuer l’entraînement
  • Composer un pipeline à partir des étapes de pipeline
  • Exécuter le pipeline dans l’expérience
  • Examiner la sortie des étapes et du réseau neuronal entraîné
  • Inscrire le modèle pour l’utiliser ultérieurement

Si vous n’avez pas d’abonnement Azure, créez un compte gratuit avant de commencer. Essayez la version gratuite ou payante d’Azure Machine Learning dès aujourd’hui.

Prérequis

  • Effectuez la procédure Créer des ressources pour commencer si vous ne disposez pas déjà d’un espace de travail Azure Machine Learning.
  • Un environnement Python dans lequel vous avez installé les packages azureml-core et azureml-pipeline. Cet environnement est destiné à la définition et au contrôle de vos ressources Azure Machine Learning et est séparé de l’environnement utilisé lors de l’exécution pour l’entraînement.

Important

Actuellement, la version la plus récente de Python compatible avec azureml-pipeline est Python 3.8. Si vous rencontrez des difficultés lors de l’installation du package azureml-pipeline, assurez-vous que python --version est une version compatible. Pour obtenir des instructions, consultez la documentation de votre gestionnaire d’environnement virtuel Python (venv, conda, etc.).

Démarrer une session Python interactive

Ce tutoriel utilise le SDK Python pour Azure Machine Learning pour créer et contrôler un pipeline Azure Machine Learning. Ce tutoriel part du principe que vous allez exécuter les extraits de code de manière interactive dans un environnement REPL Python ou un notebook Jupyter.

  • Ce tutoriel est basé sur le notebook image-classification.ipynb qui se trouve dans le répertoire python-sdk/tutorial/using-pipelines du référentiel exemples Azure Machine Learning. Le code source pour les étapes elles-mêmes se trouve dans le sous-répertoire keras-mnist-fashion.

Importer les types

Importez tous les types Azure Machine Learning dont vous aurez besoin pour ce tutoriel :

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)

La version du SDK Azure Machine Learning doit être 1.37 ou supérieure. Si ce n’est pas le cas, effectuez une mise à niveau avec pip install --upgrade azureml-core.

Configurer l’espace de travail

Créez un objet d’espace de travail à partir de l’espace de travail Azure Machine Learning existant.

workspace = Workspace.from_config()

Important

Cet extrait de code s’attend à ce que la configuration de l’espace de travail soit enregistrée dans le répertoire actif ou son parent. Pour plus d’informations sur la création d’un espace de travail, consultez Créer des ressources d’espace de travail. Pour plus d’informations sur l’enregistrement de la configuration dans un fichier, consultez Créer un fichier de configuration d’espace de travail.

Créer l’infrastructure pour votre pipeline

Créez un objet Experiment pour stocker les résultats de vos exécutions de pipeline :

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

Créez un ComputeTarget qui représente la ressource de l’ordinateur sur lequel votre pipeline s’exécutera. Le simple réseau neuronal utilisé dans ce tutoriel est entraîné en seulement quelques minutes, même sur un ordinateur basé sur un processeur. Si vous souhaitez utiliser un GPU pour l’entraînement, affectez à use_gpu la valeur True. Le provisionnement d’une cible de calcul prend généralement cinq minutes environ.

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

Notes

La disponibilité de GPU dépend du quota de votre abonnement Azure et de la capacité Azure. Consultez Gérer et augmenter les quotas pour les ressources avec Azure Machine Learning.

Créer un jeu de données pour les données stockées dans Azure

Fashion-MNIST est un jeu de données d’images de mode divisé en 10 classes. Chaque image est une image en nuances de gris 28x28 et il y a 60 000 images d’entraînement et 10 000 images de test. Au niveau de la classification d’images, Fashion-MNIST est plus difficile que la base de données MNIST de chiffres écrits à la main classique. Elle est distribuée sous la même forme binaire compressé que la base de données de chiffres écrits à la main.

Pour créer un Dataset qui référence les données web, exécutez :

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

L’exécution de ce code est rapide. Les données sous-jacentes restent dans la ressource de stockage Azure spécifiée dans le tableau data_urls.

Créer l’étape de pipeline de préparation des données

La première étape de ce pipeline convertit les fichiers de données compressées de fashion_ds en jeu de données dans votre propre espace de travail constitué de fichiers CSV prêts à être utilisés dans l’entraînement. Une fois inscrits à l’espace de travail, vos collaborateurs peuvent accéder à ces données pour leur propre analyse, entraînement, etc.

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

Le code ci-dessus spécifie un jeu de données basé sur la sortie d’une étape de pipeline. Les fichiers traités sous-jacents sont placés dans le stockage de blobs du magasin de données par défaut de l’espace de travail dans le chemin spécifié dans destination. Le jeu de données est inscrit dans l’espace de travail avec le nom prepared_fashion_ds.

Créer la source de l’étape de pipeline

Le code que vous avez exécuté jusqu’à présent a créé et contrôlé des ressources Azure. Il est maintenant temps d’écrire le code qui fait la première étape dans le domaine.

Si vous suivez l’exemple du référentiel d’exemples Azure Machine Learning, le fichier source est déjà disponible en tant que keras-mnist-fashion/prepare.py.

Si vous travaillez à partir de zéro, créez un sous-répertoire appelé keras-mnist-fashion/. Créez un fichier, ajoutez-y le code suivant et nommez-le 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,
)

Le code dans prepare.py prend deux arguments de ligne de commande : le premier est affecté à mounted_input_path et le deuxième à mounted_output_path. Si ce sous-répertoire n’existe pas, l’appel à os.makedirs le crée. Ensuite, le programme convertit les données d’entraînement et de test et génère des fichiers séparés par des virgules dans mounted_output_path.

Spécifier l’étape de pipeline

De retour dans l’environnement Python que vous utilisez pour spécifier le pipeline, exécutez ce code pour créer un PythonScriptStep pour votre code de préparation :

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

L’appel à PythonScriptStep spécifie que, lorsque l’étape de pipeline est exécutée :

  • Tous les fichiers du répertoire script_folder sont chargés sur le compute_target
  • Parmi ces fichiers sources chargés, le fichier prepare.py est exécuté
  • Les jeux de données fashion_ds et prepared_fashion_ds sont montés sur le compute_target et apparaissent en tant que répertoires
  • Le chemin vers les fichiers fashion_ds sera le premier argument sur le prepare.py. Dans prepare.py, cet argument est affecté à mounted_input_path
  • Le chemin vers prepared_fashion_ds sera le deuxième argument sur le prepare.py. Dans prepare.py, cet argument est affecté à mounted_output_path
  • Étant donné que allow_reuse est True, il n’est pas réexécuté tant que ses entrées ou fichiers sources ne changent pas
  • Ce PythonScriptStep est appelé prepare step

La modularité et la réutilisation sont les principaux avantages des pipelines. Azure Machine Learning peut déterminer automatiquement le code source ou les modifications du jeu de données. La sortie d’une étape qui n’est pas affectée sera réutilisée sans réexécuter les étapes si allow_reuse est True. Si une étape s’appuie sur une source de données externe à Azure Machine Learning qui peut changer (par exemple, une URL qui contient des données de ventes), définissez allow_reuse avec la valeur False et l’étape de pipeline s’exécutera chaque fois que le pipeline sera exécuté.

Créer l’étape d’entraînement

Une fois que les données ont été converties du format compressé en fichiers CSV, elles peuvent être utilisées pour l’entraînement d’un réseau neuronal convolutif.

Créer la source de l’étape d’entraînement

Avec des pipelines plus grands, il est recommandé de placer le code source de chaque étape dans un répertoire distinct (src/prepare/, src/train/, etc.), mais pour ce tutoriel, utilisez ou créez juste le fichier train.py dans le même répertoire source keras-mnist-fashion/.

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

Une grande partie de ce code devrait être familière aux développeurs ML :

  • Les données sont partitionnées dans des jeux d’entraînement et de validation pour l’entraînement, ainsi qu’un sous-ensemble de test distinct pour le scoring final
  • La forme des entrées est 28x28x1 (1 uniquement parce que les entrées sont en nuances de gris), il y aura 256 entrées dans un lot, ainsi que 10 classes
  • Le nombre d’époques d’entraînement sera de 10
  • Le modèle a trois couches convolutives : pooling max et suppression (dropout), suivis d’une couche dense et d’une tête softmax
  • Le modèle est ajusté pour 10 époques, puis évalué
  • L’architecture du modèle est écrite dans outputs/model/model.json et les poids dans outputs/model/model.h5

Toutefois, une partie du code est spécifique à Azure Machine Learning. run = Run.get_context() récupère un objet Run qui contient le contexte de service actuel. La source train.py utilise cet objet run pour récupérer le jeu de données d’entrée à l’aide de son nom (alternative au code dans prepare.py qui a récupéré le jeu de données via le tableau argv d’arguments de script).

L’objet run est également utilisé pour journaliser la progression de l’entraînement à la fin de chaque époque et, à la fin de l’entraînement, pour journaliser le graphique de perte et de justesse au fil du temps.

Créer l’étape de pipeline d’entraînement

L’étape d’entraînement présente une configuration légèrement plus complexe que l’étape de préparation. L’étape de préparation a utilisé uniquement des bibliothèques Python standard. Plus généralement, vous devez modifier l’environnement d’exécution dans lequel votre code source s’exécute.

Créez un fichier conda_dependencies.yml avec le contenu suivant :

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

La classe Environment représente l’environnement d’exécution dans lequel une tâche de machine learning s’exécute. Associez la spécification ci-dessus au code d’entraînement avec :

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

La création de l’étape d’entraînement elle-même utilise du code similaire au code utilisé pour créer l’étape de préparation :

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

Créer et exécuter le pipeline

Maintenant que vous avez spécifié les entrées et sorties de données et créé les étapes de votre pipeline, vous pouvez les composer dans un pipeline et l’exécuter :

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

L’objet Pipeline que vous créez s’exécute dans votre workspace et se compose des étapes de préparation et d’entraînement que vous avez spécifiées.

Notes

Ce pipeline a un graphique de dépendances simple : l’étape d’entraînement repose sur l’étape de préparation, tandis que l’étape de préparation repose sur le jeu de données fashion_ds. Les pipelines de production présentent souvent des dépendances bien plus complexes. Les étapes peuvent reposer sur plusieurs étapes en amont, une modification du code source dans une des premières étapes peut avoir des conséquences graves, et ainsi de suite. Azure Machine Learning s’occupe de ces préoccupations pour vous. Vous avez juste à passer le tableau de steps et Azure Machine Learning prend en charge le calcul du graphique d’exécution.

L’appel à submitExperiment s’exécute rapidement et produit une sortie similaire à ce qui suit :

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

Vous pouvez surveiller l’exécution du pipeline en ouvrant le lien ou vous pouvez bloquer jusqu’à ce qu’il se termine en exécutant :

run.wait_for_completion(show_output=True)

Important

La première exécution du pipeline prend environ 15 minutes. Toutes les dépendances doivent être téléchargées, une image Docker est créée, et l’environnement Python est provisionné et créé. La réexécution du pipeline prend beaucoup moins de temps, car ces ressources sont réutilisées au lieu d’être créées. Toutefois, le temps total d’exécution du pipeline dépend de la charge de travail de vos scripts et des processus qui s’exécutent à chaque étape du pipeline.

Une fois que le pipeline a fini de s’exécuter, vous pouvez récupérer les métriques que vous avez journalisées au cours de l’étape d’entraînement :

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

Si vous êtes satisfait des métriques, vous pouvez inscrire le modèle dans votre espace de travail :

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

Nettoyer les ressources

Sautez cette section si vous prévoyez de suivre d’autres tutoriels Azure Machine Learning.

Arrêter l’instance de calcul

Si vous avez utilisé une instance de calcul, arrêtez la machine virtuelle quand vous ne l’utilisez pas afin de réduire les coûts.

  1. Dans votre espace de travail, sélectionnez Capacité de calcul.

  2. Dans la liste, sélectionnez le nom de l’instance de calcul.

  3. Sélectionnez Arrêter.

  4. Quand vous êtes prêt à utiliser à nouveau le serveur, sélectionnez Démarrer.

Tout supprimer

Si vous n’avez pas l’intention d’utiliser les ressources que vous avez créées, supprimez-les pour éviter des frais :

  1. Dans le portail Azure, dans le menu de gauche, sélectionnez Groupes de ressources.
  2. Dans la liste des groupes de ressources, sélectionnez le groupe de ressources que vous avez créé.
  3. Sélectionnez Supprimer le groupe de ressources.
  4. Entrez le nom du groupe de ressources. Ensuite, sélectionnez Supprimer.

Vous pouvez également conserver le groupe de ressources mais supprimer un espace de travail unique. Affichez les propriétés de l’espace de travail, puis sélectionnez Supprimer.

Étapes suivantes

Dans ce tutoriel, vous avez utilisé les types suivants :

  • Le Workspace représente votre espace de travail Azure Machine Learning. Il contenait :
    • Le Experiment qui contient les résultats des exécutions d’entraînement de votre pipeline
    • Le Dataset qui a chargé tardivement les données conservées dans le magasin de données Fashion-MNIST
    • Le ComputeTarget qui représente la ou les machines sur lesquelles s’exécutent les étapes de pipeline
    • Le Environment qui est l’environnement d’exécution dans lequel les étapes de pipeline s’exécutent
    • Le Pipeline qui compose les étapes PythonScriptStep dans un ensemble
    • Le Model que vous avez inscrit après avoir satisfait du processus d’entraînement

L’objet Workspace contient des références à d’autres ressources (notebooks, points de terminaison, etc.) qui n’ont pas été utilisées dans ce tutoriel. Pour plus d’informations, consultez Qu’est-ce qu’un espace de travail Azure Machine Learning ?.

Le OutputFileDatasetConfig promeut la sortie d’une exécution à un jeu de données basé sur des fichiers. Pour plus d’informations sur les jeux de données et l’utilisation des données, consultez Guide pratique pour accéder aux données.

Pour plus d’informations sur les environnements et les cibles de calcul, consultez Que sont les cibles de calcul dans Azure Machine Learning ? et Ques sont les environnements Azure Machine Learning ?

Le ScriptRunConfig associe un ComputeTarget et Environment à des fichiers sources Python. Un PythonScriptStep prend ce ScriptRunConfig et définit ses entrées et ses sorties, qui dans ce pipeline étaient le jeu de données de fichier généré par le OutputFileDatasetConfig.

Pour obtenir d’autres exemples de création de pipelines à l’aide du SDK Machine Learning, consultez le dépôt d’exemples.