Créer, entraîner, déployer et surveiller un modèle de machine learning

avec Amazon SageMaker Studio

Amazon SageMaker Studio est le premier environnement de développement entièrement intégré (IDE) pour machine learning qui fournit une interface visuelle unique en ligne pour effectuer toutes les étapes de développement du machine learning.

Dans ce didacticiel, vous utiliserez Amazon SageMaker Studio pour créer, entraîner, déployer et surveiller un modèle XGBoost. Vous couvrirez l'ensemble du flux de travail du machine learning (ML) depuis l'ingénierie de fonctionnalités et l'entraînement de modèles aux déploiements en lots et en direct des modèles de machine learning.

Dans ce didacticiel, vous allez apprendre à :

  1. Configurer le Panneau de configuration d'Amazon SageMaker Studio
  2. Télécharger un ensemble de données public à l'aide d'un bloc-notes d'Amazon SageMaker Studio et le charger sur Amazon S3
  3. Créer une expérience Amazon SageMaker pour suivre et gérer les tâches d'entraînement et de traitement
  4. Exécuter une tâche de traitement Amazon SageMaker afin de générer des fonctionnalités à partir de données brutes
  5. Entraîner un modèle à l'aide de l'algorithme intégré XGBoost
  6. Tester la performance du modèle sur l'ensemble de données test à l'aide d'Amazon SageMaker Batch Transform
  7. Déployer le modèle en tant que point de terminaison et configurer une tâche de surveillance afin de surveiller le point de terminaison du modèle dans la production pour la dérive des données.
  8. Visualiser les résultats et surveiller le modèle à l'aide du SageMaker Model Monitor afin de déterminer les différences entre l'ensemble de données d'entraînement et le modèle déployé.

Le modèle sera entraîné sur l'ensemble de données des cartes de crédit UCI par défaut qui contient des information sur les données démographiques des clients, l'historique des paiements et l'historique de la facturation.

À propos de ce didacticiel
Durée 1 heure                                      
Coût Moins de 10 USD
Cas d'utilisation Machine learning
Produits Amazon SageMaker
Public ciblé Développeur, scientifique des données
Niveau Intermédiaire
Dernière mise à jour 17 août 2020

Étape 1. Créer un compte AWS

Les ressources créées et utilisées dans ce tutoriel sont éligibles à l'offre gratuite AWS. Le coût de cet atelier est inférieur à 10 USD.

Vous possédez déjà un compte ? Connectez-vous.

Étape 2. Créer votre Panneau de configuration d'Amazon SageMaker Studio

Suivez les étapes ci-dessous pour vous inscrire à Amazon SageMaker Studio et configurer votre panneau de configuration d'Amazon SageMaker.

Remarque : pour en savoir plus, consultez la page Démarrage avec Amazon SageMaker Studio de la documentation d'Amazon SageMaker.


a. Connectez-vous à la console Amazon SageMaker

Remarque : dans le coin supérieur droit, assurez-vous de sélectionner une région AWS dans laquelle SageMaker Studio est disponible. Pour avoir une liste des régions, consultez la page S'inscrire à Amazon SageMaker Studio.


b. Dans le volet de navigation d' Amazon SageMaker, sélectionnez Amazon SageMaker Studio.
 
Remarque : si vous utilisez Amazon SageMaker Studio pour la première fois, vous devez passer par le processus d'inscription à Studio. Au moment de l'inscription, vous avez le choix entre AWS Single Sign-On (AWS SSO) et AWS Identity and Access Management (IAM) comme méthode d'authentification. Si vous optez pour l'authentification IAM, vous avez le choix entre le démarrage rapide et la procédure de configuration standard. Si vous ne savez pas quelle option choisir, consultez la page S'inscrire à Amazon SageMaker Studio et demandez l'aide de votre administrateur informatique. Pour plus de simplicité, ce didacticiel utilise la procédure Démarrage rapide.

c. Dans la fenêtre Démarrage, sélectionnez Démarrage rapide et indiquez un nom d'utilisateur.

d. Pour Rôle d'exécution, sélectionnez Créer un rôle IAM. Dans la boîte de dialogue qui s'ouvre, sélectionnez N'importe quel compartiment S3 et sélectionnez Créer un rôle.

Amazon SageMaker crée un rôle avec les autorisations nécessaires et l'affecte à votre instance.  


e. Cliquez sur Soumettre.

Étape 3. Télécharger l'ensemble de données

Les blocs-notes d'Amazon SageMaker Studio sont des blocs-notes Jupyter à un clic qui contiennent tout ce dont vous avez besoin pour créer et tester vos scripts d'entraînement. SageMaker Studio comprend également un suivi et une visualisation des expériences afin que vous puissiez facilement gérer l'ensemble de votre flux de travail de machine learning de manière centralisée.

Effectuez les opérations suivantes afin de créer un bloc-notes SageMaker, téléchargez l'ensemble de données et ensuite chargez l'ensemble de données sur Amazon S3.

Remarque : pour en savoir plus, consultez la page Utilisation des blocs-notes d'Amazon SageMaker Studio de la documentation d'Amazon SageMaker.


a. Sur le Panneau de configuration d'Amazon SageMaker Studio, sélectionnez Open Studio.

b. Dans JupyterLab, sur le menu Fichier, sélectionnez Nouveau, puis Bloc-notes. Dans la fenêtre Sélection du noyau, sélectionnez Python 3 (science des données).
 

c. Vérifiez d'abord votre version d' Amazon SageMaker Python SDK. Copiez et collez le bloc de code suivant dans la cellule de code et sélectionnez Exécuter. Si un message d'impression affiche Installation de la version précédente de SageMaker. Veuillez redémarrer le noyau , sélectionnez l'onglet Noyau et sélectionnez Redémarrer le noyau. Ensuite, vous pouvez continuer les étapes restantes.
 
Remarque : pendant l'exécution du code, un signe * apparaît entre les crochets. Après quelques secondes, l'exécution du code se termine et le signe * est remplacé par un chiffre.
import boto3
import sagemaker
from sagemaker import get_execution_role
import sys

