No account yet ?
Converting dataset to numpy array :
We need to convert our images to arrays of values that will be stacked.
The neural network only works with tensors.
The value tensors correspond to the color intensities of the 3 different RGB channels which correspond to each pixel which makes up each image.
We thus have a numpy file per class.
We have 3 matrices that correspond to our 3 RGB color channels, which are stacked to form a Tensor of order 3.
Tensors
Gradient descent:
The neural network will make predictions, from an input via its different types of superimposed layers.
It is during training that he will learn, make mistakes, and in particular self-adjust via the stage of backpropagation of the gradient (backpropagation).
The gradient descent algorithm will make it possible to minimize the cost function, also called the objective or loss function.
The goal of this algorithm is to seek to solve the following function:
Ax = B, or:
A is is an input matrix
x is a set of variables contained in a tensor which represents the set of weights of the neural network
B is an output vector of the labels
Degrees of a tensor
Deg 0 : it is a scalar product
Deg 1 : it is a vector
Deg 2 : it is a matrix
Deg 3 : this is a matrix stack, a kind of 3D matrix. This is what we send to our neural network
The gradient descent algorithm will make it possible to minimize the cost function, also called the objective or loss function.
The goal of this algorithm is to seek to solve the following function:
Ax = B, or:
A is is an input matrix
x is a set of variables contained in a tensor which represents the set of weights of the neural network
B is an output vector of the labels
Pre-processing of data :
We will generate two different types of dataset from our Numpy files, the training dataset and the validation dataset.
the training Dataset will allow our network to learn and extract distinct characteristics from each of our images.
Validation dataset will be used to validate the model at the end of each iteration during training.
Indeed, by showing new images to our network, it will allow it to recalibrate to avoid over-learning the images of the training dataset.
It will be necessary to respect a certain ratio between these two sets of data.
From our original dataset, we recover 80 to 90% of the data for the training dataset, and therefore 10 to 20% for the validation dataset.
Our convolutional network will have as input a tensor of the following dimension:
( n, w, h, c )
n: total number of images in our dataset
w: width in pixels of our images
h: height in pixels of our images
c: number of channels of our images. Therefore corresponds to 1 for black & white, and 3 for color entries.
It will therefore be necessary to be careful to reshape (reshape) our data by recovering them from our numpy files.
Creation of the model :
We must respect templates concerning the stacking of the different layers:
[ [Conv -> ReLU]*n -> Pool ] *q -> [FC -> ReLU]*k -> FC -> Softmax
Conv: convolution layer
ReLU: activation function, Rectified Linear Unit
Pool: convolution layer
FC: layer of fully connected neurons
Softmax: multiple output activation function
Model training:
The neural network learns.
This will be reinforced as the iterations that your model goes through on your data set, thus becoming better.
Make a prediction:
The model is now trained and we will finally be able to make predictions on new images.
We load the model into memory.
We transform the image in jpg format to a numpy array, then we reshape its dimension.
We have at output an array of 5 values, corresponding to the 5 neurons of the output layer of the model, and therefore to our 5 classes of images.
We will have for each class a percentage concerning its prediction.
We take the highest value of the 5, which therefore corresponds to the prediction made by our model.
Testing our model on an entire dataset:
Now that we have a model, we want to know how it will behave on large amounts of new data.
We will recreate a dataset of new images, which our network will never have seen before, to allow us to better predict how our network will behave in production.
The larger the new dataset, the more we will have a precise idea of the behavior of your neural network.
The purpose of the matrix will allow us to highlight any errors.
Code source du tutoriel de https://deeplylearning.fr/cours-pratiques-deep-learning/reconnaissance-dimages/ qui permet de creer avec Tensorflow et Keras une reconnaissance d'image entre 5 types de fleurs différentes, avec des algorithmes de deep learning.
Image-classification - GitHub
Tested in Anaconda and Python 3.7
# IMPORT import os from PIL import Image import numpy as np from tqdm import tqdm """ # Classe permettant de convertir notre dataset d'images en tableaux Numpy """ def launchConversion(pathData, pathNumpy, resizeImg, imgSize): """ # Permet de lancer la conversion des images en tableau numpy :param pathData: chemin ou sont les :param pathNumpy: :param resizeImg: :param imgSize: """ #Pour chaque classe for flowerClasse in os.listdir(pathData): pathFlower = pathData + '\\' + flowerClasse imgs = [] #Pour chaque image d'une classe, on la charge, resize et transforme en tableau for imgFlower in tqdm(os.listdir(pathFlower), "Conversion de la classe : '{}'".format(flowerClasse)): imgFlowerPath = pathFlower + '\\' + imgFlower img = Image.open(imgFlowerPath) img.load() if resizeImg == True: img = img.resize(size=imgSize) data = np.asarray(img, dtype=np.float32) imgs.append(data) #Converti les gradients de pixels (allant de 0 à 255) vers des gradients compris entre 0 et 1 imgs = np.asarray(imgs) / 255. #Enregistre une classe entiere en un fichier numpy np.save(pathNumpy + '\\ ' + flowerClasse + '.npy', imgs) def main(): """ # Fonction main """ pathNumpy = '.\\numpy' pathData = '.\\dataset' resizeImg = True imgSize = (50, 50) launchConversion(pathData, pathNumpy, resizeImg, imgSize) if __name__ == '__main__': """ # MAIN """ main()
Tested in Anaconda and Python 3.7
# IMPORT import numpy as np import os import keras from sklearn.model_selection import train_test_split from keras.models import Sequential from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D from keras.utils import to_categorical from keras.callbacks import EarlyStopping, ModelCheckpoint, CSVLogger from keras.optimizers import * from keras import regularizers """ # Classe permettant d'entrainer un modèle sur une jeu de données """ def get_labels(path): """ # Permet de recuperer les labels de nos classe, leurs indices dans le tableau et leur matrix binaire one hot encoder :param path: chemin ou sont stocké nos fichiers Numpy """ labels = [file.replace('.npy', '') for file in os.listdir(path) if file.endswith('.npy')] label_indices = np.arange(0, len(labels)) return labels, label_indices, to_categorical(label_indices) def get_train_test(train_ratio, pathData): """ # Retourner le dataset melanger en dataset d'entrainement et de validation selon un ratio :param train_ratio: permet de gerer la part entre dataset de train et de validation :param pathData: chemin des fichiers numpy """ labels, _, _ = get_labels(pathData) classNumber = 0 #On init avec le premier tableau pour avoir les bonnes dimensions pour la suite X = data = np.load(pathData + '\\' + labels[0] + '.npy') Y = np.zeros(X.shape[0]) dimension = X[0].shape classNumber += 1 #On ajoute le reste des fichiers numpy de nos classes for i, label in enumerate(labels[1:]): data = np.load(pathData + '\\' + label + '.npy') X = np.vstack((X, data)) Y = np.append(Y, np.full(data.shape[0], fill_value=(i+1))) classNumber += 1 X_train, X_test, Y_train, Y_test = train_test_split(X, Y, train_size=train_ratio) return X_train, X_test, to_categorical(Y_train), to_categorical(Y_test), classNumber, dimension def main(): """ # Fonction main """ #Definition des chemins et autres variables pathData = '.\\numpy' trainRatio = 0.8 epochs = 1000 batch_size = 16 earlyStopPatience = 5 #Definition des callbacks #Permet de retourner 4 metrics de suivi a chaque iteration csv_logger = CSVLogger('.\\logs\\log_moModel.csv', append=True, separator=',') #Permet de stopper l'entrainement quand le modèle n'entraine pluss early = EarlyStopping(monitor='val_loss', min_delta=0, patience=earlyStopPatience, verbose=0, mode='auto') #Permet de sauvegarder le model a chaque iteration si il est meilleur que le precedent check = ModelCheckpoint('.\\trainedModel\\moModel.hdf5', monitor='val_loss', verbose=0, save_best_only=True, save_weights_only=False, mode='auto') #Recuperation de nos data pré traité x_train, x_test, y_train, y_test, classNumber, dimension = get_train_test(trainRatio, pathData) #On verifie les dimensions de nos données print('DIMENSION X TRAIN ' + str(x_train.shape)) print('DIMENSION X TEST ' + str(x_test.shape)) print('DIMENSION Y TRAIN ' + str(y_train.shape)) print('DIMENSION Y TEST ' + str(y_test.shape)) #On creer le modele model = Sequential() model.add(Conv2D(32, kernel_size=(2, 2), activation='relu', input_shape=(dimension[0], dimension[1], dimension[2]))) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(128, activation='relu')) model.add(Dropout(0.25)) model.add(Dense(classNumber, activation='softmax')) #On compile le modele model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adamax(lr=0.001, beta_1=0.9, beta_2=0.999, decay=0.0), metrics=['accuracy']) #On lance l'entrainement du modele trainning = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, validation_data=(x_test, y_test), callbacks=[early, check,csv_logger]) if __name__ == "__main__": """ # MAIN """ main()
Tested in Anaconda and Python 3.7
# IMPORT import matplotlib.pyplot as plt import pandas as pd """ # Classe permettant de génerer 4 graphiques de suivit de métriques durant l'entrainement d'un modèle # Train accuracy, Train loss, Validation accuracy, Validation loss """ def displayGraph(pathLog,pathSaveGraph): """ # Fonction permettant de creer nos graph de suivi de metriques :param pathLog: chemin du CSV contenant nos metrics :param pathSaveGraph: chemin de destination pour sauvegarder nos 4 graphiques en jpg """ data = pd.read_csv(pathLog) # split into input (X) and output (Y) variables plot(data['epoch'], data['acc'], data['val_acc'], 'TRAIN_VAL_Accuracy', 'Epoch', 'Accuracy', 'upper left',pathSaveGraph) plot(data['epoch'], data['loss'], data['val_loss'], 'TRAIN_VAL_Loss', 'Epoch', 'Loss', 'upper left',pathSaveGraph) def plot(X, Y, Y2, title, xLabel, yLabel, legendLoc, pathSaveGraph): """ # Fonction d'affichage de graph :param X: correspond au nombre d'époch :param Y: correspond a la courbe accuracy :param Y2: correspond a la courbe loss :param title: titre du graphique :param xLabel: label des abcisses :param yLabel: label des ordonnees :param legendLoc: legende :param pathSaveGraph: chemin de sauvegarde pour les graphiques """ #On trace nos differentes courbes plt.plot(Y) plt.plot(Y2) #titre du graph, legende... plt.title(title) plt.xlabel(xLabel) plt.ylabel(yLabel) plt.legend(['train', 'val'], loc=legendLoc) #Pour avoir un courbe propre qui demarre à 0 plt.xlim(xmin=0.0, xmax=max(X)) plt.savefig(pathSaveGraph +'\\' + title) plt.figure() #plt.show() def main(): """ # Fonction main """ #Definition des chemins d'acces a notre fichier log pathLogs = '.\\logs\\log_moModel.csv' pathSaveGraph = '.\\graph' displayGraph(pathLogs,pathSaveGraph) if __name__ == "__main__": """ # MAIN """ main()
Tested in Anaconda and Python 3.7
# IMPORT import matplotlib.pyplot as plt from tqdm import tqdm import os from PIL import Image import numpy as np from sklearn.metrics import confusion_matrix import itertools from keras.models import load_model """ # Classe permettant de génerer une matrice de confusion à partir d'un dataset de test et d'un modèle entrainé # au préalable """ def generateMatrix(model, datasetTestPath, imageSize, destinationMatrix): """ # Fonction qui va construire notre matrice de confusion :param model: chemin du modèle à charger pour realiser la prediction :param datasetTestPath: chemin du dataset contenant nos images de test :param imageSize: definit la taille de l'ensemble de nos images :param destinationMatrix: définit le chemin ou va être sauvegardé notre matrice sous format d'image :return: """ #Les tableaux contenanrt les predictions y_true = [] y_pred = [] total = 0 success = 0 index = 0 print('\nEvaluation :') #On parcours notre dataset de test for root, dirs, files in os.walk(datasetTestPath): for mydir in dirs: for sample in tqdm(os.listdir(root + '\\' + mydir), "Prediction de la classe '{}'".format(mydir)): sample_path = root + '\\' + mydir + '\\' + sample #Chargement et traitement de l'image img = Image.open(sample_path) img.load() img = img.resize(size=imageSize) img = np.asarray(img) / 255. #On reshape pour etre de la forme (nbImage,hauteurImage,largeurImage,nbCanaux) img = img.reshape(1, img.shape[0], img.shape[1], img.shape[2]) #Prediction de notre modele pred = np.argmax(model.predict(img)) total += 1 if pred == index: success += 1 y_true.append(index) y_pred.append(pred) index += 1 #Precision de notre modele sur notre jeu de test en entier accuracy = (success / total) * 100. print('\nPrecision : {0:.3f}%'.format(accuracy)) cnf_matrix = confusion_matrix(y_true, y_pred) np.set_printoptions(precision=2) # Plot normalized confusion matrix plt.figure() cmap = plt.cm.Blues classes = ['marguerite', 'pissenlit', 'rose', 'tournesol', 'tulipe'] title = 'Confusion matrix' cnf_matrix = cnf_matrix.astype('float') / cnf_matrix.sum(axis=1)[:, np.newaxis] #Legende de notre matrice plt.imshow(cnf_matrix, interpolation='nearest', cmap=cmap) plt.title(title) plt.colorbar() tick_marks = np.arange(len(classes)) plt.xticks(tick_marks, classes, rotation=45) plt.yticks(tick_marks, classes) fmt = '.2f' thresh = cnf_matrix.max() / 2. for i, j in itertools.product(range(cnf_matrix.shape[0]), range(cnf_matrix.shape[1])): plt.text(j, i, format(cnf_matrix[i, j], fmt), horizontalalignment="center", color="white" if cnf_matrix[i, j] > thresh else "black") plt.ylabel('True label') plt.xlabel('Predicted label') plt.tight_layout() #On sauvegarde notre matrice en image plt.savefig(destinationMatrix + '\\' + 'confusionMatrix') def main(): """ # Fonction main """ #On definit les chemins de nos divers ressources modelPath = '.\\trainedModel\\moModel.hdf5' datasetTestPath = '.\\datasetTest' destinationMatrix = '.\\graph' imageSize = (50, 50) model = load_model(modelPath) generateMatrix(model, datasetTestPath, imageSize, destinationMatrix) if __name__ == "__main__": """ # MAIN """ main()
Tested in Anaconda and Python 3.7
#IMPORT from keras.models import load_model from PIL import Image import numpy as np import time """ # Classe permettant de réaliser une prédiction sur une nouvelle donnée """ def main(): """ # On definit les chemins d'acces au différentes hyper parametre """ modelPath = '.\\trainedModel\\moModel.hdf5' imagePath = '.\\testImage\\rose.jpg' imageSize = (50,50) label = ['marguerite', 'pissenlit', 'rose', 'tournesol', 'tulipe'] predict(modelPath, imagePath,imageSize, label) def predict(modelPath,imagePath, imageSize, label): """ # Fonction qui permet de convertir une image en array, de charger le modele et de lui injecter notre image pour une prediction :param modelPath: chemin du modèle au format hdf5 :param imagePath: chemin de l'image pour realiser une prediction :param imageSize: défini la taille de l'image. IMPORTANT : doit être de la même taille que celle des images du dataset d'entrainements :param label: nom de nos 5 classes de sortie """ start = time.time() # Chargement du modele print("Chargement du modèle :\n") model = load_model(modelPath) print("\nModel chargé.") #Chargement de notre image et traitement data = [] img = Image.open(imagePath) img.load() img = img.resize(size=imageSize) img = np.asarray(img) / 255. data.append(img) data = np.asarray(data) #On reshape pour correspondre aux dimensions de notre modele # Arg1 : correspond au nombre d'image que on injecte # Arg2 : correspond a la largeur de l'image # Arg3 : correspond a la hauteur de l'image # Arg4 : correspond au nombre de canaux de l'image (1 grayscale, 3 couleurs) dimension = data[0].shape #Reshape pour passer de 3 à 4 dimension pour notre réseau data = data.astype(np.float32).reshape(data.shape[0], dimension[0], dimension[1], dimension[2]) #On realise une prediction prediction = model.predict(data) #On recupere le numero de label qui a la plus haut prediction maxPredict = np.argmax(prediction) #On recupere le mot correspondant à l'indice precedent word = label[maxPredict] pred = prediction[0][maxPredict] * 100. end = time.time() #On affiche les prédictions print() print('----------') print(" Prediction :") for i in range(0, len(label)): print(' ' + label[i] + ' : ' + "{0:.2f}%".format(prediction[0][i] * 100.)) print() print('RESULTAT : ' + word + ' : ' + "{0:.2f}%".format(pred)) print('temps prediction : ' + "{0:.2f}secs".format(end-start)) print('----------') if __name__ == "__main__": """ # MAIN """ main()
The handwritten digit classifier: The MNIST dataset
Tested in Anaconda and Python 3.7
from sklearn.datasets import fetch_openml import numpy as np from matplotlib import pyplot as plt X, y = fetch_openml('mnist_784', version=1, return_X_y=True) X = X.to_numpy() y = y.astype(int) X_img = np.reshape(X,(X.shape[0],28*28)) #Recuperation du nombre d'exemples d'apprentissage ainsi que la dimension des vecteurs n_samples = X.shape[0] print("Nombre d'exemples d'apprentissage n_samples = %d " % n_samples) def plotImg(X): plt.figure(figsize=(7.195, 3.841), dpi=100) for i in range(200): plt.subplot(10,20,i+1) plt.imshow(X[i,:].reshape([28,28]), cmap='gray') plt.axis('off') plt.show() plt.close() plotImg(X_img) n_classes = np.max(y) + 1 print("Nombre de classes d'objets n_classes = %d " % n_classes)
Visualization of a representative example of the dataset
The classification has two phases, a learning phase and an evaluation phase.
In the training phase, the classifier trains its model on a given set of data and in the evaluation phase, it tests the performance of the classifier.
Performance is evaluated on the basis of various parameters such as correctness, error, precision and recall.
Welcome, my name is Eric Soupet and I am the administrator of the site elodees.com. elodees.com is a state of the art of Artificial Intelligence and aims to be collaborative, you can now offer content such as articles, events, tutorials, ... so don't hesitate !
Platform images credit : Pixabay - Pixabay License | Pexels - Pexels License