Exécuter ce tutoriel sous forme de notebook dans Colab | Afficher le notebook sur GitHub |
Ce tutoriel explique comment entraîner un réseau de neurones sur AI Platform à l'aide de l'API séquentielle Keras et comment diffuser des prédictions à partir de ce modèle.
Keras est une API de haut niveau permettant de créer et d'entraîner des modèles de deep learning. tf.keras constitue la mise en œuvre de cette API par TensorFlow.
Les deux premières parties du tutoriel expliquent comment entraîner un modèle sur AI Platform à l'aide de code Keras pré-écrit, déployer le modèle entraîné sur AI Platform et diffuser des prédictions en ligne à partir du modèle déployé.
La dernière partie du tutoriel traite du code d'entraînement utilisé pour ce modèle et des éléments qui permettent d'en garantir la compatibilité avec AI Platform. Pour en savoir plus sur la création de modèles de machine learning dans Keras d'une manière générale, reportez-vous aux tutoriels sur Keras de TensorFlow.
Ensemble de données
Ce tutoriel utilise un ensemble de données sur le revenu obtenues par recensement aux États-Unis, fournies par l'UCI Machine Learning Repository (dépôt de machine learning de l'Université de Californie à Irvine). Cet ensemble de données contient des informations sur les personnes issues d'une base de données du recensement 1994, comprenant des caractéristiques d'âge, de niveau d'études, d'état civil, de profession et indiquant si le revenu de la personne est supérieur à 50 000 dollars par an.
Objectif
L'objectif est d'entraîner un réseau de neurones profond (DNN, Deep Neural Network) à l'aide de Keras, qui permet de prédire si un individu gagne plus de 50 000 $ par an (étiquette cible) à partir d'autres informations issues du recensement sur la personne (caractéristiques).
Ce tutoriel porte davantage sur l'utilisation de ce modèle avec AI Platform que sur la conception du modèle. Toutefois, lors de la création de systèmes de machine learning, il est important de considérer les problèmes potentiels et les conséquences inattendues qu'impliquent de tels modèles. Consultez l'exercice du cours d'initiation au machine learning relatif au principe d'équité pour en savoir plus sur les sources de biais dans l'ensemble de données du recensement, ainsi que sur le principe d'équité dans le domaine du machine learning en général.
Coûts
Ce tutoriel utilise des composants facturables de Google Cloud, y compris :
- AI Platform Training
- AI Platform Prediction
- Cloud Storage
Découvrez les tarifs d'AI Platform Training, les tarifs d'AI Platform Prediction et les tarifs de Cloud Storage, puis utilisez le simulateur de coûts pour générer une estimation des coûts en fonction de votre utilisation prévue.
Avant de commencer
Vous devez effectuer plusieurs opérations avant de pouvoir entraîner et déployer un modèle dans AI Platform :
- Configurer l'environnement de développement local
- Configurer un projet Google Cloud avec la facturation et les API nécessaires activées
- Créer un bucket Cloud Storage pour stocker le package d'entraînement et le modèle entraîné
Configurer l'environnement de développement local
Pour suivre ce tutoriel, vous avez besoin des éléments suivants :
- Git
- Python 3
- virtualenv
- Le SDK Google Cloud
Le guide Google Cloud Configurer un environnement de développement Python fournit des instructions détaillées permettant de répondre à ces exigences. Les étapes suivantes présentent un condensé de ces instructions :
Installez virtualenv et créez un environnement virtuel utilisant Python 3.
Activez cet environnement.
Effectuez les étapes de la section suivante pour installer le SDK Cloud.
Configurer un projet Google Cloud
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the AI Platform Training & Prediction and Compute Engine APIs.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the AI Platform Training & Prediction and Compute Engine APIs.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
Authentifier le compte GCP
Pour configurer l'authentification, vous devez créer une clé de compte de service et définir une variable d'environnement pour le chemin d'accès à la clé de compte de service.
-
Créez un compte de service :
-
Dans la console Google Cloud, accédez à la page Créer un compte de service.
- Dans le champ Nom du compte de service, saisissez un nom.
- Facultatif : Dans le champ Description du compte de service, saisissez une description.
- Cliquez sur Créer.
- Cliquez sur le champ Sélectionner un rôle. Sous Tous les rôles, sélectionnez AI Platform > Administrateur AI Platform.
- Cliquez sur Ajouter un autre rôle.
-
Cliquez sur le champ Sélectionner un rôle. Sous Tous les rôles, sélectionnez Stockage > Administrateur des objets de l'espace de stockage.
-
Cliquez sur Terminé pour créer le compte de service.
Ne fermez pas la fenêtre de votre navigateur. Vous en aurez besoin lors de la tâche suivante.
-
-
Créez une clé de compte de service pour l'authentification :
- Dans la console Google Cloud, cliquez sur l'adresse e-mail du compte de service que vous avez créé.
- Cliquez sur Keys (Clés).
- Cliquez sur AJOUTER UNE CLÉ -> Créer une clé.
- Cliquez sur Créer. Un fichier de clé JSON est téléchargé sur votre ordinateur.
- Cliquez sur Close (Fermer).
-
Définissez la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS de façon à pointer vers le chemin du fichier JSON contenant la clé de votre compte de service. Cette variable ne s'applique qu'à la session d'interface système actuelle. Par conséquent, si vous ouvrez une nouvelle session, vous devez la définir à nouveau.
Créer un bucket Cloud Storage
Lorsque vous envoyez une tâche d'entraînement à l'aide du SDK Cloud, vous importez un package Python contenant votre code d'entraînement dans un bucket Cloud Storage. AI Platform exécute le code de ce package. Dans ce tutoriel, le modèle entraîné résultant de la tâche est enregistré par AI Platform dans le même bucket. Vous pouvez ensuite créer une version du modèle AI Platform basée sur ce résultat afin de diffuser des prédictions en ligne.
Définissez le nom du bucket Cloud Storage en tant que variable d'environnement. Ce nom doit être unique dans tous les buckets Cloud Storage :
BUCKET_NAME="your-bucket-name"
Sélectionnez une région dans laquelle AI Platform Training et AI Platform Prediction sont disponibles, et créez une autre variable d'environnement. Exemple :
REGION="us-central1"
Créez le bucket Cloud Storage dans cette région, puis utilisez cette même région pour l'entraînement et les prédictions. Exécutez la commande suivante pour créer le bucket s'il n'existe pas déjà :
gsutil mb -l $REGION gs://$BUCKET_NAME
Démarrage rapide pour effectuer l'entraînement dans AI Platform
Cette section du tutoriel explique comment envoyer une tâche d'entraînement à AI Platform. Cette tâche exécute un exemple de code qui utilise Keras pour entraîner un réseau de neurones profond à partir des données de recensement en provenance des États-Unis. Le modèle entraîné est généré en tant que répertoire TensorFlow SavedModel dans le bucket Cloud Storage.
Obtenir le code d'entraînement et les dépendances
Tout d’abord, téléchargez le code d'entraînement et modifiez le répertoire de travail :
# Clone the repository of AI Platform samples
git clone --depth 1 https://github.com/GoogleCloudPlatform/cloudml-samples
# Set the working directory to the sample code directory
cd cloudml-samples/census/tf-keras
Notez que le code d'entraînement est structuré comme un package Python dans le sous-répertoire trainer/
:
# `ls` shows the working directory's contents. The `p` flag adds trailing
# slashes to subdirectory names. The `R` flag lists subdirectories recursively.
ls -pR
.: README.md requirements.txt trainer/ ./trainer: __init__.py model.py task.py util.py
Ensuite, installez les dépendances Python nécessaires pour entraîner le modèle localement :
pip install -r requirements.txt
Lorsque vous exécutez la tâche d'entraînement dans AI Platform, les dépendances sont préinstallées en fonction de la version d'exécution choisie.
Entraîner votre modèle localement
Avant de procéder à l'entraînement sur AI Platform, effectuez l'entraînement localement pour vérifier que la structure du fichier et le packaging sont corrects.
Pour une tâche complexe ou exigeante en ressources, vous pouvez procéder à l'entraînement localement sur un petit échantillon de l'ensemble de données afin de vérifier votre code. Exécutez ensuite la tâche dans AI Platform pour effectuer l'entraînement sur la totalité de l'ensemble de données.
Cet exemple exécute une tâche relativement rapide sur un petit ensemble de données. Par conséquent, l'entraînement local et la tâche AI Platform exécutent le même code sur les mêmes données.
Exécutez la commande suivante pour entraîner un modèle localement :
# This is similar to `python -m trainer.task --job-dir local-training-output`
# but it better replicates the AI Platform environment, especially
# for distributed training (not applicable here).
gcloud ai-platform local train \
--package-path trainer \
--module-name trainer.task \
--job-dir local-training-output
Observez les progrès de l'entraînement dans l'interface système. En fin d'opération, l'application d'entraînement exporte le modèle entraîné et affiche un message de ce type :
Model exported to: local-training-output/keras_export/1553709223
Entraîner votre modèle avec AI Platform
Envoyez une tâche d'entraînement à AI Platform. Cette opération exécute le module d'entraînement dans le cloud et exporte le modèle entraîné vers Cloud Storage.
Tout d'abord, attribuez un nom à la tâche d'entraînement et choisissez un répertoire dans votre bucket Cloud Storage pour l'enregistrement des fichiers intermédiaires et de sortie. Définissez ces éléments comme variables d'environnement. Exemple :
JOB_NAME="my_first_keras_job"
JOB_DIR="gs://$BUCKET_NAME/keras-job-dir"
Exécutez la commande suivante pour empaqueter le répertoire trainer/
, l'importer dans le --job-dir
spécifié, puis indiquer à AI Platform d'exécuter le module trainer.task
à partir de ce package.
L'option --stream-logs
vous permet d'afficher les journaux d'entraînement dans votre interface système. Vous pouvez également consulter les journaux et les autres informations sur la tâche dans Google Cloud Console.
gcloud ai-platform jobs submit training $JOB_NAME \
--package-path trainer/ \
--module-name trainer.task \
--region $REGION \
--python-version 3.7 \
--runtime-version 1.15 \
--job-dir $JOB_DIR \
--stream-logs
Cette façon de procéder prend plus de temps que l'entraînement local, mais elle permet d'observer les progrès de l'entraînement dans votre interface système de la même manière. À la fin de l'opération, la tâche d'entraînement exporte le modèle entraîné dans votre bucket Cloud Storage et affiche un message de ce type :
INFO 2019-03-27 17:57:11 +0000 master-replica-0 Model exported to: gs://your-bucket-name/keras-job-dir/keras_export/1553709421 INFO 2019-03-27 17:57:11 +0000 master-replica-0 Module completed; cleaning up. INFO 2019-03-27 17:57:11 +0000 master-replica-0 Clean up finished. INFO 2019-03-27 17:57:11 +0000 master-replica-0 Task completed successfully.
Réglages d'hyperparamètres
Vous pouvez également effectuer un réglage des hyperparamètres à l'aide du fichier de configuration hptuning_config.yaml
inclus. Ce fichier indique à AI Platform d'ajuster la taille de lot et le taux d'apprentissage de l'entraînement sur plusieurs essais afin d'optimiser la justesse.
Dans cet exemple, le code d'entraînement utilise un rappel TensorBoard, qui crée un Summary
Event
TensorFlow pendant l'entraînement. AI Platform suit la métrique que vous souhaitez optimiser à l'aide de ces événements. En savoir plus sur le réglage des hyperparamètres dans AI Platform Training.
gcloud ai-platform jobs submit training ${JOB_NAME}_hpt \
--config hptuning_config.yaml \
--package-path trainer/ \
--module-name trainer.task \
--region $REGION \
--python-version 3.7 \
--runtime-version 1.15 \
--job-dir $JOB_DIR \
--stream-logs
Démarrage rapide pour effectuer des prédictions en ligne dans AI Platform
Cette section explique comment utiliser AI Platform et votre modèle entraîné généré dans la section précédente pour prédire la tranche de revenu d'une personne à partir d'autres informations de recensement la concernant.
Créer des ressources de modèle et de version dans AI Platform
Pour diffuser des prédictions en ligne à l'aide du modèle que vous avez entraîné et exporté dans le guide de démarrage rapide pour effectuer l'entraînement, créez une ressource de modèle dans AI Platform et une ressource de version à l'intérieur de celle-ci. La ressource de version est l'élément sur lequel s'appuie votre modèle entraîné pour diffuser les prédictions. Cette structure vous permet de corriger et de ré-entraîner le modèle plusieurs fois. Elle permet également d'organiser toutes les versions dans AI Platform. Pour en savoir plus, consultez la section concernant les modèles et les versions.
Tout d'abord, nommez et créez la ressource de modèle :
MODEL_NAME="my_first_keras_model"
gcloud ai-platform models create $MODEL_NAME \
--regions $REGION
Created ml engine model [projects/your-project-id/models/my_first_keras_model].
Ensuite, créez la version du modèle. La tâche d'entraînement créée dans le démarrage rapide pour effectuer l'entraînement a exporté un répertoire TensorFlow SavedModel horodaté vers votre bucket Cloud Storage. AI Platform utilise ce répertoire pour créer une version de modèle. Apprenez-en plus sur SavedModel et AI Platform.
Le chemin d'accès à ce répertoire doit se trouver dans les journaux de votre tâche d'entraînement. Recherchez une ligne semblable à celle-ci :
Model exported to: gs://your-bucket-name/keras-job-dir/keras_export/1545439782
Exécutez la commande suivante pour identifier votre répertoire SavedModel et utilisez-le pour créer une ressource de version du modèle :
MODEL_VERSION="v1"
# Get a list of directories in the `keras_export` parent directory. Then pick
# the directory with the latest timestamp, in case you've trained multiple
# times.
SAVED_MODEL_PATH=$(gsutil ls $JOB_DIR/keras_export | head -n 1)
# Create model version based on that SavedModel directory
gcloud ai-platform versions create $MODEL_VERSION \
--model $MODEL_NAME \
--region $REGION \
--runtime-version 1.15 \
--python-version 3.7 \
--framework tensorflow \
--origin $SAVED_MODEL_PATH
Préparer les données d'entrée pour la prédiction
Pour obtenir des prédictions valides et pertinentes, vous devez prétraiter les données d'entrée de la même manière que vous l'avez fait pour les données d'entraînement. Dans un système de production, vous pouvez créer un pipeline de prétraitement qui sera exécuté pendant la phase de prédiction de la même manière qu'en phase d'entraînement.
Pour cet exercice, utilisez le code de chargement des données du package d'entraînement pour sélectionner un échantillon aléatoire à partir des données d'évaluation. Ces données se présentent sous la forme qui a été utilisée pour évaluer la précision après chaque époque d’entraînement. Vous pouvez donc les réemployer pour envoyer des prédictions tests sans autre prétraitement.
Ouvrez l'interpréteur Python (python
) à partir de votre répertoire de travail actuel afin d'exécuter les extraits de code ci-dessous :
from trainer import util
_, _, eval_x, eval_y = util.load_data()
prediction_input = eval_x.sample(20)
prediction_targets = eval_y[prediction_input.index]
prediction_input
age | workclass | education_num | marital_status | occupation | relationship | race | capital_gain | capital_loss | hours_per_week | native_country | |
---|---|---|---|---|---|---|---|---|---|---|---|
1979 | 0.901213 | 1 | 1.525542 | 2 | 9 | 0 | 4 | -0.144792 | -0.21713 | -0.437544 | 38 |
2430 | -0.922154 | 3 | -0.419265 | 4 | 2 | 3 | 4 | -0.144792 | -0.21713 | -0.034039 | 38 |
4214 | -1.213893 | 3 | -0.030304 | 4 | 10 | 1 | 4 | -0.144792 | -0.21713 | 1.579979 | 38 |
10389 | -0.630415 | 3 | 0.358658 | 4 | 0 | 3 | 4 | -0.144792 | -0.21713 | -0.679647 | 38 |
14525 | -1.505632 | 3 | -1.586149 | 4 | 7 | 3 | 0 | -0.144792 | -0.21713 | -0.034039 | 38 |
15040 | -0.119873 | 5 | 0.358658 | 2 | 2 | 0 | 4 | -0.144792 | -0.21713 | -0.841048 | 38 |
8409 | 0.244801 | 3 | 1.525542 | 2 | 9 | 0 | 4 | -0.144792 | -0.21713 | 1.176475 | 6 |
10628 | 0.098931 | 1 | 1.525542 | 2 | 9 | 0 | 4 | 0.886847 | -0.21713 | -0.034039 | 38 |
10942 | 0.390670 | 5 | -0.030304 | 2 | 4 | 0 | 4 | -0.144792 | -0.21713 | 4.727315 | 38 |
5129 | 1.120017 | 3 | 1.136580 | 2 | 12 | 0 | 4 | -0.144792 | -0.21713 | -0.034039 | 38 |
2096 | -1.286827 | 3 | -0.030304 | 4 | 11 | 3 | 4 | -0.144792 | -0.21713 | -1.648058 | 38 |
12463 | -0.703350 | 3 | -0.419265 | 2 | 7 | 5 | 4 | -0.144792 | 4.502280 | -0.437544 | 38 |
8528 | 0.536539 | 3 | 1.525542 | 4 | 3 | 4 | 4 | -0.144792 | -0.21713 | -0.034039 | 38 |
7093 | -1.359762 | 3 | -0.419265 | 4 | 6 | 3 | 2 | -0.144792 | -0.21713 | -0.034039 | 38 |
12565 | 0.536539 | 3 | 1.136580 | 0 | 11 | 2 | 2 | -0.144792 | -0.21713 | -0.034039 | 38 |
5655 | 1.338821 | 3 | -0.419265 | 2 | 2 | 0 | 4 | -0.144792 | -0.21713 | -0.034039 | 38 |
2322 | 0.682409 | 3 | 1.136580 | 0 | 12 | 3 | 4 | -0.144792 | -0.21713 | -0.034039 | 38 |
12652 | 0.025997 | 3 | 1.136580 | 2 | 11 | 0 | 4 | -0.144792 | -0.21713 | 0.369465 | 38 |
4755 | -0.411611 | 3 | -0.419265 | 2 | 11 | 0 | 4 | -0.144792 | -0.21713 | 1.176475 | 38 |
4413 | 0.390670 | 6 | 1.136580 | 4 | 4 | 1 | 4 | -0.144792 | -0.21713 | -0.034039 | 38 |
Notez que les champs catégoriels, tels que occupation
, ont déjà été convertis en nombres entiers (selon le même mappage que celui utilisé pour l'entraînement). Les champs numériques, tels que age
, ont été normalisés au score z.
Certains champs ont été supprimés des données d'origine. Comparez les données d'entrée de la prédiction avec les données brutes pour les mêmes échantillons :
import pandas as pd
_, eval_file_path = util.download(util.DATA_DIR)
raw_eval_data = pd.read_csv(eval_file_path,
names=util._CSV_COLUMNS,
na_values='?')
raw_eval_data.iloc[prediction_input.index]
age | workclass | fnlwgt | education | education_num | marital_status | occupation | relationship | race | gender | capital_gain | capital_loss | hours_per_week | native_country | income_bracket | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1979 | 51 | Local-gov | 99064 | Masters | 14 | Married-civ-spouse | Prof-specialty | Husband | White | Male | 0 | 0 | 35 | United-States | <=50K |
2430 | 26 | Private | 197967 | HS-grad | 9 | Never-married | Craft-repair | Own-child | White | Male | 0 | 0 | 40 | United-States | <=50K |
4214 | 22 | Private | 221694 | Some-college | 10 | Never-married | Protective-serv | Not-in-family | White | Male | 0 | 0 | 60 | United-States | <=50K |
10389 | 30 | Private | 96480 | Assoc-voc | 11 | Never-married | Adm-clerical | Own-child | White | Female | 0 | 0 | 32 | United-States | <=50K |
14525 | 18 | Private | 146225 | 10e | 6 | Never-married | Other-service | Own-child | Amer-Indian-Eskimo | Female | 0 | 0 | 40 | United-States | <=50K |
15040 | 37 | Self-emp-not-inc | 50096 | Assoc-voc | 11 | Married-civ-spouse | Craft-repair | Husband | White | Male | 0 | 0 | 30 | United-States | <=50K |
8409 | 42 | Private | 102988 | Masters | 14 | Married-civ-spouse | Prof-specialty | Husband | White | Male | 0 | 0 | 55 | Ecuador | >50K |
10628 | 40 | Local-gov | 284086 | Masters | 14 | Married-civ-spouse | Prof-specialty | Husband | White | Male | 7688 | 0 | 40 | United-States | >50K |
10942 | 44 | Self-emp-not-inc | 52505 | Some-college | 10 | Married-civ-spouse | Farming-fishing | Husband | White | Male | 0 | 0 | 99 | United-States | <=50K |
5129 | 54 | Private | 106728 | Bachelors | 13 | Married-civ-spouse | Tech-support | Husband | White | Male | 0 | 0 | 40 | United-States | <=50K |
2096 | 21 | Private | 190916 | Some-college | 10 | Never-married | Sales | Own-child | White | Female | 0 | 0 | 20 | United-States | <=50K |
12463 | 29 | Private | 197565 | HS-grad | 9 | Married-civ-spouse | Other-service | Wife | White | Female | 0 | 1902 | 35 | United-States | >50K |
8528 | 46 | Private | 193188 | Masters | 14 | Never-married | Exec-managerial | Unmarried | White | Male | 0 | 0 | 40 | United-States | <=50K |
7093 | 20 | Private | 273147 | HS-grad | 9 | Never-married | Machine-op-inspct | Own-child | Black | Male | 0 | 0 | 40 | United-States | <=50K |
12565 | 46 | Private | 203653 | Bachelors | 13 | Divorced | Sales | Other-relative | Black | Male | 0 | 0 | 40 | United-States | <=50K |
5655 | 57 | Private | 174662 | HS-grad | 9 | Married-civ-spouse | Craft-repair | Husband | White | Male | 0 | 0 | 40 | United-States | <=50K |
2322 | 48 | Private | 232149 | Bachelors | 13 | Divorced | Tech-support | Own-child | White | Female | 0 | 0 | 40 | United-States | <=50K |
12652 | 39 | Private | 82521 | Bachelors | 13 | Married-civ-spouse | Sales | Husband | White | Male | 0 | 0 | 45 | United-States | >50K |
4755 | 33 | Private | 330715 | HS-grad | 9 | Married-civ-spouse | Sales | Husband | White | Male | 0 | 0 | 55 | United-States | <=50K |
4413 | 44 | State-gov | 128586 | Bachelors | 13 | Never-married | Farming-fishing | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
Exportez les données d'entrée de la prédiction dans un fichier JSON délimité par un retour à la ligne :
import json
with open('prediction_input.json', 'w') as json_file:
for row in prediction_input.values.tolist():
json.dump(row, json_file)
json_file.write('\n')
Quittez l'interpréteur Python (exit()
). À partir de votre interface système, examinez prediction_input.json
:
cat prediction_input.json
[0.9012127751273994, 1.0, 1.525541514460902, 2.0, 9.0, 0.0, 4.0, -0.14479173735784842, -0.21713186390175285, -0.43754385253479555, 38.0] [-0.9221541171760282, 3.0, -0.4192650914017433, 4.0, 2.0, 3.0, 4.0, -0.14479173735784842, -0.21713186390175285, -0.03403923708700391, 38.0] [-1.2138928199445767, 3.0, -0.030303770229214273, 4.0, 10.0, 1.0, 4.0, -0.14479173735784842, -0.21713186390175285, 1.5799792247041626, 38.0] [-0.6304154144074798, 3.0, 0.35865755094331475, 4.0, 0.0, 3.0, 4.0, -0.14479173735784842, -0.21713186390175285, -0.6796466218034705, 38.0] [-1.5056315227131252, 3.0, -1.5861490549193304, 4.0, 7.0, 3.0, 0.0, -0.14479173735784842, -0.21713186390175285, -0.03403923708700391, 38.0] [-0.11987268456252011, 5.0, 0.35865755094331475, 2.0, 2.0, 0.0, 4.0, -0.14479173735784842, -0.21713186390175285, -0.8410484679825871, 38.0] [0.24480069389816542, 3.0, 1.525541514460902, 2.0, 9.0, 0.0, 4.0, -0.14479173735784842, -0.21713186390175285, 1.176474609256371, 6.0] [0.0989313425138912, 1.0, 1.525541514460902, 2.0, 9.0, 0.0, 4.0, 0.8868473744801746, -0.21713186390175285, -0.03403923708700391, 38.0] [0.39067004528243965, 5.0, -0.030303770229214273, 2.0, 4.0, 0.0, 4.0, -0.14479173735784842, -0.21713186390175285, 4.7273152251969375, 38.0] [1.1200168022038106, 3.0, 1.1365801932883728, 2.0, 12.0, 0.0, 4.0, -0.14479173735784842, -0.21713186390175285, -0.03403923708700391, 38.0] [-1.2868274956367138, 3.0, -0.030303770229214273, 4.0, 11.0, 3.0, 4.0, -0.14479173735784842, -0.21713186390175285, -1.6480576988781703, 38.0] [-0.7033500900996169, 3.0, -0.4192650914017433, 2.0, 7.0, 5.0, 4.0, -0.14479173735784842, 4.5022796885373735, -0.43754385253479555, 38.0] [0.5365393966667138, 3.0, 1.525541514460902, 4.0, 3.0, 4.0, 4.0, -0.14479173735784842, -0.21713186390175285, -0.03403923708700391, 38.0] [-1.3597621713288508, 3.0, -0.4192650914017433, 4.0, 6.0, 3.0, 2.0, -0.14479173735784842, -0.21713186390175285, -0.03403923708700391, 38.0] [0.5365393966667138, 3.0, 1.1365801932883728, 0.0, 11.0, 2.0, 2.0, -0.14479173735784842, -0.21713186390175285, -0.03403923708700391, 38.0] [1.338820829280222, 3.0, -0.4192650914017433, 2.0, 2.0, 0.0, 4.0, -0.14479173735784842, -0.21713186390175285, -0.03403923708700391, 38.0] [0.6824087480509881, 3.0, 1.1365801932883728, 0.0, 12.0, 3.0, 4.0, -0.14479173735784842, -0.21713186390175285, -0.03403923708700391, 38.0] [0.0259966668217541, 3.0, 1.1365801932883728, 2.0, 11.0, 0.0, 4.0, -0.14479173735784842, -0.21713186390175285, 0.3694653783607877, 38.0] [-0.4116113873310685, 3.0, -0.4192650914017433, 2.0, 11.0, 0.0, 4.0, -0.14479173735784842, -0.21713186390175285, 1.176474609256371, 38.0] [0.39067004528243965, 6.0, 1.1365801932883728, 4.0, 4.0, 1.0, 4.0, -0.14479173735784842, -0.21713186390175285, -0.03403923708700391, 38.0]
L'outil de ligne de commande gcloud
accepte les données JSON délimitées par des retours à la ligne pour la prédiction en ligne. Ce modèle Keras attend une liste de nombres pour chaque exemple d'entrée.
AI Platform requiert un format différent lorsque vous envoyez des requêtes de prédiction en ligne à l'API REST sans utiliser l'outil gcloud
. La manière dont vous structurez votre modèle peut également modifier la manière dont vous devez formater les données pour la prédiction.
Reportez-vous à la section Mettre en forme les données pour les prédictions en ligne.
Envoyer la requête de prédiction en ligne
Procédez de la façon suivante pour envoyer votre requête de prédiction en ligne avec gcloud
:
gcloud ai-platform predict \
--model $MODEL_NAME \
--region $REGION \
--version $MODEL_VERSION \
--json-instances prediction_input.json
DENSE_4 [0.6854287385940552] [0.011786997318267822] [0.037236183881759644] [0.016223609447479248] [0.0012015104293823242] [0.23621389269828796] [0.6174039244651794] [0.9822691679000854] [0.3815768361091614] [0.6715215444564819] [0.001094043254852295] [0.43077391386032104] [0.22132840752601624] [0.004075437784194946] [0.22736871242523193] [0.4111979305744171] [0.27328649163246155] [0.6981356143951416] [0.3309604525566101] [0.20807647705078125]
Comme la dernière couche du modèle utilise une fonction sigmoïde pour son activation, les sorties comprises entre 0 et 0,5 représentent des prédictions négatives ("<=50 K"), et les sorties comprises entre 0,5 et 1 des prédictions positives ("> 50 K").
Développer entièrement le modèle Keras
À ce stade, vous avez entraîné un modèle de machine learning sur AI Platform, déployé le modèle entraîné en tant que ressource de version sur AI Platform et reçu les prédictions en ligne à partir du déploiement. Dans la section suivante, nous allons recréer le code Keras utilisé pour entraîner votre modèle. Pour cela, nous verrons comment développer un modèle de machine learning à utiliser avec AI Platform à l'aide des étapes suivantes :
- Télécharger et prétraiter les données
- Concevoir et entraîner le modèle
- Visualiser l'entraînement et exporter le modèle entraîné
Cette section fournit des informations plus détaillées sur les tâches accomplies dans les parties précédentes. Si vous souhaitez en savoir plus sur l'utilisation de tf.keras
, consultez le guide Keras de TensorFlow.
Pour savoir comment structurer le code en tant que package d'entraînement dans AI Platform, consultez la section Empaqueter une application d'entraînement et référencez l'intégralité du code d'entraînement en tant que package Python.
Importer des bibliothèques et définir des constantes
Commencez par importer les bibliothèques Python nécessaires à l'entraînement :
import os
from six.moves import urllib
import tempfile
import numpy as np
import pandas as pd
import tensorflow as tf
# Examine software versions
print(__import__('sys').version)
print(tf.__version__)
print(tf.keras.__version__)
Ensuite, définissez certaines constantes utiles :
- Informations de téléchargement des données d'entraînement et d'évaluation
- Informations requises par Pandas pour interpréter les données et convertir les champs catégoriels en caractéristiques numériques
- Hyperparamètres d'entraînement, tels que le taux d'apprentissage et la taille de lot
### For downloading data ###
# Storage directory
DATA_DIR = os.path.join(tempfile.gettempdir(), 'census_data')
# Download options.
DATA_URL = 'https://storage.googleapis.com/cloud-samples-data/ai-platform' \
'/census/data'
TRAINING_FILE = 'adult.data.csv'
EVAL_FILE = 'adult.test.csv'
TRAINING_URL = '%s/%s' % (DATA_URL, TRAINING_FILE)
EVAL_URL = '%s/%s' % (DATA_URL, EVAL_FILE)
### For interpreting data ###
# These are the features in the dataset.
# Dataset information: https://archive.ics.uci.edu/ml/datasets/census+income
_CSV_COLUMNS = [
'age', 'workclass', 'fnlwgt', 'education', 'education_num',
'marital_status', 'occupation', 'relationship', 'race', 'gender',
'capital_gain', 'capital_loss', 'hours_per_week', 'native_country',
'income_bracket'
]
_CATEGORICAL_TYPES = {
'workclass': pd.api.types.CategoricalDtype(categories=[
'Federal-gov', 'Local-gov', 'Never-worked', 'Private', 'Self-emp-inc',
'Self-emp-not-inc', 'State-gov', 'Without-pay'
]),
'marital_status': pd.api.types.CategoricalDtype(categories=[
'Divorced', 'Married-AF-spouse', 'Married-civ-spouse',
'Married-spouse-absent', 'Never-married', 'Separated', 'Widowed'
]),
'occupation': pd.api.types.CategoricalDtype([
'Adm-clerical', 'Armed-Forces', 'Craft-repair', 'Exec-managerial',
'Farming-fishing', 'Handlers-cleaners', 'Machine-op-inspct',
'Other-service', 'Priv-house-serv', 'Prof-specialty', 'Protective-serv',
'Sales', 'Tech-support', 'Transport-moving'
]),
'relationship': pd.api.types.CategoricalDtype(categories=[
'Husband', 'Not-in-family', 'Other-relative', 'Own-child', 'Unmarried',
'Wife'
]),
'race': pd.api.types.CategoricalDtype(categories=[
'Amer-Indian-Eskimo', 'Asian-Pac-Islander', 'Black', 'Other', 'White'
]),
'native_country': pd.api.types.CategoricalDtype(categories=[
'Cambodia', 'Canada', 'China', 'Columbia', 'Cuba', 'Dominican-Republic',
'Ecuador', 'El-Salvador', 'England', 'France', 'Germany', 'Greece',
'Guatemala', 'Haiti', 'Holand-Netherlands', 'Honduras', 'Hong', 'Hungary',
'India', 'Iran', 'Ireland', 'Italy', 'Jamaica', 'Japan', 'Laos', 'Mexico',
'Nicaragua', 'Outlying-US(Guam-USVI-etc)', 'Peru', 'Philippines', 'Poland',
'Portugal', 'Puerto-Rico', 'Scotland', 'South', 'Taiwan', 'Thailand',
'Trinadad&Tobago', 'United-States', 'Vietnam', 'Yugoslavia'
]),
'income_bracket': pd.api.types.CategoricalDtype(categories=[
'<=50K', '>50K'
])
}
# This is the label (target) we want to predict.
_LABEL_COLUMN = 'income_bracket'
### Hyperparameters for training ###
# This the training batch size
BATCH_SIZE = 128
# This is the number of epochs (passes over the full training data)
NUM_EPOCHS = 20
# Define learning rate.
LEARNING_RATE = .01
Télécharger et prétraiter les données
Télécharger les données
Ensuite, définissez les fonctions pour télécharger les données d'entraînement et d’évaluation. Ces fonctions corrigent également les anomalies mineures de formatage des données.
def _download_and_clean_file(filename, url):
"""Downloads data from url, and makes changes to match the CSV format.
The CSVs may use spaces after the comma delimters (non-standard) or include
rows which do not represent well-formed examples. This function strips out
some of these problems.
Args:
filename: filename to save url to
url: URL of resource to download
"""
temp_file, _ = urllib.request.urlretrieve(url)
with tf.gfile.Open(temp_file, 'r') as temp_file_object:
with tf.gfile.Open(filename, 'w') as file_object:
for line in temp_file_object:
line = line.strip()
line = line.replace(', ', ',')
if not line or ',' not in line:
continue
if line[-1] == '.':
line = line[:-1]
line += '\n'
file_object.write(line)
tf.gfile.Remove(temp_file)
def download(data_dir):
"""Downloads census data if it is not already present.
Args:
data_dir: directory where we will access/save the census data
"""
tf.gfile.MakeDirs(data_dir)
training_file_path = os.path.join(data_dir, TRAINING_FILE)
if not tf.gfile.Exists(training_file_path):
_download_and_clean_file(training_file_path, TRAINING_URL)
eval_file_path = os.path.join(data_dir, EVAL_FILE)
if not tf.gfile.Exists(eval_file_path):
_download_and_clean_file(eval_file_path, EVAL_URL)
return training_file_path, eval_file_path
Utilisez ces fonctions pour télécharger les données d'entraînement et vérifiez que vous disposez de fichiers CSV destinés à l'entraînement et à l'évaluation :
training_file_path, eval_file_path = download(DATA_DIR)
Ensuite, chargez ces fichiers à l'aide de Pandas et examinez les données :
# This census data uses the value '?' for fields (column) that are missing data.
# We use na_values to find ? and set it to NaN values.
# https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html
train_df = pd.read_csv(training_file_path, names=_CSV_COLUMNS, na_values='?')
eval_df = pd.read_csv(eval_file_path, names=_CSV_COLUMNS, na_values='?')
Le tableau suivant présente un extrait des données (train_df.head()
) avant le prétraitement :
age | workclass | fnlwgt | education | education_num | marital_status | occupation | relationship | race | gender | capital_gain | capital_loss | hours_per_week | native_country | income_bracket | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 39 | State-gov | 77516 | Bachelors | 13 | Never-married | Adm-clerical | Not-in-family | White | Male | 2174 | 0 | 40 | United-States | <=50K |
1 | 50 | Self-emp-not-inc | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
2 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
3 | 53 | Private | 234721 | 11e | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
4 | 28 | Private | 338409 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Wife | Black | Female | 0 | 0 | 40 | Cuba | <=50K |
Prétraiter les données
La première étape du prétraitement consiste à supprimer certaines caractéristiques des données et à convertir les caractéristiques catégorielles en valeurs numériques à utiliser avec Keras.
Pour en savoir plus, consultez la section portant sur l'ingénierie des caractéristiques et les biais dans les données.
UNUSED_COLUMNS = ['fnlwgt', 'education', 'gender']
def preprocess(dataframe):
"""Converts categorical features to numeric. Removes unused columns.
Args:
dataframe: Pandas dataframe with raw data
Returns:
Dataframe with preprocessed data
"""
dataframe = dataframe.drop(columns=UNUSED_COLUMNS)
# Convert integer valued (numeric) columns to floating point
numeric_columns = dataframe.select_dtypes(['int64']).columns
dataframe[numeric_columns] = dataframe[numeric_columns].astype('float32')
# Convert categorical columns to numeric
cat_columns = dataframe.select_dtypes(['object']).columns
dataframe[cat_columns] = dataframe[cat_columns].apply(lambda x: x.astype(
_CATEGORICAL_TYPES[x.name]))
dataframe[cat_columns] = dataframe[cat_columns].apply(lambda x: x.cat.codes)
return dataframe
prepped_train_df = preprocess(train_df)
prepped_eval_df = preprocess(eval_df)
Le tableau suivant (prepped_train_df.head()
) montre comment le prétraitement a modifié les données. Notez en particulier que income_bracket
, l'étiquette que vous entraînez le modèle à prédire, est passé de <=50K
et >50K
à 0
et 1
:
age | workclass | education_num | marital_status | occupation | relationship | race | capital_gain | capital_loss | hours_per_week | native_country | income_bracket | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 39.0 | 6 | 13.0 | 4 | 0 | 1 | 4 | 2174.0 | 0,0 | 40,0 | 38 | 0 |
1 | 50,0 | 5 | 13.0 | 2 | 3 | 0 | 4 | 0,0 | 0,0 | 13.0 | 38 | 0 |
2 | 38.0 | 3 | 9,0 | 0 | 5 | 1 | 4 | 0,0 | 0,0 | 40,0 | 38 | 0 |
3 | 53.0 | 3 | 7.0 | 2 | 5 | 0 | 2 | 0,0 | 0,0 | 40,0 | 38 | 0 |
4 | 28.0 | 3 | 13.0 | 2 | 9 | 5 | 2 | 0,0 | 0,0 | 40,0 | 4 | 0 |
Répartissez ensuite les données en caractéristiques ("x") et en étiquettes ("y"), puis remettez en forme les tableaux par étiquette dans un format à utiliser plus tard avec l'ensemble de données tf.data.Dataset
.
# Split train and test data with labels.
# The pop() method will extract (copy) and remove the label column from the dataframe
train_x, train_y = prepped_train_df, prepped_train_df.pop(_LABEL_COLUMN)
eval_x, eval_y = prepped_eval_df, prepped_eval_df.pop(_LABEL_COLUMN)
# Reshape label columns for use with tf.data.Dataset
train_y = np.asarray(train_y).astype('float32').reshape((-1, 1))
eval_y = np.asarray(eval_y).astype('float32').reshape((-1, 1))
Vous pouvez améliorer votre modèle en effectuant un scaling des données d'entraînement de sorte que chaque colonne de caractéristiques numériques représente une moyenne de 0 et un écart-type de 1.
Dans un système de production, il peut être utile d'enregistrer les moyennes et les écarts-types de l'ensemble d'entraînement, puis de les appliquer pour effectuer une transformation identique sur les données de test au moment de la prédiction. Pour faciliter cet exercice, associez temporairement les données d'entraînement et d’évaluation pour toutes les mettre à l’échelle :
def standardize(dataframe):
"""Scales numerical columns using their means and standard deviation to get
z-scores: the mean of each numerical column becomes 0, and the standard
deviation becomes 1. This can help the model converge during training.
Args:
dataframe: Pandas dataframe
Returns:
Input dataframe with the numerical columns scaled to z-scores
"""
dtypes = list(zip(dataframe.dtypes.index, map(str, dataframe.dtypes)))
# Normalize numeric columns.
for column, dtype in dtypes:
if dtype == 'float32':
dataframe[column] -= dataframe[column].mean()
dataframe[column] /= dataframe[column].std()
return dataframe
# Join train_x and eval_x to normalize on overall means and standard
# deviations. Then separate them again.
all_x = pd.concat([train_x, eval_x], keys=['train', 'eval'])
all_x = standardize(all_x)
train_x, eval_x = all_x.xs('train'), all_x.xs('eval')
Le tableau suivant (train_x.head()
) montre un exemple de données entièrement prétraitées :
age | workclass | education_num | marital_status | occupation | relationship | race | capital_gain | capital_loss | hours_per_week | native_country | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.025997 | 6 | 1.136580 | 4 | 0 | 1 | 4 | 0.146933 | -0.21713 | -0.034039 | 38 |
1 | 0.828278 | 5 | 1.136580 | 2 | 3 | 0 | 4 | -0.144792 | -0.21713 | -2.212964 | 38 |
2 | -0.046938 | 3 | -0.419265 | 0 | 5 | 1 | 4 | -0.144792 | -0.21713 | -0.034039 | 38 |
3 | 1.047082 | 3 | -1.197188 | 2 | 5 | 0 | 2 | -0.144792 | -0.21713 | -0.034039 | 38 |
4 | -0.776285 | 3 | 1.136580 | 2 | 9 | 5 | 2 | -0.144792 | -0.21713 | -0.034039 | 4 |
Concevoir et entraîner le modèle
Créez des ensembles de données d'entraînement et de validation
Créez une fonction d'entrée pour convertir les caractéristiques et les étiquettes en un ensemble de données tf.data.Dataset
pour l'entraînement ou l'évaluation.
def input_fn(features, labels, shuffle, num_epochs, batch_size):
"""Generates an input function to be used for model training.
Args:
features: numpy array of features used for training or inference
labels: numpy array of labels for each example
shuffle: boolean for whether to shuffle the data or not (set True for
training, False for evaluation)
num_epochs: number of epochs to provide the data for
batch_size: batch size for training
Returns:
A tf.data.Dataset that can provide data to the Keras model for training or
evaluation
"""
if labels is None:
inputs = features
else:
inputs = (features, labels)
dataset = tf.data.Dataset.from_tensor_slices(inputs)
if shuffle:
dataset = dataset.shuffle(buffer_size=len(features))
# We call repeat after shuffling, rather than before, to prevent separate
# epochs from blending together.
dataset = dataset.repeat(num_epochs)
dataset = dataset.batch(batch_size)
return dataset
Créez ensuite ces ensembles de données d'entraînement et d'évaluation. Utilisez les hyperparamètres NUM_EPOCHS
et BATCH_SIZE
définis précédemment pour définir la manière dont l'ensemble de données d'entraînement fournit des exemples au modèle pendant l'entraînement. Configurez l'ensemble de données de validation pour fournir tous ses exemples en un seul lot et en une seule étape de validation à la fin de chaque période d'entraînement.
# Pass a numpy array by using DataFrame.values
training_dataset = input_fn(features=train_x.values,
labels=train_y,
shuffle=True,
num_epochs=NUM_EPOCHS,
batch_size=BATCH_SIZE)
num_eval_examples = eval_x.shape[0]
# Pass a numpy array by using DataFrame.values
validation_dataset = input_fn(features=eval_x.values,
labels=eval_y,
shuffle=False,
num_epochs=NUM_EPOCHS,
batch_size=num_eval_examples)
Concevoir un modèle Keras
Concevez votre réseau de neurones à l’aide de l’API séquentielle Keras.
Ce réseau neuronal profond (DNN) possède plusieurs couches cachées. La dernière couche utilise une fonction d’activation sigmoïde pour générer une valeur comprise entre 0 et 1 :
- La couche d'entrée contient 100 unités utilisant la fonction d'activation ReLU.
- La couche cachée contient 75 unités utilisant la fonction d’activation ReLU.
- La couche cachée contient 50 unités utilisant la fonction d’activation ReLU.
- La couche cachée contient 25 unités utilisant la fonction d’activation ReLU.
- La couche de sortie contient 1 unité utilisant une fonction d’activation sigmoïde.
- L'optimiseur utilise la fonction binaire de perte d'entropie croisée, la méthode appropriée pour un problème de classification binaire tel que celui-ci.
N'hésitez pas à modifier ces couches pour améliorer le modèle :
def create_keras_model(input_dim, learning_rate):
"""Creates Keras Model for Binary Classification.
Args:
input_dim: How many features the input has
learning_rate: Learning rate for training
Returns:
The compiled Keras model (still needs to be trained)
"""
Dense = tf.keras.layers.Dense
model = tf.keras.Sequential(
[
Dense(100, activation=tf.nn.relu, kernel_initializer='uniform',
input_shape=(input_dim,)),
Dense(75, activation=tf.nn.relu),
Dense(50, activation=tf.nn.relu),
Dense(25, activation=tf.nn.relu),
Dense(1, activation=tf.nn.sigmoid)
])
# Custom Optimizer:
# https://www.tensorflow.org/api_docs/python/tf/train/RMSPropOptimizer
optimizer = tf.keras.optimizers.RMSprop(
lr=learning_rate)
# Compile Keras model
model.compile(
loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy'])
return model
Ensuite, créez l'objet de modèle Keras :
num_train_examples, input_dim = train_x.shape
print('Number of features: {}'.format(input_dim))
print('Number of examples: {}'.format(num_train_examples))
keras_model = create_keras_model(
input_dim=input_dim,
learning_rate=LEARNING_RATE)
L'examen du modèle à l'aide de keras_model.summary()
devrait se présenter comme ceci :
Number of features: 11 Number of examples: 32561 WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/resource_variable_ops.py:435: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version. Instructions for updating: Colocations handled automatically by placer. _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense (Dense) (None, 100) 1200 _________________________________________________________________ dense_1 (Dense) (None, 75) 7575 _________________________________________________________________ dense_2 (Dense) (None, 50) 3800 _________________________________________________________________ dense_3 (Dense) (None, 25) 1275 _________________________________________________________________ dense_4 (Dense) (None, 1) 26 ================================================================= Total params: 13,876 Trainable params: 13,876 Non-trainable params: 0 _________________________________________________________________
Entraîner et évaluer le modèle
Définissez une décroissance du taux d'apprentissage afin de forcer les paramètres du modèle à diminuer l'ampleur des modifications à mesure que l'entraînement progresse:
# Setup Learning Rate decay.
lr_decay_cb = tf.keras.callbacks.LearningRateScheduler(
lambda epoch: LEARNING_RATE + 0.02 * (0.5 ** (1 + epoch)),
verbose=True)
# Setup TensorBoard callback.
JOB_DIR = os.getenv('JOB_DIR')
tensorboard_cb = tf.keras.callbacks.TensorBoard(
os.path.join(JOB_DIR, 'keras_tensorboard'),
histogram_freq=1)
Enfin, entraînez le modèle. Indiquez les séquences steps_per_epoch
appropriées pour que le modèle puisse s'entraîner sur la totalité de l'ensemble de données d'entraînement (avec des exemples BATCH_SIZE
par étape) à chaque époque. Indiquez également au modèle de calculer la précision de validation avec un seul lot de validation à la fin de chaque époque.
history = keras_model.fit(training_dataset,
epochs=NUM_EPOCHS,
steps_per_epoch=int(num_train_examples/BATCH_SIZE),
validation_data=validation_dataset,
validation_steps=1,
callbacks=[lr_decay_cb, tensorboard_cb],
verbose=1)
La progression de l'entraînement devrait se présenter comme ceci :
WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version. Instructions for updating: Use tf.cast instead. Epoch 00001: LearningRateScheduler reducing learning rate to 0.02. Epoch 1/20 254/254 [==============================] - 1s 5ms/step - loss: 0.6986 - acc: 0.7893 - val_loss: 0.3894 - val_acc: 0.8329 Epoch 00002: LearningRateScheduler reducing learning rate to 0.015. Epoch 2/20 254/254 [==============================] - 1s 4ms/step - loss: 0.3574 - acc: 0.8335 - val_loss: 0.3861 - val_acc: 0.8131 ... Epoch 00019: LearningRateScheduler reducing learning rate to 0.010000038146972657. Epoch 19/20 254/254 [==============================] - 1s 4ms/step - loss: 0.3239 - acc: 0.8512 - val_loss: 0.3334 - val_acc: 0.8496 Epoch 00020: LearningRateScheduler reducing learning rate to 0.010000019073486329. Epoch 20/20 254/254 [==============================] - 1s 4ms/step - loss: 0.3279 - acc: 0.8504 - val_loss: 0.3174 - val_acc: 0.8523
Visualiser l'entraînement et exporter le modèle entraîné
Visualiser l'entraînement
Importez la bibliothèque matplotlib
pour visualiser la manière dont le modèle a fait son apprentissage au cours de la période d'entraînement.
(Si nécessaire, procédez d'abord à son installation avec pip install matplotlib
).
from matplotlib import pyplot as plt
Tracez la perte du modèle (entropie croisée binaire) et la précision mesurée à la fin de chaque époque d'entraînement :
# Visualize History for Loss.
plt.title('Keras model loss')
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['training', 'validation'], loc='upper right')
plt.show()
# Visualize History for Accuracy.
plt.title('Keras model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.legend(['training', 'validation'], loc='lower right')
plt.show()
Au fil du temps, la perte diminue et la précision augmente. Mais ces tendances s'acheminent-elles vers un niveau stable de convergence ? Les métriques d'entraînement et de validation présentent-elles de fortes différences (signe de surapprentissage) ?
Découvrez comment améliorer votre modèle de machine learning. Ensuite, n'hésitez pas à ajuster les hyperparamètres ou l'architecture du modèle et poursuivez l'entraînement.
Exporter le modèle pour la diffusion
Utilisez tf.contrib.saved_model.save_keras_model pour exporter un répertoire TensorFlow SavedModel. C'est le format requis par AI Platform lorsque vous créez une ressource de version de modèle.
Dans la mesure où tous les optimiseurs ne peuvent pas être exportés au format SavedModel, des avertissements peuvent apparaître pendant le processus d'exportation. Mais, du moment que vous parvenez à exporter un graphique de diffusion, le modèle SavedModel pourra être utilisé par AI Platform pour les prédictions.
# Export the model to a local SavedModel directory
export_path = tf.contrib.saved_model.save_keras_model(keras_model, 'keras_export')
print("Model exported to: ", export_path)
WARNING: The TensorFlow contrib module will not be included in TensorFlow 2.0. For more information, please see: * https://github.com/tensorflow/community/blob/master/rfcs/20180907-contrib-sunset.md * https://github.com/tensorflow/addons If you depend on functionality not listed there, please file an issue. WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.RMSprop object at 0x7fc198c4e400>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved. Consider using a TensorFlow optimizer from `tf.train`. WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/network.py:1436: update_checkpoint_state (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version. Instructions for updating: Use tf.train.CheckpointManager to manage checkpoints rather than manually editing the Checkpoint proto. WARNING:tensorflow:Model was compiled with an optimizer, but the optimizer is not from `tf.train` (e.g. `tf.train.AdagradOptimizer`). Only the serving graph was exported. The train and evaluate graphs were not added to the SavedModel. WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/saved_model/signature_def_utils_impl.py:205: build_tensor_info (from tensorflow.python.saved_model.utils_impl) is deprecated and will be removed in a future version. Instructions for updating: This function will only be available through the v1 compatibility library as tf.compat.v1.saved_model.utils.build_tensor_info or tf.compat.v1.saved_model.build_tensor_info. INFO:tensorflow:Signatures INCLUDED in export for Classify: None INFO:tensorflow:Signatures INCLUDED in export for Regress: None INFO:tensorflow:Signatures INCLUDED in export for Predict: ['serving_default'] INFO:tensorflow:Signatures INCLUDED in export for Train: None INFO:tensorflow:Signatures INCLUDED in export for Eval: None INFO:tensorflow:No assets to save. INFO:tensorflow:No assets to write. INFO:tensorflow:SavedModel written to: keras_export/1553710367/saved_model.pb Model exported to: b'keras_export/1553710367'
Vous pouvez exporter un répertoire SavedModel vers votre système de fichiers local ou vers Cloud Storage, à condition de disposer des autorisations nécessaires. Dans votre environnement actuel, vous avez accordé l'accès à Cloud Storage en authentifiant votre compte Google Cloud et en définissant la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS
. Les tâches d'entraînement AI Platform permettent également d'exporter directement vers Cloud Storage, car les comptes de service AI Platform ont accès aux buckets Cloud Storage dans leur propre projet.
Essayez d’exporter directement vers Cloud Storage :
JOB_DIR = os.getenv('JOB_DIR')
# Export the model to a SavedModel directory in Cloud Storage
export_path = tf.contrib.saved_model.save_keras_model(keras_model, JOB_DIR + '/keras_export')
print("Model exported to: ", export_path)
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.RMSprop object at 0x7fc198c4e400>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved. Consider using a TensorFlow optimizer from `tf.train`. WARNING:tensorflow:Model was compiled with an optimizer, but the optimizer is not from `tf.train` (e.g. `tf.train.AdagradOptimizer`). Only the serving graph was exported. The train and evaluate graphs were not added to the SavedModel. INFO:tensorflow:Signatures INCLUDED in export for Classify: None INFO:tensorflow:Signatures INCLUDED in export for Regress: None INFO:tensorflow:Signatures INCLUDED in export for Predict: ['serving_default'] INFO:tensorflow:Signatures INCLUDED in export for Train: None INFO:tensorflow:Signatures INCLUDED in export for Eval: None INFO:tensorflow:No assets to save. INFO:tensorflow:No assets to write. INFO:tensorflow:SavedModel written to: gs://your-bucket-name/keras-job-dir/keras_export/1553710379/saved_model.pb Model exported to: b'gs://your-bucket-name/keras-job-dir/keras_export/1553710379'
Vous pouvez maintenant déployer ce modèle sur AI Platform et diffuser les prédictions en suivant la procédure du démarrage rapide pour effectuer des prédictions.
Nettoyer
Pour nettoyer toutes les ressources Google Cloud utilisées dans ce projet, vous pouvez supprimer le projet Google Cloud que vous avez utilisé dans le cadre de ce tutoriel.
Vous pouvez également nettoyer des ressources individuelles en exécutant les commandes suivantes :
# Delete model version resource
gcloud ai-platform versions delete $MODEL_VERSION --quiet --model $MODEL_NAME
# Delete model resource
gcloud ai-platform models delete $MODEL_NAME --quiet
# Delete Cloud Storage objects that were created
gsutil -m rm -r $JOB_DIR
# If training job is still running, cancel it
gcloud ai-platform jobs cancel $JOB_NAME --quiet
Si votre bucket Cloud Storage ne contient aucun autre objet et que vous souhaitez le supprimer, exécutez la commande gsutil rm -r gs://$BUCKET_NAME
.
Étape suivante
- Affichez le code d'entraînement complet utilisé dans ce guide, qui fournit la structure nécessaire pour accepter les hyperparamètres personnalisés en tant qu'indicateurs de ligne de commande.
- Découvrez-en plus sur le code de packaging d'une tâche d'entraînement sur AI Platform.
- Découvrez comment déployer un modèle pour diffuser des prédictions.