Tutoriel de régression linéaire avec TensorFlow [Exemples]
Qu'est-ce que la régression linéaire?
Régression Linéaire est une approche en statistique pour modéliser les relations entre deux variables. Cette modélisation se fait entre une réponse scalaire et une ou plusieurs variables explicatives. La relation avec une variable explicative est appelée régression linéaire simple et pour plusieurs variables explicatives, elle est appelée régression linéaire multiple.
TensorFlow fournit des outils pour avoir un contrôle total sur les calculs. Cela se fait avec l'API de bas niveau. De plus, TensorFlow est équipé d'une vaste gamme d'API pour effectuer de nombreuses machine learning algorithmes. Il s'agit de l'API de haut niveau. TensorFlow les appelle des estimateurs
- API de bas niveau: Construire l'architecture, optimiser le modèle à partir de zéro. C'est compliqué pour un débutant
- API de haut niveau: Définir l'algorithme. C’est plus convivial. TensorFlow fournit une boîte à outils appelée estimateur construire, former, évaluer et faire une prédiction.
Dans ce tutoriel, vous utiliserez le estimateurs seulement. Les calculs sont plus rapides et plus faciles à mettre en œuvre. La première partie du didacticiel explique comment utiliser l'optimiseur de descente de gradient pour entraîner une régression linéaire dans TensorFlow. Dans une deuxième partie, vous utiliserez l'ensemble de données de Boston pour prédire le prix d'une maison à l'aide de l'estimateur TensorFlow.
Télécharger le jeu de données de Boston
Comment entraîner un modèle de régression linéaire
Avant de commencer à entraîner le modèle, voyons ce qu'est une régression linéaire.
Imaginez que vous ayez deux variables, x et y, et que votre tâche consiste à prédire la valeur de la connaissance de la valeur de . Si vous tracez les données, vous pouvez voir une relation positive entre votre variable indépendante x et votre variable dépendante y.
Vous observerez peut-être que si x=1,y sera à peu près égal à 6 et si x=2,y sera d'environ 8.5.
Ce n'est pas une méthode très précise et sujette aux erreurs, en particulier avec un ensemble de données comportant des centaines de milliers de points.
Une régression linéaire est évaluée avec une équation. La variable y s'explique par une ou plusieurs covariables. Dans votre exemple, il n'y a qu'une seule variable dépendante. Si vous devez écrire cette équation, ce sera :
Avec:
est le biais. c'est à dire si x=0, y=
est le poids associé à x
est le résidu ou l'erreur du modèle. Il inclut ce que le modèle ne peut pas apprendre des données
Imaginez que vous adaptez le modèle et que vous trouvez la solution suivante pour :
= 3.8
= 2.78
Vous pouvez remplacer ces nombres dans l’équation et cela devient :
y= 3.8 + 2.78x
Vous disposez désormais d’un meilleur moyen de trouver les valeurs de y. Autrement dit, vous pouvez remplacer x par n’importe quelle valeur pour laquelle vous souhaitez prédire y. Dans l'image ci-dessous, nous avons remplacé x dans l'équation par toutes les valeurs de l'ensemble de données et tracé le résultat.
La ligne rouge représente la valeur ajustée, c'est-à-dire les valeurs de y pour chaque valeur de x. Vous n'avez pas besoin de voir la valeur de x pour prédire y, pour chaque x il y en a un qui appartient à la ligne rouge. Vous pouvez également prédire des valeurs de x supérieures à 2 !
Si vous souhaitez étendre la régression linéaire à davantage de covariables, vous pouvez le faire en ajoutant plus de variables au modèle. La différence entre l'analyse traditionnelle et la régression linéaire est que la régression linéaire examine comment y réagira pour chaque variable x prise indépendamment.
Voyons un exemple. Imaginez que vous souhaitiez prédire les ventes d’un glacier. L'ensemble de données contient différentes informations telles que la météo (c'est-à-dire pluvieux, ensoleillé, nuageux), des informations sur les clients (c'est-à-dire le salaire, le sexe, l'état civil).
L'analyse traditionnelle tentera de prédire la vente en calculant, disons, la moyenne de chaque variable et tentera d'estimer la vente pour différents scénarios. Cela conduira à de mauvaises prévisions et limitera l’analyse au scénario choisi.
Si vous utilisez la régression linéaire, vous pouvez écrire cette équation :
L'algorithme trouvera la meilleure solution pour les poids ; cela signifie qu'il essaiera de minimiser le coût (la différence entre la ligne ajustée et les points de données).
Comment fonctionne l'algorithme
L'algorithme choisira un nombre aléatoire pour chacun et mes
et remplacez la valeur de x pour obtenir la valeur prédite de y. Si l'ensemble de données contient 100 observations, l'algorithme calcule 100 valeurs prédites.
Nous pouvons calculer l'erreur, notée du modèle, qui est la différence entre la valeur prédite et la valeur réelle. Une erreur positive signifie que le modèle sous-estime la prédiction de y, et une erreur négative signifie que le modèle surestime la prédiction de y.
Votre objectif est de minimiser le carré de l’erreur. L'algorithme calcule la moyenne de l'erreur quadratique. Cette étape est appelée minimisation de l’erreur. Pour la régression linéaire, est le Erreur quadratique moyenne, également appelé MSE. Mathématiquement, c'est :
Où? :
est-ce que les poids sont comme ça
fait référence à la valeur prédite
- y est les vraies valeurs
- m est le nombre d'observations
Notez que signifie qu'il utilise la transposition des matrices. Le
est la notation mathématique de la moyenne.
Le but est de trouver le meilleur qui minimisent le MSE
Si l’erreur moyenne est importante, cela signifie que le modèle fonctionne mal et que les poids ne sont pas choisis correctement. Pour corriger les poids, vous devez utiliser un optimiseur. L'optimiseur traditionnel s'appelle Descente graduelle.
La descente de pente prend la dérivée et diminue ou augmente le poids. Si la dérivée est positive, le poids est diminué. Si la dérivée est négative, le poids augmente. Le modèle mettra à jour les poids et recalculera l'erreur. Ce processus est répété jusqu'à ce que l'erreur ne change plus. Chaque processus est appelé un itération. De plus, les gradients sont multipliés par un taux d'apprentissage. Il indique la vitesse de l’apprentissage.
Si le taux d'apprentissage est trop faible, la convergence de l'algorithme prendra très longtemps (c'est-à-dire qu'elle nécessitera de nombreuses itérations). Si le taux d’apprentissage est trop élevé, l’algorithme risque de ne jamais converger.
Vous pouvez voir sur l'image ci-dessus que le modèle répète le processus environ 20 fois avant de trouver une valeur stable pour les poids, atteignant ainsi l'erreur la plus faible.
Notez que, l'erreur n'est pas égale à zéro mais se stabilise autour de 5. Cela signifie que le modèle fait une erreur typique de 5. Si vous souhaitez réduire l'erreur, vous devez ajouter plus d'informations au modèle, comme plus de variables ou utiliser différents estimateurs. .
Tu te souviens de la première équation
Les poids finaux sont 3.8 et 2.78. La vidéo ci-dessous vous montre comment la descente de gradient optimise la fonction de perte pour trouver ces poids
Comment entraîner une régression linéaire avec TensorFlow
Maintenant que vous comprenez mieux ce qui se passe derrière le capot, vous êtes prêt à utiliser l'API d'estimateur fournie par TensorFlow pour entraîner votre première régression linéaire à l'aide de TensorFlow.
Vous utiliserez le Boston Dataset, qui comprend les variables suivantes
crime | taux de criminalité par habitant par ville |
---|---|
zn | proportion de terrains résidentiels zonés pour des lots de plus de 25,000 pieds carrés. |
indus | proportion de superficies commerciales non commerciales par ville. |
nox | concentration d'oxyde nitrique |
rm | nombre moyen de pièces par logement |
âge | proportion de logements occupés par leur propriétaire construits avant 1940 |
DIS | distances pondérées jusqu'à cinq centres d'emploi de Boston |
impôt | taux de taxe foncière pleine valeur par dollar 10,000 |
ptratio | ratio élèves/enseignant par ville |
avec V | Valeur médiane des maisons occupées par leur propriétaire en milliers de dollars |
Vous allez créer trois ensembles de données différents :
jeu de données | objectif | forme |
---|---|---|
Formation | Entraîner le modèle et obtenir les poids | 400, 10 |
Évaluation | Évaluer les performances du modèle sur des données invisibles | 100, 10 |
Prédire | Utilisez le modèle pour prédire la valeur d'une maison à partir de nouvelles données | 6, 10 |
L'objectif est d'utiliser les caractéristiques de l'ensemble de données pour prédire la valeur de la maison.
Au cours de la deuxième partie du didacticiel, vous apprendrez à utiliser TensorFlow avec trois manières différentes d'importer les données :
- Avec des pandas
- Avec Numpy
- Seulement TF
Notez que toutes les options fournissent les mêmes résultats.
Vous apprendrez à utiliser l'API de haut niveau pour créer, entraîner et évaluer un modèle de régression linéaire TensorFlow. Si vous utilisiez l'API de bas niveau, vous deviez définir manuellement :
- Fonction de perte
- Optimiser : descente de gradient
- Multiplication des matrices
- Graphique et tenseur
C'est fastidieux et plus compliqué pour un débutant.
Pandas
Vous devez importer les bibliothèques nécessaires pour entraîner le modèle.
import pandas as pd from sklearn import datasets import tensorflow as tf import itertools
Étape 1) Importez les données avec Panda.
Vous définissez les noms de colonnes et les stockez dans COLUMNS. Vous pouvez utiliser pd.read_csv() pour importer les données.
COLUMNS = ["crim", "zn", "indus", "nox", "rm", "age", "dis", "tax", "ptratio", "medv"]
training_set = pd.read_csv("E:/boston_train.csv", skipinitialspace=True,skiprows=1, noms=COLUMNS)
test_set = pd.read_csv("E:/boston_test.csv", skipinitialspace=True,skiprows=1, noms=COLUMNS)
prédiction_set = pd.read_csv("E:/boston_predict.csv", skipinitialspace=True,skiprows=1, noms=COLUMNS)
Vous pouvez imprimer la forme des données.
print(training_set.shape, test_set.shape, prediction_set.shape)
Sortie
(400, 10) (100, 10) (6, 10)
Notez que l'étiquette, c'est-à-dire votre y, est incluse dans l'ensemble de données. Vous devez donc définir deux autres listes. Un contenant uniquement les fonctionnalités et un avec le nom du label uniquement. Ces deux listes indiqueront à votre estimateur quelles sont les caractéristiques de l'ensemble de données et quel nom de colonne correspond à l'étiquette.
Cela se fait avec le code ci-dessous.
FEATURES = ["crim", "zn", "indus", "nox", "rm", "age", "dis", "tax", "ptratio"] LABEL = "medv"
Étape 2) Convertir les données
Vous devez convertir les variables numériques au format approprié. Tensorflow fournit une méthode pour convertir une variable continue : tf.feature_column.numeric_column().
À l'étape précédente, vous définissez une liste des fonctionnalités que vous souhaitez inclure dans le modèle. Vous pouvez maintenant utiliser cette liste pour les convertir en données numériques. Si vous souhaitez exclure des fonctionnalités de votre modèle, n'hésitez pas à déposer une ou plusieurs variables dans la liste FEATURES avant de construire le feature_cols.
Notez que vous utiliserez Python compréhension de la liste avec la liste FEATURES pour créer une nouvelle liste nommée feature_cols. Cela vous aide à éviter d'écrire neuf fois tf.feature_column.numeric_column(). La compréhension de liste est un moyen plus rapide et plus propre de créer de nouvelles listes
feature_cols = [tf.feature_column.numeric_column(k) for k in FEATURES]
Étape 3) Définir l'estimateur
Dans cette étape, vous devez définir l'estimateur. Tensorflow fournit actuellement 6 estimateurs prédéfinis, dont 3 pour la tâche de classification et 3 pour la tâche de régression TensorFlow :
- Régresseur
- DNNRégresseur
- Régresseur Linéaire
- DNNLineaCombinedRegressor
- Classificateur
- Classificateur DNN
- Classificateur linéaire
- DNNLineaCombinedClassifier
Dans ce didacticiel, vous utiliserez le régresseur linéaire. Pour accéder à cette fonction, vous devez utiliser tf.estimator.
La fonction a besoin de deux arguments :
- feature_columns : Contient les variables à inclure dans le modèle
- model_dir : chemin pour stocker le graphique, sauvegarder les paramètres du modèle, etc.
Tensorflow créera automatiquement un fichier nommé train dans votre répertoire de travail. Vous devez utiliser ce chemin pour accéder au Tensorboard, comme indiqué dans l'exemple de régression TensorFlow ci-dessous.
estimator = tf.estimator.LinearRegressor( feature_columns=feature_cols, model_dir="train")
Sortie
INFO:tensorflow:Using default config. INFO:tensorflow:Using config: {'_model_dir': 'train', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1a215dc550>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
La partie délicate avec TensorFlow est la manière d'alimenter le modèle. Tensorflow est conçu pour fonctionner avec du calcul parallèle et un très grand ensemble de données. En raison des ressources limitées de la machine, il est impossible d’alimenter le modèle avec toutes les données d’un coup. Pour cela, vous devez alimenter un lot de données à chaque fois. Notez que nous parlons d’un énorme ensemble de données contenant des millions d’enregistrements ou plus. Si vous n'ajoutez pas de lot, vous vous retrouverez avec une erreur de mémoire.
Par exemple, si vos données contiennent 100 observations et que vous définissez une taille de lot de 10, cela signifie que le modèle verra 10 observations pour chaque itération (10*10).
Lorsque le modèle a vu toutes les données, il en termine une époque. Une époque définit combien de fois vous souhaitez que le modèle voie les données. Il est préférable de définir cette étape sur aucune et de laisser le modèle effectuer un certain nombre d'itérations.
Une deuxième information à ajouter est si vous souhaitez mélanger les données avant chaque itération. Pendant la formation, il est important de mélanger les données afin que le modèle n'apprenne pas de modèle spécifique de l'ensemble de données. Si le modèle apprend les détails du modèle sous-jacent des données, il aura des difficultés à généraliser la prédiction pour les données invisibles. C'est appelé surajustement. Le modèle fonctionne bien sur les données d'entraînement mais ne peut pas prédire correctement les données invisibles.
TensorFlow facilite la réalisation de ces deux étapes. Lorsque les données sont acheminées vers le pipeline, il sait de combien d'observations il a besoin (lot) et s'il doit mélanger les données.
Pour indiquer à Tensorflow comment alimenter le modèle, vous pouvez utiliser pandas_input_fn. Cet objet a besoin de 5 paramètres :
- x : données sur les fonctionnalités
- y : données d'étiquette
- batch_size : lot. Par défaut 128
- num_epoch : numéro d'époque, par défaut 1
- shuffle : Mélange ou non les données. Par défaut, Aucun
Vous devez alimenter le modèle plusieurs fois afin de définir une fonction pour répéter ce processus. toute cette fonction get_input_fn.
def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True): return tf.estimator.inputs.pandas_input_fn( x=pd.DataFrame({k: data_set[k].values for k in FEATURES}), y = pd.Series(data_set[LABEL].values), batch_size=n_batch, num_epochs=num_epochs, shuffle=shuffle)
La méthode habituelle pour évaluer les performances d’un modèle consiste à :
- Former le modèle
- Évaluer le modèle dans un autre ensemble de données
- Faire des prédictions
L'estimateur Tensorflow fournit trois fonctions différentes pour effectuer facilement ces trois étapes.
Étape 4): Entraîner le modèle
Vous pouvez utiliser le train d’estimateurs pour évaluer le modèle. L'estimateur de train a besoin d'un input_fn et d'un certain nombre d'étapes. Vous pouvez utiliser la fonction que vous avez créée ci-dessus pour alimenter le modèle. Ensuite, vous demandez au modèle d’itérer 1000 1000 fois. Notez que vous ne spécifiez pas le nombre d'époques, vous laissez le modèle itérer 1 4 fois. Si vous définissez le nombre d'époques sur 400, le modèle itérera 128 fois : il y a enregistrements dans l'ensemble d'apprentissage et la taille du lot est de .
- 128 lignes
- 128 lignes
- 128 lignes
- 16 lignes
Par conséquent, il est plus facile de définir le nombre d'époques sur aucun et de définir le nombre d'itérations comme indiqué dans l'exemple de classification TensorFlow ci-dessous.
estimator.train(input_fn=get_input_fn(training_set, num_epochs=None, n_batch = 128, shuffle=False), steps=1000)
Sortie
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Create CheckpointSaverHook. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Saving checkpoints for 1 into train/model.ckpt. INFO:tensorflow:loss = 83729.64, step = 1 INFO:tensorflow:global_step/sec: 238.616 INFO:tensorflow:loss = 13909.657, step = 101 (0.420 sec) INFO:tensorflow:global_step/sec: 314.293 INFO:tensorflow:loss = 12881.449, step = 201 (0.320 sec) INFO:tensorflow:global_step/sec: 303.863 INFO:tensorflow:loss = 12391.541, step = 301 (0.327 sec) INFO:tensorflow:global_step/sec: 308.782 INFO:tensorflow:loss = 12050.5625, step = 401 (0.326 sec) INFO:tensorflow:global_step/sec: 244.969 INFO:tensorflow:loss = 11766.134, step = 501 (0.407 sec) INFO:tensorflow:global_step/sec: 155.966 INFO:tensorflow:loss = 11509.922, step = 601 (0.641 sec) INFO:tensorflow:global_step/sec: 263.256 INFO:tensorflow:loss = 11272.889, step = 701 (0.379 sec) INFO:tensorflow:global_step/sec: 254.112 INFO:tensorflow:loss = 11051.9795, step = 801 (0.396 sec) INFO:tensorflow:global_step/sec: 292.405 INFO:tensorflow:loss = 10845.855, step = 901 (0.341 sec) INFO:tensorflow:Saving checkpoints for 1000 into train/model.ckpt. INFO:tensorflow:Loss for final step: 5925.9873.
Vous pouvez vérifier le Tensorboard avec la commande suivante :
activate hello-tf # For MacOS tensorboard --logdir=./train # For Windows tensorboard --logdir=train
Étape 5) Évaluez votre modèle
Vous pouvez évaluer l'ajustement de votre modèle sur l'ensemble de test avec le code ci-dessous :
ev = estimator.evaluate( input_fn=get_input_fn(test_set, num_epochs=1, n_batch = 128, shuffle=False))
Sortie
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Starting evaluation at 2018-05-13-01:43:13 INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train/model.ckpt-1000 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Finished evaluation at 2018-05-13-01:43:13 INFO:tensorflow:Saving dict for global step 1000: average_loss = 32.15896, global_step = 1000, loss = 3215.896
Vous pouvez imprimer la perte avec le code ci-dessous :
loss_score = ev["loss"] print("Loss: {0:f}".format(loss_score))
Sortie
Loss: 3215.895996
Le modèle a une perte de 3215 . Vous pouvez consulter les statistiques récapitulatives pour avoir une idée de l’ampleur de l’erreur.
training_set['medv'].describe()
Sortie
count 400.000000 mean 22.625500 std 9.572593 min 5.000000 25% 16.600000 50% 21.400000 75% 25.025000 max 50.000000 Name: medv, dtype: float64
D'après les statistiques récapitulatives ci-dessus, vous savez que le prix moyen d'une maison est de 22 9, avec un prix minimum de 50 3 et maximum de . Le modèle commet une erreur typique de dollars.
Étape 6) Faites la prédiction
Enfin, vous pouvez utiliser l'estimateur TensorFlow Predict pour estimer la valeur de 6 maisons de Boston.
y = estimator.predict( input_fn=get_input_fn(prediction_set, num_epochs=1, n_batch = 128, shuffle=False))
Pour imprimer les valeurs estimées de , vous pouvez utiliser ce code :
predictions = list(p["predictions"] for p in itertools.islice(y, 6))print("Predictions: {}".format(str(predictions)))
Sortie
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train/model.ckpt-1000 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. Predictions: [array([32.297546], dtype=float32), array([18.96125], dtype=float32), array([27.270979], dtype=float32), array([29.299236], dtype=float32), array([16.436684], dtype=float32), array([21.460876], dtype=float32)]
Le modèle prévoit les valeurs suivantes :
Maison | Prédiction | |
---|---|---|
1 | 32.29 | |
2 | 18.96 | |
3 | 27.27 | |
4 | 29.29 | |
5 | 16.43 | |
7 | 21.46 |
Notez que nous ne connaissons pas la vraie valeur de . Dans le tutoriel de deep learning, vous allez essayer de battre le modèle linéaire
Solution numpy
Cette section explique comment entraîner le modèle à l'aide d'un estimateur numpy pour alimenter les données. La méthode est la même sauf que vous utiliserez l'estimateur numpy_input_fn.
training_set_n = pd.read_csv("E:/boston_train.csv").values
test_set_n = pd.read_csv("E:/boston_test.csv").values
prédiction_set_n = pd.read_csv("E:/boston_predict.csv").values
Étape 1) Importez les données
Tout d'abord, vous devez différencier les variables de fonctionnalité de l'étiquette. Vous devez le faire pour les données de formation et l’évaluation. Il est plus rapide de définir une fonction pour diviser les données.
def prepare_data(df): X_train = df[:, :-3] y_train = df[:,-3] return X_train, y_train
Vous pouvez utiliser la fonction pour diviser l'étiquette des caractéristiques de l'ensemble de données d'entraînement/évaluation
X_train, y_train = prepare_data(training_set_n) X_test, y_test = prepare_data(test_set_n)
Vous devez exclure la dernière colonne de l'ensemble de données de prédiction, car elle ne contient que NaN
x_predict = prediction_set_n[:, :-2]
Confirmez la forme du tableau. Notez que l'étiquette ne doit pas avoir de dimension, cela signifie (400,).
print(X_train.shape, y_train.shape, x_predict.shape)
Sortie
(400, 9) (400,) (6, 9)
Vous pouvez construire les colonnes de fonctionnalités comme suit :
feature_columns = [ tf.feature_column.numeric_column('x', shape=X_train.shape[1:])]
L'estimateur est défini comme précédemment, vous indiquez les colonnes de caractéristiques et où enregistrer le graphique.
estimator = tf.estimator.LinearRegressor( feature_columns=feature_columns, model_dir="train1")
Sortie
INFO:tensorflow:Using default config. INFO:tensorflow:Using config: {'_model_dir': 'train1', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1a218d8f28>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
Vous pouvez utiliser l'estimation numpy pour transmettre les données au modèle, puis entraîner le modèle. Notez que nous définissons la fonction input_fn avant pour faciliter la lisibilité.
# Train the estimatortrain_input = tf.estimator.inputs.numpy_input_fn( x={"x": X_train}, y=y_train, batch_size=128, shuffle=False, num_epochs=None) estimator.train(input_fn = train_input,steps=5000)
Sortie
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Create CheckpointSaverHook. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Saving checkpoints for 1 into train1/model.ckpt. INFO:tensorflow:loss = 83729.64, step = 1 INFO:tensorflow:global_step/sec: 490.057 INFO:tensorflow:loss = 13909.656, step = 101 (0.206 sec) INFO:tensorflow:global_step/sec: 788.986 INFO:tensorflow:loss = 12881.45, step = 201 (0.126 sec) INFO:tensorflow:global_step/sec: 736.339 INFO:tensorflow:loss = 12391.541, step = 301 (0.136 sec) INFO:tensorflow:global_step/sec: 383.305 INFO:tensorflow:loss = 12050.561, step = 401 (0.260 sec) INFO:tensorflow:global_step/sec: 859.832 INFO:tensorflow:loss = 11766.133, step = 501 (0.117 sec) INFO:tensorflow:global_step/sec: 804.394 INFO:tensorflow:loss = 11509.918, step = 601 (0.125 sec) INFO:tensorflow:global_step/sec: 753.059 INFO:tensorflow:loss = 11272.891, step = 701 (0.134 sec) INFO:tensorflow:global_step/sec: 402.165 INFO:tensorflow:loss = 11051.979, step = 801 (0.248 sec) INFO:tensorflow:global_step/sec: 344.022 INFO:tensorflow:loss = 10845.854, step = 901 (0.288 sec) INFO:tensorflow:Saving checkpoints for 1000 into train1/model.ckpt. INFO:tensorflow:Loss for final step: 5925.985. Out[23]: <tensorflow.python.estimator.canned.linear.LinearRegressor at 0x1a1b6ea860>
Vous reproduisez la même étape avec un estimateur différent pour évaluer votre modèle
eval_input = tf.estimator.inputs.numpy_input_fn( x={"x": X_test}, y=y_test, shuffle=False, batch_size=128, num_epochs=1) estimator.evaluate(eval_input,steps=None)
Sortie
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Starting evaluation at 2018-05-13-01:44:00 INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train1/model.ckpt-1000 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Finished evaluation at 2018-05-13-01:44:00 INFO:tensorflow:Saving dict for global step 1000: average_loss = 32.158947, global_step = 1000, loss = 3215.8945 Out[24]: {'average_loss': 32.158947, 'global_step': 1000, 'loss': 3215.8945}
Enfin, vous pouvez calculer la prédiction. Cela devrait être pareil aux pandas.
test_input = tf.estimator.inputs.numpy_input_fn( x={"x": x_predict}, batch_size=128, num_epochs=1, shuffle=False) y = estimator.predict(test_input) predictions = list(p["predictions"] for p in itertools.islice(y, 6)) print("Predictions: {}".format(str(predictions)))
Sortie
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train1/model.ckpt-1000 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. Predictions: [array([32.297546], dtype=float32), array([18.961248], dtype=float32), array([27.270979], dtype=float32), array([29.299242], dtype=float32), array([16.43668], dtype=float32), array([21.460878], dtype=float32)]
Solution Tensorflow
La dernière section est dédiée à une solution TensorFlow. Cette méthode est légèrement plus compliquée que l’autre.
Notez que si vous utilisez Jupyter cahier, vous devez redémarrer et nettoyer le noyau pour exécuter cette session.
TensorFlow a construit un excellent outil pour transmettre les données dans le pipeline. Dans cette section, vous construirez vous-même la fonction input_fn.
Étape 1) Définir le chemin et le format des données
Tout d'abord, vous déclarez deux variables avec le chemin du fichier csv. Notez que vous disposez de deux fichiers, un pour l’ensemble de formation et un pour l’ensemble de test.
import tensorflow as tf
df_train = "E:/boston_train.csv"
df_eval = "E:/boston_test.csv"
Ensuite, vous devez définir les colonnes que vous souhaitez utiliser à partir du fichier csv. Nous utiliserons tout. Après cela, vous devez déclarer le type de variable dont il s’agit.
Les variables flottantes sont définies par [0.]
COLUMNS = ["crim", "zn", "indus", "nox", "rm", "age", "dis", "tax", "ptratio", "medv"]RECORDS_ALL = [[0.0], [0.0], [0.0], [0.0],[0.0],[0.0],[0.0],[0.0],[0.0],[0.0]]
Étape 2) Définir la fonction input_fn
La fonction peut être divisée en trois parties :
- Importez les données
- Créer l'itérateur
- Consommer les données
Vous trouverez ci-dessous le code global pour définir la fonction. Le code sera expliqué après
def input_fn(data_file, batch_size, num_epoch = None): # Step 1 def parse_csv(value): columns = tf.decode_csv(value, record_defaults= RECORDS_ALL) features = dict(zip(COLUMNS, columns)) #labels = features.pop('median_house_value') labels = features.pop('medv') return features, labels # Extract lines from input files using the Dataset API. dataset = (tf.data.TextLineDataset(data_file) # Read text file .skip(1) # Skip header row .map(parse_csv)) dataset = dataset.repeat(num_epoch) dataset = dataset.batch(batch_size) # Step 3 iterator = dataset.make_one_shot_iterator() features, labels = iterator.get_next() return features, labels
** Importez les données **
Pour un fichier csv, la méthode dataset lit une ligne à la fois. Pour créer l'ensemble de données, vous devez utiliser l'objet TextLineBase de données. Votre ensemble de données a un en-tête, vous devez donc utiliser skip(1) pour ignorer la première ligne. À ce stade, vous lisez uniquement les données et excluez l’en-tête du pipeline. Pour alimenter le modèle, vous devez séparer les fonctionnalités de l'étiquette. La méthode utilisée pour appliquer toute transformation aux données est la carte.
Cette méthode appelle une fonction que vous allez créer afin de vous indiquer comment transformer les données. En un mot, vous devez transmettre les données dans le TextLineObjet Ensemble de données, excluez l'en-tête et appliquez une transformation demandée par une fonction.Explication du code
- tf.data.TextLineDataset(data_file) : Cette ligne lit le fichier csv
- .skip(1) : ignore l'en-tête
- .map(parse_csv)) : analyser les enregistrements dans les tenseurs. Vous devez définir une fonction pour instruire l'objet cartographique. Vous pouvez appeler cette fonction parse_csv.
Cette fonction analyse le fichier csv avec la méthode tf.decode_csv et déclare les fonctionnalités et le label. Les fonctionnalités peuvent être déclarées sous forme de dictionnaire ou de tuple. Vous utilisez la méthode du dictionnaire car elle est plus pratique.Explication du code
- tf.decode_csv(value, record_defaults= RECORDS_ALL) : la méthode decode_csv utilise la sortie du TextLineEnsemble de données pour lire le fichier csv. record_defaults indique à TensorFlow le type de colonnes.
- dict(zip(_CSV_COLUMNS, columns)) : Remplir le dictionnaire avec toutes les colonnes extraites lors de ce traitement de données
- Features.pop('median_house_value') : excluez la variable cible de la variable de fonctionnalité et créez une variable d'étiquette
L'ensemble de données a besoin d'éléments supplémentaires pour alimenter de manière itérative les tenseurs. En effet, il faut ajouter la méthode repeat pour permettre au jeu de données de continuer indéfiniment à alimenter le modèle. Si vous n'ajoutez pas la méthode, le modèle effectuera une seule itération, puis générera une erreur car plus aucune donnée n'est introduite dans le pipeline.
Après cela, vous pouvez contrôler la taille du lot avec la méthode batch. Cela signifie que vous indiquez à l'ensemble de données combien de données vous souhaitez transmettre dans le pipeline pour chaque itération. Si vous définissez une taille de lot importante, le modèle sera lent.
Étape 3) Créer l'itérateur
Vous êtes maintenant prêt pour la deuxième étape : créer un itérateur pour renvoyer les éléments de l'ensemble de données.
La manière la plus simple de créer un opérateur consiste à utiliser la méthode make_one_shot_iterator.
Après cela, vous pouvez créer les fonctionnalités et les étiquettes à partir de l'itérateur.
Étape 4) Consommer les données
Vous pouvez vérifier ce qui se passe avec la fonction input_fn. Vous devez appeler la fonction dans une session pour consommer les données. Vous essayez avec une taille de lot égale à 1.
Notez qu'il imprime les fonctionnalités dans un dictionnaire et l'étiquette sous forme de tableau.
Il affichera la première ligne du fichier csv. Vous pouvez essayer d'exécuter ce code plusieurs fois avec des tailles de lot différentes.
next_batch = input_fn(df_train, batch_size = 1, num_epoch = None) with tf.Session() as sess: first_batch = sess.run(next_batch) print(first_batch)
Sortie
({'crim': array([2.3004], dtype=float32), 'zn': array([0.], dtype=float32), 'indus': array([19.58], dtype=float32), 'nox': array([0.605], dtype=float32), 'rm': array([6.319], dtype=float32), 'age': array([96.1], dtype=float32), 'dis': array([2.1], dtype=float32), 'tax': array([403.], dtype=float32), 'ptratio': array([14.7], dtype=float32)}, array([23.8], dtype=float32))
Étape 4) Définir la colonne de fonctionnalités
Vous devez définir les colonnes numériques comme suit :
X1= tf.feature_column.numeric_column('crim') X2= tf.feature_column.numeric_column('zn') X3= tf.feature_column.numeric_column('indus') X4= tf.feature_column.numeric_column('nox') X5= tf.feature_column.numeric_column('rm') X6= tf.feature_column.numeric_column('age') X7= tf.feature_column.numeric_column('dis') X8= tf.feature_column.numeric_column('tax') X9= tf.feature_column.numeric_column('ptratio')
Notez que vous devez combiner toutes les variables dans un bucket
base_columns = [X1, X2, X3,X4, X5, X6,X7, X8, X9]
Étape 5) Construisez le modèle
Vous pouvez entraîner le modèle avec l'estimateur LinearRegressor.
model = tf.estimator.LinearRegressor(feature_columns=base_columns, model_dir='train3')
Sortie
INFO:tensorflow:Using default config. INFO:tensorflow:Using config: {'_model_dir': 'train3', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1820a010f0>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
Vous devez utiliser une fonction lambda pour permettre d'écrire l'argument dans la fonction inpu_fn. Si vous n'utilisez pas de fonction lambda, vous ne pouvez pas entraîner le modèle.
# Train the estimatormodel.train(steps =1000, input_fn= lambda : input_fn(df_train,batch_size=128, num_epoch = None))
Sortie
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Create CheckpointSaverHook. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Saving checkpoints for 1 into train3/model.ckpt. INFO:tensorflow:loss = 83729.64, step = 1 INFO:tensorflow:global_step/sec: 72.5646 INFO:tensorflow:loss = 13909.657, step = 101 (1.380 sec) INFO:tensorflow:global_step/sec: 101.355 INFO:tensorflow:loss = 12881.449, step = 201 (0.986 sec) INFO:tensorflow:global_step/sec: 109.293 INFO:tensorflow:loss = 12391.541, step = 301 (0.915 sec) INFO:tensorflow:global_step/sec: 102.235 INFO:tensorflow:loss = 12050.5625, step = 401 (0.978 sec) INFO:tensorflow:global_step/sec: 104.656 INFO:tensorflow:loss = 11766.134, step = 501 (0.956 sec) INFO:tensorflow:global_step/sec: 106.697 INFO:tensorflow:loss = 11509.922, step = 601 (0.938 sec) INFO:tensorflow:global_step/sec: 118.454 INFO:tensorflow:loss = 11272.889, step = 701 (0.844 sec) INFO:tensorflow:global_step/sec: 114.947 INFO:tensorflow:loss = 11051.9795, step = 801 (0.870 sec) INFO:tensorflow:global_step/sec: 111.484 INFO:tensorflow:loss = 10845.855, step = 901 (0.897 sec) INFO:tensorflow:Saving checkpoints for 1000 into train3/model.ckpt. INFO:tensorflow:Loss for final step: 5925.9873. Out[8]: <tensorflow.python.estimator.canned.linear.LinearRegressor at 0x18225eb8d0>
Vous pouvez évaluer l'ajustement de votre modèle sur l'ensemble de test avec le code ci-dessous :
results = model.evaluate(steps =None,input_fn=lambda: input_fn(df_eval, batch_size =128, num_epoch = 1)) for key in results: print(" {}, was: {}".format(key, results[key]))
Sortie
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Starting evaluation at 2018-05-13-02:06:02 INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train3/model.ckpt-1000 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Finished evaluation at 2018-05-13-02:06:02 INFO:tensorflow:Saving dict for global step 1000: average_loss = 32.15896, global_step = 1000, loss = 3215.896 average_loss, was: 32.158958435058594 loss, was: 3215.89599609375 global_step, was: 1000
La dernière étape consiste à prédire la valeur de en fonction de la valeur de , les matrices des caractéristiques. Vous pouvez écrire un dictionnaire avec les valeurs que vous souhaitez prédire. Votre modèle comporte 9 fonctionnalités, vous devez donc fournir une valeur pour chacune. Le modèle fournira une prédiction pour chacun d’eux.
Dans le code ci-dessous, vous avez écrit les valeurs de chaque fonctionnalité contenue dans le fichier csv df_predict.
Vous devez écrire une nouvelle fonction input_fn car il n'y a pas d'étiquette dans l'ensemble de données. Vous pouvez utiliser l'API from_tensor à partir de l'ensemble de données.
prediction_input = { 'crim': [0.03359,5.09017,0.12650,0.05515,8.15174,0.24522], 'zn': [75.0,0.0,25.0,33.0,0.0,0.0], 'indus': [2.95,18.10,5.13,2.18,18.10,9.90], 'nox': [0.428,0.713,0.453,0.472,0.700,0.544], 'rm': [7.024,6.297,6.762,7.236,5.390,5.782], 'age': [15.8,91.8,43.4,41.1,98.9,71.7], 'dis': [5.4011,2.3682,7.9809,4.0220,1.7281,4.0317], 'tax': [252,666,284,222,666,304], 'ptratio': [18.3,20.2,19.7,18.4,20.2,18.4] } def test_input_fn(): dataset = tf.data.Dataset.from_tensors(prediction_input) return dataset # Predict all our prediction_inputpred_results = model.predict(input_fn=test_input_fn)
Enfin, vous imprimez les prédictions.
for pred in enumerate(pred_results): print(pred)
Sortie
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train3/model.ckpt-1000 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. (0, {'predictions': array([32.297546], dtype=float32)}) (1, {'predictions': array([18.96125], dtype=float32)}) (2, {'predictions': array([27.270979], dtype=float32)}) (3, {'predictions': array([29.299236], dtype=float32)}) (4, {'predictions': array([16.436684], dtype=float32)}) (5, {'predictions': array([21.460876], dtype=float32)}) INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train3/model.ckpt-5000 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. (0, {'predictions': array([35.60663], dtype=float32)}) (1, {'predictions': array([22.298521], dtype=float32)}) (2, {'predictions': array([25.74533], dtype=float32)}) (3, {'predictions': array([35.126694], dtype=float32)}) (4, {'predictions': array([17.94416], dtype=float32)}) (5, {'predictions': array([22.606628], dtype=float32)})
Résumé
Pour entraîner un modèle, vous devez :
- Définir les fonctionnalités : Variables indépendantes : X
- Définir le label : Variable dépendante : y
- Construire un ensemble de train/test
- Définir le poids initial
- Définir la fonction de perte : MSE
- Optimiser le modèle : Descente de gradient
- Définir:
- Taux d'apprentissage
- Nombre d'époque
- Taille du lot
Dans ce didacticiel, vous avez appris à utiliser l'API de haut niveau pour un estimateur TensorFlow par régression linéaire. Vous devez définir :
- Colonnes de fonctionnalités. Si continu : tf.feature_column.numeric_column(). Vous pouvez remplir une liste avec la compréhension de la liste Python
- L'estimateur : tf.estimator.LinearRegressor(feature_columns, model_dir)
- Une fonction pour importer les données, la taille du lot et l'époque : input_fn()
Après cela, vous êtes prêt à vous entraîner, à évaluer et à faire des prédictions avec train(), évalue() et prédire().