if int(sagemaker.__version__.split('.')[0]) == 2:
    !{sys.executable} -m pip install sagemaker==1.72.0
    print("Installing previous SageMaker Version. Please restart the kernel")
else:
    print("Version is good")

role = get_execution_role()
sess = sagemaker.Session()
region = boto3.session.Session().region_name
print("Region = {}".format(region))
sm = boto3.Session().client('sagemaker')
Ensuite, importez les bibliothèques. Copiez et collez le code suivant dans la cellule de code et sélectionnez Exécuter.
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import os
from time import sleep, gmtime, strftime
import json
import time
Enfin, importez les expériences. Copiez et collez le code suivant dans la cellule de code et sélectionnez Exécuter.
!pip install sagemaker-experiments 
from sagemaker.analytics import ExperimentAnalytics
from smexperiments.experiment import Experiment
from smexperiments.trial import Trial
from smexperiments.trial_component import TrialComponent
from smexperiments.tracker import Tracker

d. Définissez les compartiment et les dossiers Amazon S3 pour le projet. Copiez et collez le code suivant dans la cellule de code et sélectionnez Exécuter.
rawbucket= sess.default_bucket() # Alternatively you can use our custom bucket here. 

prefix = 'sagemaker-modelmonitor' # use this prefix to store all files pertaining to this workshop.

dataprefix = prefix + '/data'
traindataprefix = prefix + '/train_data'
testdataprefix = prefix + '/test_data'
testdatanolabelprefix = prefix + '/test_data_no_label'
trainheaderprefix = prefix + '/train_headers'

e. Téléchargez l'ensemble des données et importez-le à l'aide de la bibliothèque pandas. Copiez et collez le code suivant dans une nouvelle cellule de code et sélectionnez Exécuter.

! wget https://archive.ics.uci.edu/ml/machine-learning-databases/00350/default%20of%20credit%20card%20clients.xls
data = pd.read_excel('default of credit card clients.xls', header=1)
data = data.drop(columns = ['ID'])
data.head()

f. Renommez la dernière colonne Étiquette et effectuez séparément l'extraction de la colonne des étiquettes. Pour l'algorithme XGBoost intégré à Amazon SageMaker, la colonne des étiquettes doit être la première colonne du dataframe. Pour effectuer cette modification, copiez et collez le code suivant dans une nouvelle cellule de code et sélectionnez Exécuter.

data.rename(columns={"default payment next month": "Label"}, inplace=True)
lbl = data.Label
data = pd.concat([lbl, data.drop(columns=['Label'])], axis = 1)
data.head()

g. Chargez l'ensemble de données CSV dans un compartiment Amazon S3. Copiez et collez le code suivant dans une nouvelle cellule de code et sélectionnez Exécuter.

if not os.path.exists('rawdata/rawdata.csv'):
    !mkdir rawdata
    data.to_csv('rawdata/rawdata.csv', index=None)
else:
    pass
# Upload the raw dataset
raw_data_location = sess.upload_data('rawdata', bucket=rawbucket, key_prefix=dataprefix)
print(raw_data_location)

Et voilà ! Le code de sortie indique l'URI du compartiment S3 comme suit :

s3://sagemaker-us-east-2-ACCOUNT_NUMBER/sagemaker-modelmonitor/data

Étape 4: Traiter les données à l'aide d'Amazon SageMaker Processing

Dans cette étape, vous utilisez Amazon SageMaker Processing afin de prétraiter l'ensemble des données, y compris le dimensionnement des colonnes et la répartition de l'ensemble des données dans les données d'entraînement et de test. Amazon SageMaker Processing permet d'exécuter les charges de travail de prétraitement, de post-traitement et d'évaluation du modèle sur une infrastructure entièrement gérée.

Suivez les étapes suivantes pour traiter les données et générer des fonctionnalités à l'aide d'Amazon SageMaker Processing.

Remarque : Amazon SageMaker Processing s'exécute sur des instances de calcul distinctes de votre bloc-notes. Cela signifie que vous pouvez continuer à expérimenter et exécuter du code dans votre bloc-notes pendant que la tâche de traitement est en cours. Cela entraînera des frais supplémentaires pour le coût de l'instance qui est fonctionnelle pendant la durée de la tâche de traitement. Les instances sont automatiquement résiliées par SageMaker dès que la tâche de traitement se termine. Pour consulter les informations de tarification, reportez-vous à la page Tarification Amazon SageMaker.

Remarque : pour en savoir plus, consultez la page Traiter des données et évaluer des modèles de la documentation d'Amazon SageMaker.


a. Importez le conteneur de traitement scikit-learn. Copiez et collez le code suivant dans une nouvelle cellule de code et sélectionnez Exécuter.

Remarque : Amazon SageMaker fournit un conteneur géré pour scikit-learn. Pour en savoir plus, consultez la page Traiter des données et évaluer des modèles avec scikit-learn.

from sagemaker.sklearn.processing import SKLearnProcessor
sklearn_processor = SKLearnProcessor(framework_version='0.20.0',
                                     role=role,
                                     instance_type='ml.c4.xlarge',
                                     instance_count=1)

b. Copiez et collez le script de prétraitement suivant dans une nouvelle cellule et sélectionnez Exécuter.

%%writefile preprocessing.py

import argparse
import os
import warnings

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.exceptions import DataConversionWarning
from sklearn.compose import make_column_transformer

warnings.filterwarnings(action='ignore', category=DataConversionWarning)

