Keras : classificateur gauss

This commit is contained in:
Philippe Roy 2023-06-28 08:11:54 +02:00
parent d3a407474e
commit 37e5fc2e58
3 changed files with 82 additions and 56 deletions

View File

@ -1,6 +1,8 @@
import os, time import os, time
import numpy as np import numpy as np
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.colors import ListedColormap, LinearSegmentedColormap
import tensorflow as tf import tensorflow as tf
from tensorflow import keras from tensorflow import keras
@ -54,57 +56,87 @@ from tensorflow import keras
# Initialisation # Initialisation
############################################################################### ###############################################################################
# Init de Tensorflow + Keras
# tf.__version__
# keras.__version__
# tf.config.list_physical_devices('GPU')
# Init du temps # Init du temps
t_debut = time.time() t_debut = time.time()
# Init des plots # Init des plots
fig = plt.figure(layout="constrained", figsize=(15, 5)) fig = plt.figure(figsize=(15, 5))
fig.suptitle("Réseaux de neurones avec Keras - Classificateur d'images") fig.suptitle("Réseaux de neurones avec Keras - Classificateur : points sur une Gaussienne")
subfigs = fig.subfigures(1, 3) model_ax = fig.add_subplot(131) # Modèle
model_ax = subfigs[0].subplots(1, 1) apts_ax = fig.add_subplot(132) # Courbes d'apprentissage
apts_ax = subfigs[1].subplots(1, 1) donnees_ax = fig.add_subplot(133) # Observations : x1,x2 et cibles : y
img_ax = subfigs[2].subplots(4, 8)
############################################################################### ###############################################################################
# Observations # Observations
############################################################################### ###############################################################################
# Observations d'apprentissage, de validation et de test # Observations d'apprentissage
vetement = keras.datasets.fashion_mnist # Jeu de données Fashion MNIST m = 1000 # Nombre d'observations
(X, y), (X_test, y_test) = vetement.load_data() bg = 1 # Quantité du bruit gaussien # FIXME : pas en place
X_train, y_train = X[5000:]/255.0 , y[5000:] rayon = 2.5 # Rayon de séparation
X_valid, y_valid = X[:5000]/255.0 , y[:5000] marge = 0.25
classes = ["Tshirt", "Pantalon", "Pull", "Robe", "Manteau", "Sandale", "Chemise", "Basket", "Sac", "Bottine"] x1 = np.empty(m)
x2 = np.empty(m)
y = np.empty(m)
# Go !
j=0
for i in range (round(m/2)-1):
# Première gaussienne
xc1, yc1 = 2, 2
sigma1 = 0.5
x1[j] = np.random.normal(xc1, sigma1)
x2[j] = np.random.normal(xc1, sigma1)
y[j] = 1
j+=1
# Deuxième gaussienne
xc2, yc2 = -2, -2
sigma2 = 0.5
x1[j] = np.random.normal(xc2, sigma2)
x2[j] = np.random.normal(xc2, sigma2)
y[j] = 0
j+=1
# Split en observations d'entrainement et de validation
test_size=0.1 # Ratio du lot de test
m_train = int(np.round(m*(1-test_size)))
x1_train, x2_train, y_train = x1[:m_train], x2[:m_train], y[:m_train] # Jeu d'entrainement
x1_valid, x2_valid, y_valid = x1[m_train:], x2[m_train:], y[m_train:] # Jeu de validation
X_train = np.c_[x1_train, x2_train]
X_valid = np.c_[x1_valid, x2_valid]
# Plots
donnees_ax.plot(x1_train[y_train==1], x2_train[y_train==1], "o", markerfacecolor="tab:blue", markeredgecolor='white', markeredgewidth=0.75)
donnees_ax.plot(x1_train[y_train==0], x2_train[y_train==0], "o" , markerfacecolor="tab:orange", markeredgecolor='white', markeredgewidth=0.75)
donnees_ax.plot(x1_valid[y_valid==1], x2_valid[y_valid==1], "o", markerfacecolor='tab:blue', markeredgecolor='black')
donnees_ax.plot(x1_valid[y_valid==0], x2_valid[y_valid==0], "o", markerfacecolor='tab:orange', markeredgecolor='black')
# Nouvelles observations
m_new = 100 # Résolution par axes
x1_new=np.linspace(-6, 6, m_new).reshape(-1, 1)
x2_new=np.linspace(-6, 6, m_new).reshape(-1, 1)
x1_new_mg, x2_new_mg = np.meshgrid(x1_new, x2_new)
X_new = np.c_[x1_new_mg.ravel(), x2_new_mg.ravel()]
############################################################################### ###############################################################################
# Phase d'apprentissage # Phase d'apprentissage
############################################################################### ###############################################################################
n = 30 # Nombre d'itérations (valeur par défaut : 30 , hyperparamètre) n = 50 # Nombre d'itérations (valeur par défaut : 40 , hyperparamètre)
eta = 0.01 # Taux d'appentissage (valeur par défaut dans Keras : 0.01, 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) 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) # perte="sparse_categorical_crossentropy" # Type de perte (hyperparamètre)
perte="mse" # Type de perte (hyperparamètre)
# perte='mean_absolute_error'
keras.backend.clear_session() keras.backend.clear_session()
# np.random.seed(42)
# tf.random.set_seed(42)
model = keras.models.Sequential() # Modèle de reseau de neurones 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(2, input_dim=2, activation="relu")) # Couche 1 : 2 nodes
model.add(keras.layers.Dense(300, activation="relu")) # Couche 1 : 300 nodes model.add(keras.layers.Dense(1, activation="sigmoid")) # Couche de sortie : 1 node par classe
# 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) optimiseur=keras.optimizers.SGD(learning_rate= eta)
model.compile(loss=perte, optimizer=optimiseur, metrics=["accuracy"]) # Compilation du modèle model.compile(loss=perte, optimizer=optimiseur, metrics=["accuracy"]) # Compilation du modèle
@ -114,20 +146,8 @@ apts = model.fit(X_train, y_train, epochs=n, batch_size=lot, validation_data=(X_
# Phase d'inférence # Phase d'inférence
############################################################################### ###############################################################################
# X_new=[] y_predict=model.predict(X_new) # Prédiction
# y_new=[] y_predict_map = y_predict.reshape(x1_new_mg.shape)
# 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 # Résultats
@ -147,20 +167,21 @@ 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['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['accuracy'], 'b:', label="Précision - entrainement")
apts_ax.plot(apts.epoch, apts.history['val_accuracy'], 'r:', label="Précision - validation") apts_ax.plot(apts.epoch, apts.history['val_accuracy'], 'r:', label="Précision - validation")
apts_ax.set(ylim=(0, 1)) apts_ax.set(ylim=(-0.05, 1.05))
apts_ax.set_xlabel("Époque") apts_ax.set_xlabel("Époque")
apts_ax.legend() apts_ax.legend()
# Prédictions # Plot des données
for i in range (8): donnees_ax.set_title("Données")
for j in range (4): new_colors = ["tab:orange", "white", "tab:blue"]
img_ax[j][i].imshow(X_new[i*2+j], cmap="binary", interpolation="nearest") new_cmap = LinearSegmentedColormap.from_list("mycmap", new_colors) # FIXME : faire un dégradé
img_ax[j][i].set_axis_off() cc = donnees_ax.contourf(x1_new_mg, x2_new_mg, y_predict_map, cmap=new_cmap)
if y_new[i*2+j] == y_new_test[i*2+j]: donnees_ax.set_xticks([-5,0,5])
img_ax[j][i].set_title(classes[y_new[i*2+j]], fontsize=10) donnees_ax.set_yticks([-5,0,5])
else: donnees_ax.set_xlabel(r'$x_1$')
img_ax[j][i].set_title(classes[y_new[i*2+j]], fontsize=10, color="red") donnees_ax.set_ylabel(r'$x_2$', rotation=0)
donnees_ax.set(xlim=(-5.25, 5.25), ylim=(-5.25, 5.25))
fig.colorbar(cc, ax=donnees_ax)
plt.show() plt.show()
# Performances # Performances

View File

@ -16,4 +16,9 @@
![capture d'écran](img/04-keras-tf_playground-xor.png) ![capture d'écran](img/04-keras-tf_playground-xor.png)
### Réseaux de neurones avec Keras - Classificateur : Points sur des gaussiennes
![capture d'écran](img/05-keras-tf_playground-gauss.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 KiB