From fd7daadac89a4271904f70a0c12c297de1ba5b2a Mon Sep 17 00:00:00 2001 From: Philippe Roy Date: Tue, 27 Jun 2023 12:57:24 +0200 Subject: [PATCH] Mise en place du portage vers Keras de TensorFlow Playground --- .../03-descente_gradient_stochastique.py | 7 +- 01-fondamentaux/05-regression_polynomiale.py | 26 +-- 02-intro_rna/03-keras-tf_playground-cercle.py | 160 ++++++++++++++++ 02-intro_rna/04-keras-tf_playground-xor.py | 171 ++++++++++++++++++ 02-intro_rna/05-keras-tf_playground-gauss.py | 167 +++++++++++++++++ 02-intro_rna/06-keras-tf_playground-spiral.py | 167 +++++++++++++++++ 6 files changed, 682 insertions(+), 16 deletions(-) create mode 100644 02-intro_rna/03-keras-tf_playground-cercle.py create mode 100644 02-intro_rna/04-keras-tf_playground-xor.py create mode 100644 02-intro_rna/05-keras-tf_playground-gauss.py create mode 100644 02-intro_rna/06-keras-tf_playground-spiral.py diff --git a/01-fondamentaux/03-descente_gradient_stochastique.py b/01-fondamentaux/03-descente_gradient_stochastique.py index a138c5d..f1fd85e 100644 --- a/01-fondamentaux/03-descente_gradient_stochastique.py +++ b/01-fondamentaux/03-descente_gradient_stochastique.py @@ -1,3 +1,4 @@ + import time import numpy as np import sklearn @@ -76,14 +77,14 @@ X_new = np.c_[np.ones((2, 1)), x1_new] # Matrice des observations, avec x0=1 # Phase d'apprentissage par descente de gradient stochastique # - theta : vecteur paramètres du modèle # - gradient : gradient du coût en fonction de theta -# - eta : taux d'appentissage ici dégressif par échéancier d'apprentissage (ech_app) +# - eta : taux d'appentissage ici dégressif par échéancier d'apprentissage (apts_ech) # n_epoq = 50 # Nombre d'époques n_epoq = 2 # Nombre d'époques (hyperparamètre) # Rédéfinition du taux d'apprentissage à partir de l'échéancier d'apprentissage t0, t1 = 5, 50 # Facteurs de l'échéancier d'apprentissage (hyperparamètres) -def ech_app (t): +def apts_ech (t): return t0 / (t + t1) # Calcul du coût (Mean Square Error (MSE), Root Mean Square Error (RMSE)) @@ -107,7 +108,7 @@ for epoq in range (n_epoq): xi = X[idx : idx+1] yi = y[idx : idx+1] gradients = 2/1 * xi.T.dot(xi.dot(theta) - yi) - eta = ech_app (epoq * m + i) + eta = apts_ech (epoq * m + i) eta_list.append(eta) theta = theta - eta * gradients theta0.append(theta[0]) diff --git a/01-fondamentaux/05-regression_polynomiale.py b/01-fondamentaux/05-regression_polynomiale.py index 9bdae44..65c4121 100644 --- a/01-fondamentaux/05-regression_polynomiale.py +++ b/01-fondamentaux/05-regression_polynomiale.py @@ -44,7 +44,7 @@ t_debut = time.time() fig = plt.figure(figsize=(15, 5)) fig.suptitle("Régression polynomiale") donnees_ax = fig.add_subplot(121) # Observations : x1 et cibles : y -app_ax = fig.add_subplot(122) # Courbes d'apprentissage +apts_ax = fig.add_subplot(122) # Courbes d'apprentissage ############################################################################### # Observations @@ -145,22 +145,22 @@ donnees_ax.legend() donnees_ax.set(xlim=(-3, 3), ylim=(0, 10)) # Plot des courbes d'apprentissage -app_ax.set_title("Courbes d'apprentissage") +apts_ax.set_title("Courbes d'apprentissage") -app_ax.plot(np.sqrt(train_errors_1), 'g:', label="Entrainement - degré 1") -app_ax.plot(np.sqrt(val_errors_1), 'g-', label="Validation - degré 1") +apts_ax.plot(np.sqrt(train_errors_1), 'g:', label="Entrainement - degré 1") +apts_ax.plot(np.sqrt(val_errors_1), 'g-', label="Validation - degré 1") -app_ax.plot(np.sqrt(train_errors_2), 'r:', label="Entrainement - degré 2") -app_ax.plot(np.sqrt(val_errors_2), 'r-', label="Validation - degré 2") +apts_ax.plot(np.sqrt(train_errors_2), 'r:', label="Entrainement - degré 2") +apts_ax.plot(np.sqrt(val_errors_2), 'r-', label="Validation - degré 2") -app_ax.plot(np.sqrt(train_errors_30), 'k:', label="Entrainement - degré 30") -app_ax.plot(np.sqrt(val_errors_30), 'k-', label="Validation - degré 30") +apts_ax.plot(np.sqrt(train_errors_30), 'k:', label="Entrainement - degré 30") +apts_ax.plot(np.sqrt(val_errors_30), 'k-', label="Validation - degré 30") -app_ax.set_xlabel("Taille du lot d'entrainement") -app_ax.set_ylabel("RMSE") -app_ax.set(xlim=(0, 80), ylim=(0, 10)) -# app_ax.set(xlim=(0, 80), ylim=(0, 3)) -app_ax.legend() +apts_ax.set_xlabel("Taille du lot d'entrainement") +apts_ax.set_ylabel("RMSE") +apts_ax.set(xlim=(0, 80), ylim=(0, 10)) +# apts_ax.set(xlim=(0, 80), ylim=(0, 3)) +apts_ax.legend() plt.show() diff --git a/02-intro_rna/03-keras-tf_playground-cercle.py b/02-intro_rna/03-keras-tf_playground-cercle.py new file mode 100644 index 0000000..e4a9061 --- /dev/null +++ b/02-intro_rna/03-keras-tf_playground-cercle.py @@ -0,0 +1,160 @@ +import os, time +import numpy as np +import matplotlib.pyplot as plt + +import tensorflow as tf +from tensorflow import keras + +############################################################################### +# 03-keras-tf_playground-cercle.py +# @title: Introduction aux réseaux de neurones - Portage de TensorFlow Playground vers Keras - Points en cercle +# @project: Mes scripts de ML +# @lang: fr +# @authors: Philippe Roy +# @copyright: Copyright (C) 2023 Philippe Roy +# @license: GNU GPL +############################################################################### + +### +# TensorFlow Playground : +# - Site internet : https://playground.tensorflow.org +# - Dépôt git : https://github.com/tensorflow/playground +### + +### +# Installation : +# - pip3 install tensorflow +# - pip3 install keras +# - pip3 install pydot +# - pip3 install graphviz +### + +### +# Commandes NumPy : +# - np.array : créer un tableau à partir d'une liste de listes +# - np.c_ : concatène les colonnes des tableaux +# - np.linspace : créer un tableau 1D de la valeur de début à la valeur de fin avec n valeurs +# - np.meshgrid : créer un tableau 2D avec l'ensemble des combinaisons allant des deux valeurs de début aux deux valeurs de fin +# - .reshape : reformater la tableau avec le nombre de lignes et le nombre de colonnes +### + +### +# Commandes Keras : +# - keras.models.Sequential() : créer un modèle où les couches de neurones sont reliées séquentiellement (modèle simple) +# - keras.layers.Flatten : ajout d'une couche de formatage de mise à plat +# - keras.layers.Dense : ajout d'une couche de neurones +# - keras.backend.clear_session() : reset de la session +# - .compile : compilation du modèle +# - .fit : entrainement du modèle +# - .predict : prédiction du modèle +# - keras.utils.plot_model : créer le diagramme d'un modèle +### + +############################################################################### +# Initialisation +############################################################################### + +# Init du temps +t_debut = time.time() + +# Init des plots +fig = plt.figure(figsize=(15, 5)) +fig.suptitle("Réseaux de neurones avec Keras - Classificateur : points en cercle") +model_ax = fig.add_subplot(131) # Modèle +apts_ax = fig.add_subplot(132) # Courbes d'apprentissage +donnees_ax = fig.add_subplot(133) # Observations : x1,x2 et cibles : y + +############################################################################### +# Observations +############################################################################### + +# Observations d'apprentissage, de validation et de test +vetement = keras.datasets.fashion_mnist # Jeu de données Fashion MNIST +(X, y), (X_test, y_test) = vetement.load_data() +X_train, y_train = X[5000:]/255.0 , y[5000:] +X_valid, y_valid = X[:5000]/255.0 , y[:5000] +classes = ["Tshirt", "Pantalon", "Pull", "Robe", "Manteau", "Sandale", "Chemise", "Basket", "Sac", "Bottine"] + +############################################################################### +# Phase d'apprentissage +############################################################################### + +n = 30 # Nombre d'itérations (valeur par défaut : 30 , hyperparamètre) +eta = 0.01 # Taux d'appentissage (valeur par défaut dans Keras : 0.01, hyperparamètre) +lot=32 # Taille de lot (valeur par défaut dans Keras: 32 , hyperparamètre) +perte="sparse_categorical_crossentropy" # Type de perte (hyperparamètre) +#perte="mse" # Type de perte (hyperparamètre) + +keras.backend.clear_session() +# np.random.seed(42) +# tf.random.set_seed(42) + +model = keras.models.Sequential() # Modèle de reseau de neurones +model.add(keras.layers.Flatten(input_shape=[28, 28])) # Couche d'entrée : mise à plat des données d'entrée -> 1 node / pixel soit 784 (28x28) +model.add(keras.layers.Dense(300, activation="relu")) # Couche 1 : 300 nodes +# model.add(keras.layers.Dense(300, activation="relu")) # Couche 2 : 300 nodes -> passage de 100 à 300 +# model.add(keras.layers.Dense(300, activation="relu")) # Couche 3 : 300 nodes -> ajout +model.add(keras.layers.Dense(100, activation="relu")) # Couche 4 : 100 nodes -> ajout +model.add(keras.layers.Dense(10, activation="softmax")) # Couche de sortie : 1 node par classe soit 10 + +# model.compile(loss="sparse_categorical_crossentropy", optimizer="sgd", metrics=["accuracy"]) +optimiseur=keras.optimizers.SGD(learning_rate= eta) +model.compile(loss=perte, optimizer=optimiseur, metrics=["accuracy"]) # Compilation du modèle + +apts = model.fit(X_train, y_train, epochs=n, batch_size=lot, validation_data=(X_valid, y_valid)) # Entrainement + +############################################################################### +# Phase d'inférence +############################################################################### + +# X_new=[] +# y_new=[] +# for i in range(8): +# idx = np.random.randint(X_test.shape[0]) # Index aléatoire +# X_new.append(X_test[idx:idx+1]/255.0) +# y_new.append(y_test[idx:idx+1]) + +idx = np.random.randint(X_test.shape[0]-32) # Index aléatoire +print ("\n") +print ("Test sur les images de "+ str(idx) + " à "+ str(idx+32) + " sur un jeu de 10 000 images.") +X_new = X_test[idx:idx+32] +y_new = np.argmax(model.predict(X_new), axis=-1) +y_new_test= y_test[idx:idx+32] +print ("\n") + +############################################################################### +# Résultats +############################################################################### + +# Modèle +model_ax.set_title("Modèle") +keras.utils.plot_model(model, "model.png", show_shapes=True) +model_img=plt.imread("model.png") +model_ax.imshow(model_img) +model_ax.set_axis_off() +os.remove("model.png") # Supression du fichier temporaire + +# Courbes d'apprentissage +apts_ax.set_title("Courbes d'apprentissage") +apts_ax.plot(apts.epoch, apts.history['loss'], 'b-', label="Perte - entrainement") +apts_ax.plot(apts.epoch, apts.history['val_loss'], 'r-', label="Perte - validation") +apts_ax.plot(apts.epoch, apts.history['accuracy'], 'b:', label="Précision - entrainement") +apts_ax.plot(apts.epoch, apts.history['val_accuracy'], 'r:', label="Précision - validation") +apts_ax.set(ylim=(0, 1)) +apts_ax.set_xlabel("Époque") +apts_ax.legend() + +# Prédictions +for i in range (8): + for j in range (4): + img_ax[j][i].imshow(X_new[i*2+j], cmap="binary", interpolation="nearest") + img_ax[j][i].set_axis_off() + if y_new[i*2+j] == y_new_test[i*2+j]: + img_ax[j][i].set_title(classes[y_new[i*2+j]], fontsize=10) + else: + img_ax[j][i].set_title(classes[y_new[i*2+j]], fontsize=10, color="red") + +plt.show() + +# Performances +print ("Temps total : "+str(time.time()-t_debut)) diff --git a/02-intro_rna/04-keras-tf_playground-xor.py b/02-intro_rna/04-keras-tf_playground-xor.py new file mode 100644 index 0000000..65189a9 --- /dev/null +++ b/02-intro_rna/04-keras-tf_playground-xor.py @@ -0,0 +1,171 @@ +import os, time +import numpy as np +import matplotlib.pyplot as plt + +import tensorflow as tf +from tensorflow import keras + +############################################################################### +# 04-keras-tf_playground-xor.py +# @title: Introduction aux réseaux de neurones - Portage de TensorFlow Playground vers Keras - Points en XOR +# @project: Mes scripts de ML +# @lang: fr +# @authors: Philippe Roy +# @copyright: Copyright (C) 2023 Philippe Roy +# @license: GNU GPL +############################################################################### + +### +# TensorFlow Playground : +# - Site internet : https://playground.tensorflow.org +# - Dépôt git : https://github.com/tensorflow/playground +### + +### +# Installation : +# - pip3 install tensorflow +# - pip3 install keras +# - pip3 install pydot +# - pip3 install graphviz +### + +### +# Commandes NumPy : +# - np.array : créer un tableau à partir d'une liste de listes +# - np.c_ : concatène les colonnes des tableaux +# - np.linspace : créer un tableau 1D de la valeur de début à la valeur de fin avec n valeurs +# - np.meshgrid : créer un tableau 2D avec l'ensemble des combinaisons allant des deux valeurs de début aux deux valeurs de fin +# - .reshape : reformater la tableau avec le nombre de lignes et le nombre de colonnes +### + +### +# Commandes Keras : +# - keras.models.Sequential() : créer un modèle où les couches de neurones sont reliées séquentiellement (modèle simple) +# - keras.layers.Flatten : ajout d'une couche de formatage de mise à plat +# - keras.layers.Dense : ajout d'une couche de neurones +# - keras.backend.clear_session() : reset de la session +# - .compile : compilation du modèle +# - .fit : entrainement du modèle +# - .predict : prédiction du modèle +# - keras.utils.plot_model : créer le diagramme d'un modèle +### + +############################################################################### +# Initialisation +############################################################################### + +# Init de Tensorflow + Keras + +# tf.__version__ +# keras.__version__ +# tf.config.list_physical_devices('GPU') + +# Init du temps +t_debut = time.time() + +# Init des plots +fig = plt.figure(figsize=(15, 5)) +fig.suptitle("Réseaux de neurones avec Keras - Classificateur : XOR") +model_ax = fig.add_subplot(131) # Modèle +apts_ax = fig.add_subplot(132) # Courbes d'apprentissage +donnees_ax = fig.add_subplot(133) # Observations : x1,x2 et cibles : y + +############################################################################### +# Observations +############################################################################### + +# Observations d'apprentisage +m = 1000 # Nombre d'observations +bg = 1 # Quantité du bruit gaussien +x1 = 10*np.random.rand(m, 1) # Liste des observations x1 +x2 = 10*np.random.rand(m, 1) # Liste des observations x1 +# y = 4 + 3*x1 + bg * np.random.rand(m, 1) # Liste des cibles y +# X = np.c_[np.ones((m, 1)), x1] # Matrice des observations, avec x0=1 +plt.plot(x1, x2, 'b.', label="Observations") + +# Nouvelles observations +# x1_new=np.array([[0], [2]]) +# X_new = np.c_[np.ones((2, 1)), x1_new] # Matrice des observations, avec x0=1 + +# # Observations d'apprentissage, de validation et de test +# vetement = keras.datasets.fashion_mnist # Jeu de données Fashion MNIST +# (X, y), (X_test, y_test) = vetement.load_data() +# X_train, y_train = X[5000:]/255.0 , y[5000:] +# X_valid, y_valid = X[:5000]/255.0 , y[:5000] +# classes = ["Tshirt", "Pantalon", "Pull", "Robe", "Manteau", "Sandale", "Chemise", "Basket", "Sac", "Bottine"] + +############################################################################### +# Phase d'apprentissage +############################################################################### + +n = 30 # Nombre d'itérations (valeur par défaut : 30 , hyperparamètre) +eta = 0.01 # Taux d'appentissage (valeur par défaut dans Keras : 0.01, hyperparamètre) +lot=32 # Taille de lot (valeur par défaut dans Keras: 32 , hyperparamètre) +perte="sparse_categorical_crossentropy" # Type de perte (hyperparamètre) +#perte="mse" # Type de perte (hyperparamètre) + +keras.backend.clear_session() +# model = keras.models.Sequential() # Modèle de reseau de neurones +# model.add(keras.layers.Flatten(input_shape=[28, 28])) # Couche d'entrée : mise à plat des données d'entrée -> 1 node / pixel soit 784 (28x28) +# model.add(keras.layers.Dense(300, activation="relu")) # Couche 1 : 300 nodes +# # model.add(keras.layers.Dense(300, activation="relu")) # Couche 2 : 300 nodes -> passage de 100 à 300 +# # model.add(keras.layers.Dense(300, activation="relu")) # Couche 3 : 300 nodes -> ajout +# model.add(keras.layers.Dense(100, activation="relu")) # Couche 4 : 100 nodes -> ajout +# model.add(keras.layers.Dense(10, activation="softmax")) # Couche de sortie : 1 node par classe soit 10 + +# # model.compile(loss="sparse_categorical_crossentropy", optimizer="sgd", metrics=["accuracy"]) +# optimiseur=keras.optimizers.SGD(learning_rate= eta) +# model.compile(loss=perte, optimizer=optimiseur, metrics=["accuracy"]) # Compilation du modèle + +# apts = model.fit(X_train, y_train, epochs=n, batch_size=lot, validation_data=(X_valid, y_valid)) # Entrainement + +############################################################################### +# Phase d'inférence +############################################################################### + +# X_new=[] +# y_new=[] +# for i in range(8): +# idx = np.random.randint(X_test.shape[0]) # Index aléatoire +# X_new.append(X_test[idx:idx+1]/255.0) +# y_new.append(y_test[idx:idx+1]) + +# idx = np.random.randint(X_test.shape[0]-32) # Index aléatoire +# print ("\n") +# print ("Test sur les images de "+ str(idx) + " à "+ str(idx+32) + " sur un jeu de 10 000 images.") +# X_new = X_test[idx:idx+32] +# y_new = np.argmax(model.predict(X_new), axis=-1) +# y_new_test= y_test[idx:idx+32] +# print ("\n") + +############################################################################### +# Résultats +############################################################################### + +# Modèle +# model_ax.set_title("Modèle") +# keras.utils.plot_model(model, "model.png", show_shapes=True) +# model_img=plt.imread("model.png") +# model_ax.imshow(model_img) +# model_ax.set_axis_off() +# os.remove("model.png") # Supression du fichier temporaire + +# Courbes d'apprentissage +# apts_ax.set_title("Courbes d'apprentissage") +# apts_ax.plot(apts.epoch, apts.history['loss'], 'b-', label="Perte - entrainement") +# apts_ax.plot(apts.epoch, apts.history['val_loss'], 'r-', label="Perte - validation") +# apts_ax.plot(apts.epoch, apts.history['accuracy'], 'b:', label="Précision - entrainement") +# apts_ax.plot(apts.epoch, apts.history['val_accuracy'], 'r:', label="Précision - validation") +# apts_ax.set(ylim=(0, 1)) +# apts_ax.set_xlabel("Époque") +# apts_ax.legend() + +# Plot des données +donnees_ax.set_title("Données") +donnees_ax.set_xlabel(r'$x_1$') +donnees_ax.set_ylabel(r'$x_2$', rotation=0) +# donnees_ax.legend() +plt.show() + +# Performances +print ("Temps total : "+str(time.time()-t_debut)) diff --git a/02-intro_rna/05-keras-tf_playground-gauss.py b/02-intro_rna/05-keras-tf_playground-gauss.py new file mode 100644 index 0000000..5f703c8 --- /dev/null +++ b/02-intro_rna/05-keras-tf_playground-gauss.py @@ -0,0 +1,167 @@ +import os, time +import numpy as np +import matplotlib.pyplot as plt + +import tensorflow as tf +from tensorflow import keras + +############################################################################### +# 05-keras-tf_playground-gauss.py +# @title: Introduction aux réseaux de neurones - Portage de TensorFlow Playground vers Keras - Points en gaussienne +# @project: Mes scripts de ML +# @lang: fr +# @authors: Philippe Roy +# @copyright: Copyright (C) 2023 Philippe Roy +# @license: GNU GPL +############################################################################### + +### +# TensorFlow Playground : +# - Site internet : https://playground.tensorflow.org +# - Dépôt git : https://github.com/tensorflow/playground +### + +### +# Installation : +# - pip3 install tensorflow +# - pip3 install keras +# - pip3 install pydot +# - pip3 install graphviz +### + +### +# Commandes NumPy : +# - np.array : créer un tableau à partir d'une liste de listes +# - np.c_ : concatène les colonnes des tableaux +# - np.linspace : créer un tableau 1D de la valeur de début à la valeur de fin avec n valeurs +# - np.meshgrid : créer un tableau 2D avec l'ensemble des combinaisons allant des deux valeurs de début aux deux valeurs de fin +# - .reshape : reformater la tableau avec le nombre de lignes et le nombre de colonnes +### + +### +# Commandes Keras : +# - keras.models.Sequential() : créer un modèle où les couches de neurones sont reliées séquentiellement (modèle simple) +# - keras.layers.Flatten : ajout d'une couche de formatage de mise à plat +# - keras.layers.Dense : ajout d'une couche de neurones +# - keras.backend.clear_session() : reset de la session +# - .compile : compilation du modèle +# - .fit : entrainement du modèle +# - .predict : prédiction du modèle +# - keras.utils.plot_model : créer le diagramme d'un modèle +### + +############################################################################### +# Initialisation +############################################################################### + +# Init de Tensorflow + Keras + +# tf.__version__ +# keras.__version__ +# tf.config.list_physical_devices('GPU') + +# Init du temps +t_debut = time.time() + +# Init des plots +fig = plt.figure(layout="constrained", figsize=(15, 5)) +fig.suptitle("Réseaux de neurones avec Keras - Classificateur d'images") +subfigs = fig.subfigures(1, 3) +model_ax = subfigs[0].subplots(1, 1) +apts_ax = subfigs[1].subplots(1, 1) +img_ax = subfigs[2].subplots(4, 8) + +############################################################################### +# Observations +############################################################################### + +# Observations d'apprentissage, de validation et de test +vetement = keras.datasets.fashion_mnist # Jeu de données Fashion MNIST +(X, y), (X_test, y_test) = vetement.load_data() +X_train, y_train = X[5000:]/255.0 , y[5000:] +X_valid, y_valid = X[:5000]/255.0 , y[:5000] +classes = ["Tshirt", "Pantalon", "Pull", "Robe", "Manteau", "Sandale", "Chemise", "Basket", "Sac", "Bottine"] + +############################################################################### +# Phase d'apprentissage +############################################################################### + +n = 30 # Nombre d'itérations (valeur par défaut : 30 , hyperparamètre) +eta = 0.01 # Taux d'appentissage (valeur par défaut dans Keras : 0.01, hyperparamètre) +lot=32 # Taille de lot (valeur par défaut dans Keras: 32 , hyperparamètre) +perte="sparse_categorical_crossentropy" # Type de perte (hyperparamètre) +#perte="mse" # Type de perte (hyperparamètre) + +keras.backend.clear_session() +# np.random.seed(42) +# tf.random.set_seed(42) + +model = keras.models.Sequential() # Modèle de reseau de neurones +model.add(keras.layers.Flatten(input_shape=[28, 28])) # Couche d'entrée : mise à plat des données d'entrée -> 1 node / pixel soit 784 (28x28) +model.add(keras.layers.Dense(300, activation="relu")) # Couche 1 : 300 nodes +# model.add(keras.layers.Dense(300, activation="relu")) # Couche 2 : 300 nodes -> passage de 100 à 300 +# model.add(keras.layers.Dense(300, activation="relu")) # Couche 3 : 300 nodes -> ajout +model.add(keras.layers.Dense(100, activation="relu")) # Couche 4 : 100 nodes -> ajout +model.add(keras.layers.Dense(10, activation="softmax")) # Couche de sortie : 1 node par classe soit 10 + +# model.compile(loss="sparse_categorical_crossentropy", optimizer="sgd", metrics=["accuracy"]) +optimiseur=keras.optimizers.SGD(learning_rate= eta) +model.compile(loss=perte, optimizer=optimiseur, metrics=["accuracy"]) # Compilation du modèle + +apts = model.fit(X_train, y_train, epochs=n, batch_size=lot, validation_data=(X_valid, y_valid)) # Entrainement + +############################################################################### +# Phase d'inférence +############################################################################### + +# X_new=[] +# y_new=[] +# for i in range(8): +# idx = np.random.randint(X_test.shape[0]) # Index aléatoire +# X_new.append(X_test[idx:idx+1]/255.0) +# y_new.append(y_test[idx:idx+1]) + +idx = np.random.randint(X_test.shape[0]-32) # Index aléatoire +print ("\n") +print ("Test sur les images de "+ str(idx) + " à "+ str(idx+32) + " sur un jeu de 10 000 images.") +X_new = X_test[idx:idx+32] +y_new = np.argmax(model.predict(X_new), axis=-1) +y_new_test= y_test[idx:idx+32] +print ("\n") + +############################################################################### +# Résultats +############################################################################### + +# Modèle +model_ax.set_title("Modèle") +keras.utils.plot_model(model, "model.png", show_shapes=True) +model_img=plt.imread("model.png") +model_ax.imshow(model_img) +model_ax.set_axis_off() +os.remove("model.png") # Supression du fichier temporaire + +# Courbes d'apprentissage +apts_ax.set_title("Courbes d'apprentissage") +apts_ax.plot(apts.epoch, apts.history['loss'], 'b-', label="Perte - entrainement") +apts_ax.plot(apts.epoch, apts.history['val_loss'], 'r-', label="Perte - validation") +apts_ax.plot(apts.epoch, apts.history['accuracy'], 'b:', label="Précision - entrainement") +apts_ax.plot(apts.epoch, apts.history['val_accuracy'], 'r:', label="Précision - validation") +apts_ax.set(ylim=(0, 1)) +apts_ax.set_xlabel("Époque") +apts_ax.legend() + +# Prédictions +for i in range (8): + for j in range (4): + img_ax[j][i].imshow(X_new[i*2+j], cmap="binary", interpolation="nearest") + img_ax[j][i].set_axis_off() + if y_new[i*2+j] == y_new_test[i*2+j]: + img_ax[j][i].set_title(classes[y_new[i*2+j]], fontsize=10) + else: + img_ax[j][i].set_title(classes[y_new[i*2+j]], fontsize=10, color="red") + +plt.show() + +# Performances +print ("Temps total : "+str(time.time()-t_debut)) diff --git a/02-intro_rna/06-keras-tf_playground-spiral.py b/02-intro_rna/06-keras-tf_playground-spiral.py new file mode 100644 index 0000000..79319e0 --- /dev/null +++ b/02-intro_rna/06-keras-tf_playground-spiral.py @@ -0,0 +1,167 @@ +import os, time +import numpy as np +import matplotlib.pyplot as plt + +import tensorflow as tf +from tensorflow import keras + +############################################################################### +# 06-keras-tf_playground-spiral.py +# @title: Introduction aux réseaux de neurones - Portage de TensorFlow Playground vers Keras - Points en spirale +# @project: Mes scripts de ML +# @lang: fr +# @authors: Philippe Roy +# @copyright: Copyright (C) 2023 Philippe Roy +# @license: GNU GPL +############################################################################### + +### +# TensorFlow Playground : +# - Site internet : https://playground.tensorflow.org +# - Dépôt git : https://github.com/tensorflow/playground +### + +### +# Installation : +# - pip3 install tensorflow +# - pip3 install keras +# - pip3 install pydot +# - pip3 install graphviz +### + +### +# Commandes NumPy : +# - np.array : créer un tableau à partir d'une liste de listes +# - np.c_ : concatène les colonnes des tableaux +# - np.linspace : créer un tableau 1D de la valeur de début à la valeur de fin avec n valeurs +# - np.meshgrid : créer un tableau 2D avec l'ensemble des combinaisons allant des deux valeurs de début aux deux valeurs de fin +# - .reshape : reformater la tableau avec le nombre de lignes et le nombre de colonnes +### + +### +# Commandes Keras : +# - keras.models.Sequential() : créer un modèle où les couches de neurones sont reliées séquentiellement (modèle simple) +# - keras.layers.Flatten : ajout d'une couche de formatage de mise à plat +# - keras.layers.Dense : ajout d'une couche de neurones +# - keras.backend.clear_session() : reset de la session +# - .compile : compilation du modèle +# - .fit : entrainement du modèle +# - .predict : prédiction du modèle +# - keras.utils.plot_model : créer le diagramme d'un modèle +### + +############################################################################### +# Initialisation +############################################################################### + +# Init de Tensorflow + Keras + +# tf.__version__ +# keras.__version__ +# tf.config.list_physical_devices('GPU') + +# Init du temps +t_debut = time.time() + +# Init des plots +fig = plt.figure(layout="constrained", figsize=(15, 5)) +fig.suptitle("Réseaux de neurones avec Keras - Classificateur d'images") +subfigs = fig.subfigures(1, 3) +model_ax = subfigs[0].subplots(1, 1) +apts_ax = subfigs[1].subplots(1, 1) +img_ax = subfigs[2].subplots(4, 8) + +############################################################################### +# Observations +############################################################################### + +# Observations d'apprentissage, de validation et de test +vetement = keras.datasets.fashion_mnist # Jeu de données Fashion MNIST +(X, y), (X_test, y_test) = vetement.load_data() +X_train, y_train = X[5000:]/255.0 , y[5000:] +X_valid, y_valid = X[:5000]/255.0 , y[:5000] +classes = ["Tshirt", "Pantalon", "Pull", "Robe", "Manteau", "Sandale", "Chemise", "Basket", "Sac", "Bottine"] + +############################################################################### +# Phase d'apprentissage +############################################################################### + +n = 30 # Nombre d'itérations (valeur par défaut : 30 , hyperparamètre) +eta = 0.01 # Taux d'appentissage (valeur par défaut dans Keras : 0.01, hyperparamètre) +lot=32 # Taille de lot (valeur par défaut dans Keras: 32 , hyperparamètre) +perte="sparse_categorical_crossentropy" # Type de perte (hyperparamètre) +#perte="mse" # Type de perte (hyperparamètre) + +keras.backend.clear_session() +# np.random.seed(42) +# tf.random.set_seed(42) + +model = keras.models.Sequential() # Modèle de reseau de neurones +model.add(keras.layers.Flatten(input_shape=[28, 28])) # Couche d'entrée : mise à plat des données d'entrée -> 1 node / pixel soit 784 (28x28) +model.add(keras.layers.Dense(300, activation="relu")) # Couche 1 : 300 nodes +# model.add(keras.layers.Dense(300, activation="relu")) # Couche 2 : 300 nodes -> passage de 100 à 300 +# model.add(keras.layers.Dense(300, activation="relu")) # Couche 3 : 300 nodes -> ajout +model.add(keras.layers.Dense(100, activation="relu")) # Couche 4 : 100 nodes -> ajout +model.add(keras.layers.Dense(10, activation="softmax")) # Couche de sortie : 1 node par classe soit 10 + +# model.compile(loss="sparse_categorical_crossentropy", optimizer="sgd", metrics=["accuracy"]) +optimiseur=keras.optimizers.SGD(learning_rate= eta) +model.compile(loss=perte, optimizer=optimiseur, metrics=["accuracy"]) # Compilation du modèle + +apts = model.fit(X_train, y_train, epochs=n, batch_size=lot, validation_data=(X_valid, y_valid)) # Entrainement + +############################################################################### +# Phase d'inférence +############################################################################### + +# X_new=[] +# y_new=[] +# for i in range(8): +# idx = np.random.randint(X_test.shape[0]) # Index aléatoire +# X_new.append(X_test[idx:idx+1]/255.0) +# y_new.append(y_test[idx:idx+1]) + +idx = np.random.randint(X_test.shape[0]-32) # Index aléatoire +print ("\n") +print ("Test sur les images de "+ str(idx) + " à "+ str(idx+32) + " sur un jeu de 10 000 images.") +X_new = X_test[idx:idx+32] +y_new = np.argmax(model.predict(X_new), axis=-1) +y_new_test= y_test[idx:idx+32] +print ("\n") + +############################################################################### +# Résultats +############################################################################### + +# Modèle +model_ax.set_title("Modèle") +keras.utils.plot_model(model, "model.png", show_shapes=True) +model_img=plt.imread("model.png") +model_ax.imshow(model_img) +model_ax.set_axis_off() +os.remove("model.png") # Supression du fichier temporaire + +# Courbes d'apprentissage +apts_ax.set_title("Courbes d'apprentissage") +apts_ax.plot(apts.epoch, apts.history['loss'], 'b-', label="Perte - entrainement") +apts_ax.plot(apts.epoch, apts.history['val_loss'], 'r-', label="Perte - validation") +apts_ax.plot(apts.epoch, apts.history['accuracy'], 'b:', label="Précision - entrainement") +apts_ax.plot(apts.epoch, apts.history['val_accuracy'], 'r:', label="Précision - validation") +apts_ax.set(ylim=(0, 1)) +apts_ax.set_xlabel("Époque") +apts_ax.legend() + +# Prédictions +for i in range (8): + for j in range (4): + img_ax[j][i].imshow(X_new[i*2+j], cmap="binary", interpolation="nearest") + img_ax[j][i].set_axis_off() + if y_new[i*2+j] == y_new_test[i*2+j]: + img_ax[j][i].set_title(classes[y_new[i*2+j]], fontsize=10) + else: + img_ax[j][i].set_title(classes[y_new[i*2+j]], fontsize=10, color="red") + +plt.show() + +# Performances +print ("Temps total : "+str(time.time()-t_debut))