if __name__=='__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--train-test-split-ratio', type=float, default=0.3)
    parser.add_argument('--random-split', type=int, default=0)
    args, _ = parser.parse_known_args()
    
    print('Received arguments {}'.format(args))

    input_data_path = os.path.join('/opt/ml/processing/input', 'rawdata.csv')
    
    print('Reading input data from {}'.format(input_data_path))
    df = pd.read_csv(input_data_path)
    df.sample(frac=1)
    
    COLS = df.columns
    newcolorder = ['PAY_AMT1','BILL_AMT1'] + list(COLS[1:])[:11] + list(COLS[1:])[12:17] + list(COLS[1:])[18:]
    
    split_ratio = args.train_test_split_ratio
    random_state=args.random_split
    
    X_train, X_test, y_train, y_test = train_test_split(df.drop('Label', axis=1), df['Label'], 
                                                        test_size=split_ratio, random_state=random_state)
    
    preprocess = make_column_transformer(
        (['PAY_AMT1'], StandardScaler()),
        (['BILL_AMT1'], MinMaxScaler()),
    remainder='passthrough')
    
    print('Running preprocessing and feature engineering transformations')
    train_features = pd.DataFrame(preprocess.fit_transform(X_train), columns = newcolorder)
    test_features = pd.DataFrame(preprocess.transform(X_test), columns = newcolorder)
    
    # concat to ensure Label column is the first column in dataframe
    train_full = pd.concat([pd.DataFrame(y_train.values, columns=['Label']), train_features], axis=1)
    test_full = pd.concat([pd.DataFrame(y_test.values, columns=['Label']), test_features], axis=1)
    
    print('Train data shape after preprocessing: {}'.format(train_features.shape))
    print('Test data shape after preprocessing: {}'.format(test_features.shape))
    
    train_features_headers_output_path = os.path.join('/opt/ml/processing/train_headers', 'train_data_with_headers.csv')
    
    train_features_output_path = os.path.join('/opt/ml/processing/train', 'train_data.csv')
    
    test_features_output_path = os.path.join('/opt/ml/processing/test', 'test_data.csv')
    
    print('Saving training features to {}'.format(train_features_output_path))
    train_full.to_csv(train_features_output_path, header=False, index=False)
    print("Complete")
    
    print("Save training data with headers to {}".format(train_features_headers_output_path))
    train_full.to_csv(train_features_headers_output_path, index=False)
                 
    print('Saving test features to {}'.format(test_features_output_path))
    test_full.to_csv(test_features_output_path, header=False, index=False)
    print("Complete")

c. Copiez le code de prétraitement dans le compartiment Amazon S3 à l'aide du code suivant, puis sélectionnez Exécuter.

# Copy the preprocessing code over to the s3 bucket
codeprefix = prefix + '/code'
codeupload = sess.upload_data('preprocessing.py', bucket=rawbucket, key_prefix=codeprefix)
print(codeupload)

d. Indiquez l'emplacement où vous souhaitez stocker vos données d'entraînement et de test à la fin de la tâche de SageMaker Processing. Amazon SageMaker Processing stocke automatiquement les données dans l'emplacement indiqué.

train_data_location = rawbucket + '/' + traindataprefix
test_data_location = rawbucket+'/'+testdataprefix
print("Training data location = {}".format(train_data_location))
print("Test data location = {}".format(test_data_location))


e. Copiez et collez le code suivant pour démarrer la tâche de traitement. Ce code démarre la tâche en lançant sklearn_processor.run et extrait certaines métadonnées optimales relatives à la tâche de traitement, telle que l'emplacement de stockage des résultats d'entraînement et de test.

from sagemaker.processing import ProcessingInput, ProcessingOutput

sklearn_processor.run(code=codeupload,
                      inputs=[ProcessingInput(
                        source=raw_data_location,
                        destination='/opt/ml/processing/input')],
                      outputs=[ProcessingOutput(output_name='train_data',
                                                source='/opt/ml/processing/train',
                               destination='s3://' + train_data_location),
                               ProcessingOutput(output_name='test_data',
                                                source='/opt/ml/processing/test',
                                               destination="s3://"+test_data_location),
                               ProcessingOutput(output_name='train_data_headers',
                                                source='/opt/ml/processing/train_headers',
                                               destination="s3://" + rawbucket + '/' + prefix + '/train_headers')],
                      arguments=['--train-test-split-ratio', '0.2']
                     )

preprocessing_job_description = sklearn_processor.jobs[-1].describe()

output_config = preprocessing_job_description['ProcessingOutputConfig']
for output in output_config['Outputs']:
    if output['OutputName'] == 'train_data':
        preprocessed_training_data = output['S3Output']['S3Uri']
    if output['OutputName'] == 'test_data':
        preprocessed_test_data = output['S3Output']['S3Uri']


Notez les emplacement du code et des données d'entraînement et de test dans les résultats fournis au processeur. Notez également les arguments fournis aux scripts de traitement.  

Étape 5 : Créer une expérience Amazon SageMaker

Maintenant que vous avez téléchargé et compartimenté votre ensemble de données dans Amazon S3, vous pouvez créer une expérience Amazon SageMaker. Une expérience est une collection de tâches de traitement et d'entraînement liées au même projet de machine learning. Amazon SageMaker Experiments gère et suit automatiquement vos exécutions d'entraînement pour vous.

Suivez les étapes suivantes pour créer une nouvelle expérience.

Remarque : pour en savoir plus, consultez la page Expériences de la documentation d'Amazon SageMaker.


a. Copiez et collez le code suivant afin de créer une expérience nommée Créer-entraîner-déployer-.

# Create a SageMaker Experiment
cc_experiment = Experiment.create(
    experiment_name=f"Build-train-deploy-{int(time.time())}", 
    description="Predict credit card default from payments data", 
    sagemaker_boto_client=sm)
print(cc_experiment)

Chaque tâche d'entraînement est enregistrée comme un essai. Chaque essai est une itération de bout en bout de votre tâche d'entraînement. En plus de la tâche d'entraînement, il peut également suivre les tâches de prétraitement et de post-traitement ainsi que les ensembles de données et d'autres métadonnées. Une seule expérience peut comprendre plusieurs essais qui vous facilitent de suivre plusieurs itérations au fil du temps dans le cadre du volet Amazon SageMaker Studio Experiments.


b. Copiez et collez le code suivant pour suivre votre tâche de prétraitement sous Expériences ainsi qu'une étape dans le pipeline d'entraînement.

# Start Tracking parameters used in the Pre-processing pipeline.
with Tracker.create(display_name="Preprocessing", sagemaker_boto_client=sm) as tracker:
    tracker.log_parameters({
        "train_test_split_ratio": 0.2,
        "random_state":0
    })
    # we can log the s3 uri to the dataset we just uploaded
    tracker.log_input(name="ccdefault-raw-dataset", media_type="s3/uri", value=raw_data_location)
    tracker.log_input(name="ccdefault-train-dataset", media_type="s3/uri", value=train_data_location)
    tracker.log_input(name="ccdefault-test-dataset", media_type="s3/uri", value=test_data_location)

