diff --git a/03-vision/01-digit-prepa_data.py b/03-vision/01-digit-prepa_data.py new file mode 100644 index 0000000..5d62fab --- /dev/null +++ b/03-vision/01-digit-prepa_data.py @@ -0,0 +1,223 @@ +import os, time, random +import numpy as np +import matplotlib.pyplot as plt + +import tensorflow as tf +from tensorflow import keras + +############################################################################### +# 01-digit_simple.py +# @title: Vision par ordinateur - Reconnaissance de digit - Réseaux de neurones simples +# @project: Mes scripts de ML +# @lang: fr +# @authors: Philippe Roy +# @copyright: Copyright (C) 2023 Philippe Roy +# @license: GNU GPL +############################################################################### + +### +# 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) +# - model.add : ajout d'une couche +# - keras.layers.Flatten : couche de formatage de mise à plat +# - keras.layers.Dense : couche de neurones +# - keras.backend.clear_session() : reset de la session +# - model.compile : compilation du modèle +# - model.fit : entrainement du modèle +# - model.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(layout="constrained", figsize=(15, 5)) +fig = plt.figure(layout="constrained", figsize=(20, 7)) +fig.suptitle("Vision par ordinateur - Reconnaissance de digit par réseaux de neurones simples") +# subfigs = fig.subfigures(1, 3) +# model_ax = subfigs[0].subplots(1, 1) +# apts_ax = subfigs[1].subplots(1, 1) +# img_ax = subfigs[2].subplots(8, 10) +img_ax = fig.subplots(10, 30) + + + +############################################################################### +# Observations +############################################################################### + +# Observations d'apprentissage, de validation et de test + +chiffre = keras.datasets.mnist # Jeu de données MNIST (digit) +# train_filter = np.unique(Y_train, return_index=True) +# X_train, Y_train = X_train[train_filter[1:]], Y_train[train_filter[1:]] +(X, y), (X_test, y_test) = chiffre.load_data() +X_train, y_train = X[5000:]/255.0 , y[5000:] +X_valid, y_valid = X[:5000]/255.0 , y[:5000] +classes = [0,1,2,3,4,5,6,7,8,9] + +# ############################################################################### +# # Phase d'apprentissage +# ############################################################################### + +# n = 2 # 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(100, activation="relu")) # Couche 2 : 100 nodes -> ajout +# model.add(keras.layers.Dense(10, activation="softmax")) # Couche de sortie : 1 node par classe soit 10 + +# 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 +############################################################################### + +print ("\n") +print ("Test sur les 80 images différentes sur un jeu de 10 000 images.") + +# X_new = np.empty([80, 28, 28]) +# y_new_test = np.empty(80) +# for i_new in range(80): +# # print ("i_new ", i_new ) + +# # Boucle de remplissage +# deja_present=True +# while deja_present == True: +# idx = np.random.randint(X_test.shape[0]) # Index aléatoire +# # print ("idx ", idx ) +# X_idx = X_test[idx] + +# # Comparaison de chaque images présentes avec image idx +# deja_present_unitaire=[] +# for i_img in range (80): +# # print ("i_img ", i_img ) +# deja_present_unitaire.append(True) +# for j in range (28): +# for k in range (28): +# if X_new[i_img][j][k] != X_idx[j][k]: +# deja_present_unitaire[i_img]=False + +# # Test sur l'ensemble des images +# deja_present=False +# for i_img in range (80): +# if deja_present_unitaire[i_img]==True: +# deja_present = True + +# # Ajout de la nouvelle image idx +# X_new[i_new]=X_test[idx] +# y_new_test[i_new] = y_test[idx] +# print ("ajout ", i_new, idx) + +# FIXME : ne marche pas -> à faire à la main + +# (X_train, Y_train), (X_test, Y_test) = tf.keras.datasets.mnist.load_data() +# train_filter = np.unique(Y_train, return_index=True) +# X_train, Y_train = X_train[train_filter[1:]], Y_train[train_filter[1:]] + +X_new_unique = np.unique(X_test, axis=0, return_index=True) + +# X_new = np.empty([80, 28, 28]) +# y_new_test = np.empty(80) +# new_unique = random.sample(list(X_new_unique_i), 80) +# for i in range(80): +# X_new[i]=X_test[new_unique[i]] +# y_new_test[i] = y_test[new_unique[i]] + +# X_new_idx = np.empty(80) +# for i in range(80): + +# # Vérification que l'index aléatoire n'a pas été +# idx_unique= False +# while idx_unique ==False : +# idx_unique= True +# idx = np.random.randint(len(test_filter[1])) # Index aléatoire +# for j in range (80): +# if X_new_idx[j] == idx: +# idx_unique= False + + +# X_new[i]=X_test[idx] +# y_new_test[i] = y_test[idx] + +# y_new = np.argmax(model.predict(X_new), axis=-1) +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 (10): +# for j in range (8): +# 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") + +# Prédictions +k=0 +for i in range (10): # Ligne + for j in range (30): # Colonne + img_ax[i][j].imshow(X_test[k], cmap="binary", interpolation="nearest") + img_ax[i][j].set_axis_off() + img_ax[i][j].set_title(str(k)+" : "+str(y_test[k]), fontsize=10) + k+=1 + +plt.show() + + +# Performances +print ("Temps total : "+str(time.time()-t_debut)) diff --git a/03-vision/01-digit-simple.py b/03-vision/01-digit-simple.py new file mode 100644 index 0000000..5d62fab --- /dev/null +++ b/03-vision/01-digit-simple.py @@ -0,0 +1,223 @@ +import os, time, random +import numpy as np +import matplotlib.pyplot as plt + +import tensorflow as tf +from tensorflow import keras + +############################################################################### +# 01-digit_simple.py +# @title: Vision par ordinateur - Reconnaissance de digit - Réseaux de neurones simples +# @project: Mes scripts de ML +# @lang: fr +# @authors: Philippe Roy +# @copyright: Copyright (C) 2023 Philippe Roy +# @license: GNU GPL +############################################################################### + +### +# 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) +# - model.add : ajout d'une couche +# - keras.layers.Flatten : couche de formatage de mise à plat +# - keras.layers.Dense : couche de neurones +# - keras.backend.clear_session() : reset de la session +# - model.compile : compilation du modèle +# - model.fit : entrainement du modèle +# - model.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(layout="constrained", figsize=(15, 5)) +fig = plt.figure(layout="constrained", figsize=(20, 7)) +fig.suptitle("Vision par ordinateur - Reconnaissance de digit par réseaux de neurones simples") +# subfigs = fig.subfigures(1, 3) +# model_ax = subfigs[0].subplots(1, 1) +# apts_ax = subfigs[1].subplots(1, 1) +# img_ax = subfigs[2].subplots(8, 10) +img_ax = fig.subplots(10, 30) + + + +############################################################################### +# Observations +############################################################################### + +# Observations d'apprentissage, de validation et de test + +chiffre = keras.datasets.mnist # Jeu de données MNIST (digit) +# train_filter = np.unique(Y_train, return_index=True) +# X_train, Y_train = X_train[train_filter[1:]], Y_train[train_filter[1:]] +(X, y), (X_test, y_test) = chiffre.load_data() +X_train, y_train = X[5000:]/255.0 , y[5000:] +X_valid, y_valid = X[:5000]/255.0 , y[:5000] +classes = [0,1,2,3,4,5,6,7,8,9] + +# ############################################################################### +# # Phase d'apprentissage +# ############################################################################### + +# n = 2 # 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(100, activation="relu")) # Couche 2 : 100 nodes -> ajout +# model.add(keras.layers.Dense(10, activation="softmax")) # Couche de sortie : 1 node par classe soit 10 + +# 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 +############################################################################### + +print ("\n") +print ("Test sur les 80 images différentes sur un jeu de 10 000 images.") + +# X_new = np.empty([80, 28, 28]) +# y_new_test = np.empty(80) +# for i_new in range(80): +# # print ("i_new ", i_new ) + +# # Boucle de remplissage +# deja_present=True +# while deja_present == True: +# idx = np.random.randint(X_test.shape[0]) # Index aléatoire +# # print ("idx ", idx ) +# X_idx = X_test[idx] + +# # Comparaison de chaque images présentes avec image idx +# deja_present_unitaire=[] +# for i_img in range (80): +# # print ("i_img ", i_img ) +# deja_present_unitaire.append(True) +# for j in range (28): +# for k in range (28): +# if X_new[i_img][j][k] != X_idx[j][k]: +# deja_present_unitaire[i_img]=False + +# # Test sur l'ensemble des images +# deja_present=False +# for i_img in range (80): +# if deja_present_unitaire[i_img]==True: +# deja_present = True + +# # Ajout de la nouvelle image idx +# X_new[i_new]=X_test[idx] +# y_new_test[i_new] = y_test[idx] +# print ("ajout ", i_new, idx) + +# FIXME : ne marche pas -> à faire à la main + +# (X_train, Y_train), (X_test, Y_test) = tf.keras.datasets.mnist.load_data() +# train_filter = np.unique(Y_train, return_index=True) +# X_train, Y_train = X_train[train_filter[1:]], Y_train[train_filter[1:]] + +X_new_unique = np.unique(X_test, axis=0, return_index=True) + +# X_new = np.empty([80, 28, 28]) +# y_new_test = np.empty(80) +# new_unique = random.sample(list(X_new_unique_i), 80) +# for i in range(80): +# X_new[i]=X_test[new_unique[i]] +# y_new_test[i] = y_test[new_unique[i]] + +# X_new_idx = np.empty(80) +# for i in range(80): + +# # Vérification que l'index aléatoire n'a pas été +# idx_unique= False +# while idx_unique ==False : +# idx_unique= True +# idx = np.random.randint(len(test_filter[1])) # Index aléatoire +# for j in range (80): +# if X_new_idx[j] == idx: +# idx_unique= False + + +# X_new[i]=X_test[idx] +# y_new_test[i] = y_test[idx] + +# y_new = np.argmax(model.predict(X_new), axis=-1) +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 (10): +# for j in range (8): +# 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") + +# Prédictions +k=0 +for i in range (10): # Ligne + for j in range (30): # Colonne + img_ax[i][j].imshow(X_test[k], cmap="binary", interpolation="nearest") + img_ax[i][j].set_axis_off() + img_ax[i][j].set_title(str(k)+" : "+str(y_test[k]), fontsize=10) + k+=1 + +plt.show() + + +# Performances +print ("Temps total : "+str(time.time()-t_debut)) diff --git a/03-vision/01-digit_simple.py b/03-vision/01-digit_simple.py deleted file mode 100644 index e0a2049..0000000 --- a/03-vision/01-digit_simple.py +++ /dev/null @@ -1,146 +0,0 @@ -import os, time -import numpy as np -import matplotlib.pyplot as plt - -import tensorflow as tf -from tensorflow import keras - -############################################################################### -# 01-digit_simple.py -# @title: Vision par ordinateur - Reconnaissance de digit - Réseaux de neurones simples -# @project: Mes scripts de ML -# @lang: fr -# @authors: Philippe Roy -# @copyright: Copyright (C) 2023 Philippe Roy -# @license: GNU GPL -############################################################################### - -### -# 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) -# - model.add : ajout d'une couche -# - keras.layers.Flatten : couche de formatage de mise à plat -# - keras.layers.Dense : couche de neurones -# - keras.backend.clear_session() : reset de la session -# - model.compile : compilation du modèle -# - model.fit : entrainement du modèle -# - model.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(layout="constrained", figsize=(15, 5)) -fig.suptitle("Vision par ordinateur - Reconnaissance de digit par réseaux de neurones simples") -subfigs = fig.subfigures(1, 3) -model_ax = subfigs[0].subplots(1, 1) -apts_ax = subfigs[1].subplots(1, 1) -img_ax = subfigs[2].subplots(8, 10) - -############################################################################### -# Observations -############################################################################### - -# Observations d'apprentissage, de validation et de test -chiffre = keras.datasets.mnist # Jeu de données MNIST (digit) -(X, y), (X_test, y_test) = chiffre.load_data() -X_train, y_train = X[5000:]/255.0 , y[5000:] -X_valid, y_valid = X[:5000]/255.0 , y[:5000] -classes = [0,1,2,3,4,5,6,7,8,9] - -############################################################################### -# Phase d'apprentissage -############################################################################### - -n = 2 # 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(100, activation="relu")) # Couche 2 : 100 nodes -> ajout -model.add(keras.layers.Dense(10, activation="softmax")) # Couche de sortie : 1 node par classe soit 10 - -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 -############################################################################### - -print ("\n") -print ("Test sur les 80 images différentes sur un jeu de 10 000 images.") - -idx = np.random.randint(X_test.shape[0]-80) # Index aléatoire -X_new = X_test[idx:idx+80] -y_new = np.argmax(model.predict(X_new), axis=-1) -y_new_test= y_test[idx:idx+80] - -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 (10): - for j in range (8): - 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/03-vision/02-digit_cnn.py b/03-vision/02-digit-cnn.py similarity index 100% rename from 03-vision/02-digit_cnn.py rename to 03-vision/02-digit-cnn.py