Keras : classificateur XOR

This commit is contained in:
Philippe Roy 2023-06-28 02:27:43 +02:00
parent 7c954a1d5b
commit 90c6c581d2
3 changed files with 42 additions and 33 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
@ -74,9 +76,9 @@ donnees_ax = fig.add_subplot(133) # Observations : x1,x2 et cibles : y
# Observations # Observations
############################################################################### ###############################################################################
# Observations # Observations d'apprentissage
m = 1000 # Nombre d'observations m = 1000 # Nombre d'observations
bg = 1 # Quantité du bruit gaussien bg = 1 # Quantité du bruit gaussien # FIXME : pas en place
x1 = np.random.uniform(-5,5, m) # Liste des observations x1 x1 = np.random.uniform(-5,5, m) # Liste des observations x1
x2 = np.random.uniform(-5,5, m) # Liste des observations x2 x2 = np.random.uniform(-5,5, m) # Liste des observations x2
y = np.empty(m) # Liste des observations cible (XOR) y = np.empty(m) # Liste des observations cible (XOR)
@ -91,62 +93,57 @@ for i in range (m):
else: else:
y[i]=1 y[i]=1
# Split en observations d'entrainement et observations de test # Split en observations d'entrainement et de validation
test_size=0.1 # Ratio du lot de test test_size=0.1 # Ratio du lot de test
m_train = int(np.round(m*(1-test_size))) 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_train, x2_train, y_train = x1[:m_train], x2[:m_train], y[:m_train] # Jeu d'entrainement
x1_test, x2_test, y_test = x1[m_train:], x2[m_train:], y[m_train:] # Jeu de test 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_train = np.c_[x1_train, x2_train]
X_test = np.c_[x1_test, x2_test] X_valid = np.c_[x1_valid, x2_valid]
# Plots # Plots
donnees_ax.plot(x1_train[y_train==1], x2_train[y_train==1], ".", color="tab:blue") 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], "." , color="tab:orange") 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_test[y_test==1], x2_test[y_test==1], "o", markerfacecolor='tab:blue', color="black") donnees_ax.plot(x1_valid[y_valid==1], x2_valid[y_valid==1], "o", markerfacecolor='tab:blue', markeredgecolor='black')
donnees_ax.plot(x1_test[y_test==0], x2_test[y_test==0], "o", markerfacecolor='tab:orange', color="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 = 1000 # Nombre d'itérations (valeur par défaut : 30 , hyperparamètre) n = 200 # Nombre d'itérations (valeur par défaut : 200 , 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="sparse_categorical_crossentropy" # Type de perte (hyperparamètre)
# perte="mse" # Type de perte (hyperparamètre) perte="mse" # Type de perte (hyperparamètre)
perte='mean_absolute_error' # perte='mean_absolute_error'
keras.backend.clear_session() keras.backend.clear_session()
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=[1, 1])) # Couche d'entrée # model.add(keras.layers.Flatten(input_shape=[1, 1])) # Couche d'entrée
model.add(keras.layers.Dense(4, input_dim=2, activation="relu")) # Couche 1 : 4 nodes model.add(keras.layers.Dense(4, input_dim=2, activation="relu")) # Couche 1 : 4 nodes
model.add(keras.layers.Dense(4, activation="relu")) # Couche 2 : 4 nodes model.add(keras.layers.Dense(4, activation="relu")) # Couche 2 : 4 nodes
model.add(keras.layers.Dense(1, activation="relu")) # Couche de sortie : 1 node par classe model.add(keras.layers.Dense(1, activation="sigmoid")) # Couche de sortie : 1 node par classe
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
apts = model.fit(X_train, y_train, epochs=n, batch_size=lot) # Entrainement apts = model.fit(X_train, y_train, epochs=n, batch_size=lot, validation_data=(X_valid, y_valid)) # Entrainement
############################################################################### ###############################################################################
# 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
@ -162,18 +159,25 @@ os.remove("model.png") # Supression du fichier temporaire
# Courbes d'apprentissage # Courbes d'apprentissage
apts_ax.set_title("Courbes d'apprentissage") apts_ax.set_title("Courbes d'apprentissage")
apts_ax.plot(apts.epoch, apts.history['loss'], 'r-', label="Perte - entrainement") 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()
# Plot des données # Plot des données
donnees_ax.set_title("Données") donnees_ax.set_title("Données")
new_colors = ["tab:orange", "white", "tab:blue"]
new_cmap = LinearSegmentedColormap.from_list("mycmap", new_colors) # FIXME : faire un dégradé
cc = donnees_ax.contourf(x1_new_mg, x2_new_mg, y_predict_map, cmap=new_cmap)
donnees_ax.set_xticks([-5,0,5])
donnees_ax.set_yticks([-5,0,5])
donnees_ax.set_xlabel(r'$x_1$') donnees_ax.set_xlabel(r'$x_1$')
donnees_ax.set_ylabel(r'$x_2$', rotation=0) 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)
# donnees_ax.legend() # donnees_ax.legend()
plt.show() plt.show()

View File

@ -8,3 +8,8 @@
![capture d'écran](img/02-keras-classificateur_img.png) ![capture d'écran](img/02-keras-classificateur_img.png)
### Réseaux de neurones avec Keras - Classificateur : Ou exclusif (XOR)
![capture d'écran](img/04-keras-tf_playground-xor.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 608 KiB