c. Consultez les détails de votre expérience : dans le volet Expériences, faites un clic droit sur l'expérience nommée Créer-entraîner-déployer- et sélectionnez Ouvrir dans une liste de composants d'essai.


d. Copiez et collez le code suivant et sélectionnez Exécuter. Ensuite, examinez le code :

Pour entraîner un classificateur XGBoost, vous importez d'abord le conteneur XGBoost mis à jour par Amazon SageMaker. Ensuite, vous enregistrez l'exécution d'entraînement sous un Essai afin que SageMaker Experiments puisse la suivre sous un nom d'Essai. La tâche de prétraitement est incluse sous le même nom d'essai car elle fait partie du pipeline. Ensuite, créez un objet SageMaker Estimator qui met automatiquement en service le type d'instance sous-jacent de votre choix, copie les données d'entraînement de l'emplacement de sortie spécifié de la tâche de traitement, entraîne le modèle et génère les artefacts du modèle.

from sagemaker.amazon.amazon_estimator import get_image_uri
container = get_image_uri(boto3.Session().region_name, 'xgboost', '1.0-1')
s3_input_train = sagemaker.s3_input(s3_data='s3://' + train_data_location, content_type='csv')
preprocessing_trial_component = tracker.trial_component

trial_name = f"cc-default-training-job-{int(time.time())}"
cc_trial = Trial.create(
        trial_name=trial_name, 
            experiment_name=cc_experiment.experiment_name,
        sagemaker_boto_client=sm
    )

cc_trial.add_trial_component(preprocessing_trial_component)
cc_training_job_name = "cc-training-job-{}".format(int(time.time()))

xgb = sagemaker.estimator.Estimator(container,
                                    role, 
                                    train_instance_count=1, 
                                    train_instance_type='ml.m4.xlarge',
                                    train_max_run=86400,
                                    output_path='s3://{}/{}/models'.format(rawbucket, prefix),
                                    sagemaker_session=sess) # set to true for distributed training

xgb.set_hyperparameters(max_depth=5,
                        eta=0.2,
                        gamma=4,
                        min_child_weight=6,
                        subsample=0.8,
                        verbosity=0,
                        objective='binary:logistic',
                        num_round=100)

xgb.fit(inputs = {'train':s3_input_train},
       job_name=cc_training_job_name,
        experiment_config={
            "TrialName": cc_trial.trial_name, #log training job in Trials for lineage
            "TrialComponentDisplayName": "Training",
        },
        wait=True,
    )
time.sleep(2)

La tâche d'entraînement dure environ 70 secondes. Vous devrez obtenir le résultat suivant.

Completed - Training job completed

e. Sélectionnez Expérience dans la barre d'outils de gauche. Faites un clic droit sur l'expérience Créer-entraîner-déployer- et sélectionnez Ouvrir dans la liste des composants d'essai. Amazon SageMaker Experiments capture toutes les exécutions, y compris les exécutions d'entraînement en échec.


f. Faites un clic droit sur l'une des Tâches d'entraînement terminées et sélectionnez Ouvrir dans les détails des essais afin d'explorer les métadonnées associées à la tâche d'entraînement.  

Remarque : vous pourriez devoir actualiser la page pour voir les derniers résultats.  

Étape 6: Déployer un modèle pour une inférence hors ligne

Dans votre étape de prétraitement, vous avez généré des données de test. Au cours de cette étape, vous allez générer une inférence hors ligne ou en lots à partir du modèle entraîné afin d'évaluer les performances du modèle sur des données de test non vues.

Suivez les étapes suivantes pour déployer le modèle pour une inférence hors ligne.

Remarque : pour en savoir plus, consultez la page Batch Transform de la documentation d'Amazon SageMaker.


a. Copiez et collez le code suivant et sélectionnez Exécuter.

Cette étape copie l'ensemble de données de test depuis l'emplacement Amazon S3 dans votre dossier local.  

test_data_path = 's3://' + test_data_location + '/test_data.csv'
! aws s3 cp $test_data_path .

b. Copiez et collez le code suivant et sélectionnez Exécuter.

test_full = pd.read_csv('test_data.csv', names = [str(x) for x in range(len(data.columns))])
test_full.head()

c. Copiez et collez le code suivant et sélectionnez Exécuter. Cette étape extrait la colonne des étiquettes.

label = test_full['0'] 

d. Copiez et collez le code suivant et sélectionnez Exécuter pour créer la tâche Batch Transform. Ensuite, examinez le code :

Comme la tâche d'entraînement, SageMaker met en service toutes les ressources sous-jacentes, copie les artefacts du modèle entraîné, configure localement un point de terminaison Batch, y copie les données et exécute des inférences sur les données en envoyant les résultats à Amazon S3. Notez qu'en configurant leinput_filter, vous faites savoir à Batch Transform de ne pas prendre en compte la première colonne dans les données de test, qui est la colonne des étiquettes.

%%time

sm_transformer = xgb.transformer(1, 'ml.m5.xlarge', accept = 'text/csv')

# start a transform job
sm_transformer.transform(test_data_path, split_type='Line', input_filter='$[1:]', content_type='text/csv')
sm_transformer.wait()

La tâche Batch Transform dure environ 4 minutes à la fin desquelles vous pouvez évaluer les résultats du modèle.


e. Copiez et collez le code suivant pour évaluer les métriques du modèle. Ensuite, examinez le code :

En premier lieu, définissez une fonction qui extrait le résultat de la tâche Batch Transform contenu dans un fichier à extension .out depuis le compartiment Amazon S3. Ensuite, vous effectuez l'extraction des étiquettes prévues dans un dataframe et vous apposez les bonnes étiquettes à ce dataframe.

import json
import io
from urllib.parse import urlparse

def get_csv_output_from_s3(s3uri, file_name):
    parsed_url = urlparse(s3uri)
    bucket_name = parsed_url.netloc
    prefix = parsed_url.path[1:]
    s3 = boto3.resource('s3')
    obj = s3.Object(bucket_name, '{}/{}'.format(prefix, file_name))
    return obj.get()["Body"].read().decode('utf-8')
output = get_csv_output_from_s3(sm_transformer.output_path, 'test_data.csv.out')
output_df = pd.read_csv(io.StringIO(output), sep=",", header=None)
output_df.head(8)
output_df['Predicted']=np.round(output_df.values)
output_df['Label'] = label
from sklearn.metrics import confusion_matrix, accuracy_score
confusion_matrix = pd.crosstab(output_df['Predicted'], output_df['Label'], rownames=['Actual'], colnames=['Predicted'], margins = True)
confusion_matrix

Vous devez obtenir un résultat similaire à l'image, qui affiche le nombre total de valeurs Vraies et Fausses Prévues comparées aux valeurs Actuelles.  


f. Utilisez le code suivant pour extraire la précision du modèle de référence et la précision du modèle.

Remarque : un modèle utile pour la précision de la référence peut être la fraction des cas qui ne sont pas en défaut. Un modèle qui prédit toujours qu'un utilisateur ne sera pas en défaut présente cette précision.

print("Baseline Accuracy = {}".format(1- np.unique(data['Label'], return_counts=True)[1][1]/(len(data['Label']))))
print("Accuracy Score = {}".format(accuracy_score(label, output_df['Predicted'])))

Les résultats affichent qu'un simple modèle peut déjà surpasser la précision de la référence. Afin d'améliorer les résultats, vous pouvez régler les hyperparamètres. Vous pouvez utiliser l'optimisation des hyperparamètres (HPO) sur SageMaker pour le réglage automatique d'un modèle. Pour en savoir plus, consultez la page Fonctionnement du réglage des hyperparamètres

Remarque : bien que Batch Transform ne soit pas inclus dans ce didacticiel dans le cadre de votre essai, vous avez également la possibilité de l'inclure. Lorsque vous lancez la fonction .transform, passez simplement experiment_config comme vous l'avez fait dans la tâche d'entraînement. Amazon SageMaker associe automatiquement Batch Transform en tant que composant d'essai.

Étape 7 : Déployer le modèle en tant que point de terminaison et configurer la capture des données

Dans cette étape, vous déployez le modèle en tant que point de terminaison RESTful HTTPS afin de desservir des inférences en direct. Amazon SageMaker gère automatiquement l'hébergement du modèle et la création du point de terminaison.

Suivez les étapes suivantes pour déployer le modèle en tant que point de terminaison et configurer la capture des données.

Remarque : pour en savoir plus, consultez la page Déployer des modèles pour inférence de la documentation d'Amazon SageMaker.


a. Copiez et collez le code suivant et sélectionnez Exécuter.

from sagemaker.model_monitor import DataCaptureConfig
from sagemaker import RealTimePredictor
from sagemaker.predictor import csv_serializer

sm_client = boto3.client('sagemaker')

latest_training_job = sm_client.list_training_jobs(MaxResults=1,
                                                SortBy='CreationTime',
                                                SortOrder='Descending')

training_job_name=TrainingJobName=latest_training_job['TrainingJobSummaries'][0]['TrainingJobName']

training_job_description = sm_client.describe_training_job(TrainingJobName=training_job_name)

model_data = training_job_description['ModelArtifacts']['S3ModelArtifacts']
container_uri = training_job_description['AlgorithmSpecification']['TrainingImage']

# create a model.
def create_model(role, model_name, container_uri, model_data):
    return sm_client.create_model(
        ModelName=model_name,
        PrimaryContainer={
        'Image': container_uri,
        'ModelDataUrl': model_data,
        },
        ExecutionRoleArn=role)
    

try:
    model = create_model(role, training_job_name, container_uri, model_data)
except Exception as e:
        sm_client.delete_model(ModelName=training_job_name)
        model = create_model(role, training_job_name, container_uri, model_data)
        

print('Model created: '+model['ModelArn'])


b. Pour préciser les paramètres de configuration des données, copiez et collez le code suivant et sélectionnez Exécuter.

Ce code indique à SageMaker de capturer 100 % des charges d'inférence reçues par le point de terminaison, de capturer les entrées et les sorties et de noter également le type du contenu d'entrée sous un format csv.

s3_capture_upload_path = 's3://{}/{}/monitoring/datacapture'.format(rawbucket, prefix)
data_capture_configuration = {
    "EnableCapture": True,
    "InitialSamplingPercentage": 100,
    "DestinationS3Uri": s3_capture_upload_path,
    "CaptureOptions": [
        { "CaptureMode": "Output" },
        { "CaptureMode": "Input" }
    ],
    "CaptureContentTypeHeader": {
       "CsvContentTypes": ["text/csv"],
       "JsonContentTypes": ["application/json"]}

c. Copiez et collez le code suivant et sélectionnez Exécuter. Cette étape crée une configuration du point de terminaison et déploie le point de terminaison. Dans ce code, vous pouvez préciser le type d'instance et si vous souhaitez envoyer tout le trafic vers ce point de terminaison, etc.

def create_endpoint_config(model_config, data_capture_config): 
    return sm_client.create_endpoint_config(
                                                EndpointConfigName=model_config,
                                                ProductionVariants=[
                                                        {
                                                            'VariantName': 'AllTraffic',
                                                            'ModelName': model_config,
                                                            'InitialInstanceCount': 1,
                                                            'InstanceType': 'ml.m4.xlarge',
                                                            'InitialVariantWeight': 1.0,
                                                },
                                                    
                                                    ],
                                                DataCaptureConfig=data_capture_config
                                                )




try:
    endpoint_config = create_endpoint_config(training_job_name, data_capture_configuration)
except Exception as e:
    sm_client.delete_endpoint_config(EndpointConfigName=endpoint)
    endpoint_config = create_endpoint_config(training_job_name, data_capture_configuration)

print('Endpoint configuration created: '+ endpoint_config['EndpointConfigArn'])

d. Copiez et collez le code suivant et sélectionnez Exécuter pour créer le point de terminaison.  

# Enable data capture, sampling 100% of the data for now. Next we deploy the endpoint in the correct VPC.

endpoint_name = training_job_name
def create_endpoint(endpoint_name, config_name):
    return sm_client.create_endpoint(
                                    EndpointName=endpoint_name,
                                    EndpointConfigName=training_job_name
                                )


try:
    endpoint = create_endpoint(endpoint_name, endpoint_config)
except Exception as e:
    sm_client.delete_endpoint(EndpointName=endpoint_name)
    endpoint = create_endpoint(endpoint_name, endpoint_config)

print('Endpoint created: '+ endpoint['EndpointArn'])

e. Sélectionnez Points de terminaison dans la barre d'outils de gauche. La liste Points de terminaison affiche tous les points de terminaison en service.

Remarquez que le point de terminaison créer-entraîner-déployer affiche le statut Création. Pour déployer le modèle, Amazon SageMaker doit d'abord copier vos artefacts de modèles et l'image de l'inférence dans l'instance et configurer un point de terminaison HTTPS sur l'interface avec les applications client ou les API RESTful.

Une fois que la création du point de terminaison est terminée, le statut change et affiche En service. (Notez que la création d'un point de terminaison peut durer entre 5 à 10 minutes.)  

Remarque : vous devrez peut-être cliquer sur Actualiser pour obtenir le statut mis à jour.


f. Dans le bloc-notes JupyterLab, copiez et exécutez le code suivant afin d'obtenir un échantillon de l'ensemble des données test. Ce code occupe les 10 premières lignes.

!head -10 test_data.csv > test_sample.csv

g. Exécutez le code suivant pour envoyer des demandes d'inférence à ce point de terminaison.

Remarque : si vous avez indiqué un autre nom de point de terminaison, vous devrez remplacer le point de terminaison ci-dessous par le nom de votre point de terminaison.  

from sagemaker import RealTimePredictor
from sagemaker.predictor import csv_serializer

predictor = RealTimePredictor(endpoint=endpoint_name, content_type = 'text/csv')

with open('test_sample.csv', 'r') as f:
    for row in f:
        payload = row.rstrip('\n')
        response = predictor.predict(data=payload[2:])
        sleep(0.5)
print('done!')

h. Exécutez le code suivant pour vérifier que Model Monitor capture correctement les données entrantes.

Dans le code, le current_endpoint_capture_prefix capture le chemin du répertoire dans lequel les résultats de ModelMonitor sont stockés. Accédez à votre compartiment Amazon S3 pour voir si les demandes de prédiction sont en train d'être capturées. Notez que cet emplacement doit correspondre au s3_capture_upload_path dans le code ci-dessus.

# Extract the captured json files.
data_capture_prefix = '{}/monitoring'.format(prefix)
s3_client = boto3.Session().client('s3')
current_endpoint_capture_prefix = '{}/datacapture/{}/AllTraffic'.format(data_capture_prefix, endpoint_name)
print(current_endpoint_capture_prefix)
result = s3_client.list_objects(Bucket=rawbucket, Prefix=current_endpoint_capture_prefix)
capture_files = [capture_file.get("Key") for capture_file in result.get('Contents')]
print("Found Capture Files:")
print("\n ".join(capture_files))


capture_files[0]

Le résultat capturé indique que la capture des données est configurée et qu'elle enregistre les demandes entrantes.  

Remarque : si vous voyez une réponse Null, les données peuvent ne pas avoir été chargées de manière synchronisée dans le chemin Amazon S3 lors de l'initialisation de la capture des données. Attendez environ une minute puis réessayez.


i. Exécutez le code suivant pour extraire le contenu de l'un des fichiers json et afficher les résultats capturés. 

# View contents of the captured file.
def get_obj_body(bucket, obj_key):
    return s3_client.get_object(Bucket=rawbucket, Key=obj_key).get('Body').read().decode("utf-8")

capture_file = get_obj_body(rawbucket, capture_files[0])
print(json.dumps(json.loads(capture_file.split('\n')[5]), indent = 2, sort_keys =True))

Ce résultat indique que la capture des données est en train de capturer à la fois la charge entrante et la sortie du modèle.  

Étape 8 : Surveiller le point de terminaison avec SageMaker Model Monitor

Dans cette étape, vous activerez SageMaker Model Monitor pour surveiller le point de terminaison déployé pour la dérive des données. Pour cela, vous comparez la charge et les sorties envoyées au modèle à une référence et déterminez s'il y a une dérive dans les données d'entrée ou dans l'étiquette.  

Suivez les étapes suivantes pour activer la surveillance des modèles.

Remarque : pour en savoir plus, consultez la page Amazon SageMaker Model Monitor de la documentation d'Amazon SageMaker.


a. Exécutez le code suivant afin de créer un dossier dans votre compartiment Amazon S3 en vue d'enregistrer les sorties de Model Monitor.

Ce code crée deux dossiers : un dossier enregistre les données de référence que vous avez utilisées pour l'entraînement de votre modèle ; le deuxième dossier enregistre toutes les violations à cette référence.

model_prefix = prefix + "/" + endpoint_name
baseline_prefix = model_prefix + '/baselining'
baseline_data_prefix = baseline_prefix + '/data'
baseline_results_prefix = baseline_prefix + '/results'

baseline_data_uri = 's3://{}/{}'.format(rawbucket,baseline_data_prefix)
baseline_results_uri = 's3://{}/{}'.format(rawbucket, baseline_results_prefix)
train_data_header_location = "s3://" + rawbucket + '/' + prefix + '/train_headers'
print('Baseline data uri: {}'.format(baseline_data_uri))
print('Baseline results uri: {}'.format(baseline_results_uri))
print(train_data_header_location)


b. Exécutez le code suivant pour configurer une tâche de référence pour Model Monitor afin de capturer les statistiques des données d'entraînement. Pour cela, Model Monitor utilise la bibliothèque deequ développée sur Apache Spark pour mener des tests d'unités sur les données.  

from sagemaker.model_monitor import DefaultModelMonitor
from sagemaker.model_monitor.dataset_format import DatasetFormat

my_default_monitor = DefaultModelMonitor(
    role=role,
    instance_count=1,
    instance_type='ml.m5.xlarge',
    volume_size_in_gb=20,
    max_runtime_in_seconds=3600)

my_default_monitor.suggest_baseline(
    baseline_dataset=os.path.join(train_data_header_location, 'train_data_with_headers.csv'),
    dataset_format=DatasetFormat.csv(header=True),
    output_s3_uri=baseline_results_uri,
    wait=True
)

Model Monitor configure une instance séparée, y copie les données d'entraînement et génère certaines statistiques. Le service génère plusieurs journaux Apache Spark que vous pouvez ignorer. Une fois la tâche terminée, vous verrez le résultat Tâche Spark terminée.


c. Exécutez le code suivant pour examiner les résultats générés par la tâche de référence.

s3_client = boto3.Session().client('s3')
result = s3_client.list_objects(Bucket=rawbucket, Prefix=baseline_results_prefix)
report_files = [report_file.get("Key") for report_file in result.get('Contents')]
print("Found Files:")
print("\n ".join(report_files))

baseline_job = my_default_monitor.latest_baselining_job
schema_df = pd.io.json.json_normalize(baseline_job.baseline_statistics().body_dict["features"])
schema_df

Vous trouverez deux fichiers : constraints.json et statistics.json. Ensuite, examinez leur contenu en détail :

Le code ci-dessus convertit la sortie json dans /statistics.json en un dataframe pandas. Remarquez comment la bibliothèque deequ infère le type de données de la colonne, la présence ou l'absence de valeurs nulles ou manquantes et des paramètres statistiques tels que la moyenne, le minimum, le maximum, la somme, la déviation standard et les paramètres des croquis pour un flux de données en entrée.  

De même, le fichier constraints.json consiste en un nombre de contraintes auxquelles l'ensemble de données d'entraînement obéit, telles que la non-négativité des valeurs et le type de données du champ de fonctionnalités.

Vous trouverez deux fichiers : constraints.json et statistics.json. Ensuite, examinez leur contenu en détail :

Le code ci-dessus convertit la sortie json dans /statistics.json en un dataframe pandas. Remarquez comment la bibliothèque deequ infère le type de données de la colonne, la présence ou l'absence de valeurs nulles ou manquantes et des paramètres statistiques tels que la moyenne, le minimum, le maximum, la somme, la déviation standard et les paramètres des croquis pour un flux de données en entrée.   

De même, le fichier constraints.json consiste en un nombre de contraintes auxquelles l'ensemble de données d'entraînement obéit, telles que la non-négativité des valeurs et le type de données du champ de fonctionnalités.

constraints_df = pd.io.json.json_normalize(baseline_job.suggested_constraints().body_dict["features"])
constraints_df

d. Exécutez le code suivant pour configurer la fréquence de la surveillance du point de terminaison.

Vous pouvez préciser qu'elle soit quotidienne ou horaire. Ce code indique une fréquence horaire, mais vous pouvez souhaiter la modifier pour les applications de productions car la fréquence horaire génèrera beaucoup de données. Model Monitor produira un rapport consistant de toutes les violations qu'il trouve.

reports_prefix = '{}/reports'.format(prefix)
s3_report_path = 's3://{}/{}'.format(rawbucket,reports_prefix)
print(s3_report_path)

from sagemaker.model_monitor import CronExpressionGenerator
from time import gmtime, strftime

mon_schedule_name = 'Built-train-deploy-model-monitor-schedule-' + strftime("%Y-%m-%d-%H-%M-%S", gmtime())
my_default_monitor.create_monitoring_schedule(
    monitor_schedule_name=mon_schedule_name,
    endpoint_input=predictor.endpoint,
    output_s3_uri=s3_report_path,
    statistics=my_default_monitor.baseline_statistics(),
    constraints=my_default_monitor.suggested_constraints(),
    schedule_cron_expression=CronExpressionGenerator.hourly(),
    enable_cloudwatch_metrics=True,

)

Notez que ce code active les métriques d'Amazon CloudWatch qui indique à Model Monitor d'envoyer des résultats à CloudWatch. Vous pouvez utiliser cette approche pour déclencher des alarmes à l'aide des alarmes CloudWatch afin que les ingénieurs ou les administrateurs sachent quand une dérive de données a été détectée.  

Étape 9 : Tester les performances de SageMaker Model Monitor

Dans cette étape, vous évaluez Model Monitor par rapport à des échantillons de données. Au lieu d'envoyer la charge de test comme elle est, vous modifiez la distribution de plusieurs fonctionnalités dans la charge de test pour découvrir si Model Moniteur peut détecter la modification.

Suivez les étapes suivantes pour tester les performances de Model Monitor.

Remarque : pour en savoir plus, consultez la page Amazon SageMaker Model Monitor de la documentation d'Amazon SageMaker.


a. Exécutez le code suivant pour importer les données de test et générer des échantillons modifiés de données.

COLS = data.columns
test_full = pd.read_csv('test_data.csv', names = ['Label'] +['PAY_AMT1','BILL_AMT1'] + list(COLS[1:])[:11] + list(COLS[1:])[12:17] + list(COLS[1:])[18:]
)
test_full.head()

b. Exécutez le code suivant pour modifier certaines colonnes. Remarquez les différences marquées en rouge sur l'image de l'étape précédente. Supprimez la colonne des étiquettes et enregistrez l'échantillon modifié des données de test.

faketestdata = test_full
faketestdata['EDUCATION'] = -faketestdata['EDUCATION'].astype(float)
faketestdata['BILL_AMT2']= (faketestdata['BILL_AMT2']//10).astype(float)
faketestdata['AGE']= (faketestdata['AGE']-10).astype(float)

faketestdata.head()
faketestdata.drop(columns=['Label']).to_csv('test-data-input-cols.csv', index = None, header=None)

c. Exécutez le code suivant pour invoquer le point de terminaison de manière répétée à l'aide de cet ensemble de données modifié.

from threading import Thread

runtime_client = boto3.client('runtime.sagemaker')

# (just repeating code from above for convenience/ able to run this section independently)
def invoke_endpoint(ep_name, file_name, runtime_client):
    with open(file_name, 'r') as f:
        for row in f:
            payload = row.rstrip('\n')
            response = runtime_client.invoke_endpoint(EndpointName=ep_name,
                                          ContentType='text/csv', 
                                          Body=payload)
            time.sleep(1)
            
def invoke_endpoint_forever():
    while True:
        invoke_endpoint(endpoint, 'test-data-input-cols.csv', runtime_client)
        
thread = Thread(target = invoke_endpoint_forever)
thread.start()
# Note that you need to stop the kernel to stop the invocations

d. Exécutez le code suivant pour vérifier le statut de la tâche de Model Monitor.

desc_schedule_result = my_default_monitor.describe_schedule()
print('Schedule status: {}'.format(desc_schedule_result['MonitoringScheduleStatus']))

Vous devez obtenir un résultat Statut du programme : programmé


e. Exécutez le code suivant pour vérifier chaque 10 minutes si des résultats de surveillance ont été générés. Notez que la première tâche pourrait s'exécuter avec un tampon d'environ 20 minutes.  

mon_executions = my_default_monitor.list_executions()
print("We created ahourly schedule above and it will kick off executions ON the hour (plus 0 - 20 min buffer.\nWe will have to wait till we hit the hour...")

while len(mon_executions) == 0:
    print("Waiting for the 1st execution to happen...")
    time.sleep(600)
    mon_executions = my_default_monitor.list_executions()

f. Dans la barre d'outils de gauche d'Amazon SageMaker Studio, sélectionnez Points de terminaison. Faites un clic droit sur le point de terminaison créer-entraîner-déployer et sélectionnez Décrire le point de terminaison.


g. Sélectionnez Surveiller l'historique des tâches. Remarquez que le Statut de surveillance affiche En cours.

Une fois que la tâche est terminée, le Statut de surveillance affichera Problème trouvé (pour tout problème trouvé).  


h. Faites un double-clic sur le problème pour afficher les détails. Vous pouvez remarquer que Model Monitor a détecté de larges déviations de référence dans les champs ÉDUCATION et BILL_AMT2 que vous avez précédemment modifiés.

Model Monitor a également détecté certaines différences dans les types de donnés dans deux autres champs. Les données d'entraînement consistent en étiquettes d'entiers, mais le modèle XGBoost prédit un score de probabilité. Par conséquent, Model Monitor a signalé une incohérence.  


i. Dans votre Bloc-notes JupyterLab, exécutez les cellules suivantes pour voir le résultat de Model Monitor.

latest_execution = mon_executions[-1] # latest execution's index is -1, second to last is -2 and so on..
time.sleep(60)
latest_execution.wait(logs=False)

print("Latest execution status: {}".format(latest_execution.describe()['ProcessingJobStatus']))
print("Latest execution result: {}".format(latest_execution.describe()['ExitMessage']))

latest_job = latest_execution.describe()
if (latest_job['ProcessingJobStatus'] != 'Completed'):
        print("====STOP==== \n No completed executions to inspect further. Please wait till an execution completes or investigate previously reported failures.")

j. Exécutez le code suivant pour afficher les rapports générés par Model Monitor.

report_uri=latest_execution.output.destination
print('Report Uri: {}'.format(report_uri))
from urllib.parse import urlparse
s3uri = urlparse(report_uri)
report_bucket = s3uri.netloc
report_key = s3uri.path.lstrip('/')
print('Report bucket: {}'.format(report_bucket))
print('Report key: {}'.format(report_key))

s3_client = boto3.Session().client('s3')
result = s3_client.list_objects(Bucket=rawbucket, Prefix=report_key)
report_files = [report_file.get("Key") for report_file in result.get('Contents')]
print("Found Report Files:")
print("\n ".join(report_files))

Vous pouvez remarquer que, outre les fichiers statistics.json et constraints.json, il existe un nouveau fichier généré sous le nom constraint_violations.json. Le contenu de ce fichier a été affiché au-dessus, dans Amazon SageMaker Studio (étape g).


Remarque : une fois que vous configurez la capture des données, Amazon SageMaker Studio vous crée automatiquement un bloc-notes contenant le code ci-dessus afin d'exécuter des tâches de surveillance. Pour accéder au bloc-notes, faites un clic droit sur le point de terminaison et sélectionnez Décrire le point de terminaison. Dans l'onglet Résultats de surveillance, sélectionnez Activer la surveillance. Cette étape ouvre automatiquement un bloc-notes Jupyter contenant le code que vous avez créé ci-dessus.

Étape 10. Nettoyer

À ce stade, vous résiliez les ressources utilisées dans cet atelier.

Important : il est conseillé de résilier les ressources qui ne sont pas utilisées de façon active, afin de réduire les coûts. Des ressources non résiliées peuvent entraîner des frais sur votre compte.


a. Suppression des programmes de surveillance : dans votre bloc-notes Jupyter, copiez et collez le code suivant et sélectionnez Exécuter.

Remarque : vous ne pouvez pas supprimer le point de terminaison de Model Monitor avant de supprimer toutes les tâches de surveillance associées au point de terminaison.

my_default_monitor.delete_monitoring_schedule()
time.sleep(10) # actually wait for the deletion

b. Suppression de votre point de terminaison : dans votre bloc-notes Jupyter, copiez et collez le code suivant et sélectionnez Exécuter.

Remarque : assurez-vous de supprimer d'abord toutes les tâches de surveillance associées au point de terminaison.

sm.delete_endpoint(EndpointName = endpoint_name)

Si vous souhaitez nettoyer tous les artefacts d'entraînement (modèles, ensembles de données pré-traités, etc.), copiez et collez le code suivant dans votre cellule de code et sélectionnez Exécuter.

Remarque : pensez à bien remplacer ACCOUNT-NUMBER par votre numéro de compte.

%%sh
aws s3 rm --recursive s3://sagemaker-us-east-2-ACCOUNT_NUMBER/sagemaker-modelmonitor/data

Félicitations !

Vous avez réussi à créer, entraîner, déployer et surveiller un modèle de machine learning avec Amazon SageMaker Studio.

Ce didacticiel vous a-t-il été utile ?

Apprenez à créer, entraîner et déployer automatiquement des modèles de machine learning à l'aide d'Amazon SageMaker Autopilot