def map(map_shape, data_shape, sigma_max_value, sigma_min_value, eta_max_value, eta_min_value, decay_start_iter, decay_stop_iter, training_samples, initiale): """ crée la carte labélisée par l'algorithme de Kohonen map_shape -- taille de la carte de la forme (lignes, colonnes) data_shape -- taille des vecteurs de la forme (lignes, colonnes) iterations -- nombre d'échantillon utilisés pour entrainer la carte sigma_max_value, sigma_min_value, eta_max_value, eta_min_value, decay_start_iter, decay_stop_iter -- arguments de la mise à jour de la carte training_samples -- tableau des vecteurs utilisés pour entrainer la carte """ ## dimensions des vecteurs de poids neurons_dimension = (np.prod(map_shape), np.prod(data_shape)) ## initialisation des prototypes des vecteurs de poids neurons = np.zeros(neurons_dimension) for i in range(np.prod(map_shape)): neurons[i] = initiale #=============================================================================== # Boucle d'apprentissage suivant l'algorithme de Kohonen #=============================================================================== for curr_iter, sample in enumerate(training_samples): ## récupérer les valeurs de sigma et eta sigma = kohonen.constrainedExponentialDecay( curr_iter, decay_start_iter, decay_stop_iter * len(training_samples), sigma_max_value, sigma_min_value) eta = kohonen.constrainedExponentialDecay( curr_iter, decay_start_iter, decay_stop_iter * len(training_samples), eta_max_value, eta_min_value) ## trouver la best-matching unit (BMU) et son score (plus petite distance) bmu_idx, bmu_score = kohonen.nearestVector(sample, neurons) ## traduire la position 1D de la BMU en position 2D dans la carte bmu_2D_idx = np.unravel_index(bmu_idx, map_shape) ## gaussienne de taille sigma à la position 2D de la BMU gaussian_on_bmu = kohonen.twoDimensionGaussian(map_shape, bmu_2D_idx, sigma) ## mettre à jour les prototypes d'après l'algorithme de Kohonen (fonction à effets de bord) kohonen.updateKohonenNeurons(sample, neurons, eta, gaussian_on_bmu) return neurons
#=============================================================================== eta_var = eta sigma_var = sigma BMU = 0 for curr_iter in range(iterations): ## choisir un indice aléatoirement random_idx = numpy.random.randint(training_samples.shape[0]) ## instancier l'exemple d'apprentissage courant sample = data[random_idx] ## trouver la best-matching unit (BMU) et son score (plus petite distance) bmu_idx, bmu_score = kohonen.nearestVector(sample, weights) BMU = BMU + bmu_score ## traduire la position 1D de la BMU en position 2D dans la carte bmu_2D_idx = (bmu_idx // map_shape[0], bmu_idx % map_shape[0]) ## gaussienne de taille sigma à la position 2D de la BMU gaussian_on_bmu = kohonen.twoDimensionGaussian(map_shape, bmu_2D_idx, sigma) ## mettre à jour les prototypes d'après l'algorithme de Kohonen (fonction à effets de bord) kohonen.updateKohonenWeights(sample, weights, eta, gaussian_on_bmu) #eta = kohonen.constrainedExponentialDecay(curr_iter, 0, iterations, eta, 0.01) #sigma = kohonen.constrainedExponentialDecay(curr_iter, 0, iterations, sigma, 0.01) ## afficher l'itération courante à l'écran if verbose: print('Iteration %d/%d' % (curr_iter + 1, iterations)) #=============================================================================== # Affichage graphique #=============================================================================== weights_reshaped = weights.reshape((map_shape[0], map_shape[1], 28, 28)) img = numpy.zeros((map_shape[0] * 28, map_shape[1] * 28)) for i in range(map_shape[0]): for j in range(map_shape[1]):
def allfunction(): ''' Fonction qui va effectuer tous les calculs d'un coup lors de l'appui du bouton correspondant : CAO, labelling et évaluation. Se référer aux fonctions ainsi nommées, placées plus bas, pour plus de précision. Entrée : pas d'entrée, car fonction sur bouton, on utilise donc des sauvegardes, ici les paramètres rentrés par l'utilisateur (sauf map_shape) ou s'il n'en a pas rentré, les paramètres de base (voir plus bas) Sortie : pas de sortie, le programme sauvegarde uniquement les données de la CAO, ainsi que le résultat de l'évaluation ''' try: #Boucle de sécurité : si le fichier rentré dans le programme n'a pas le bon format ou les bonnes composantes, la fonction ne va rien faire et afficher un message d'erreur sur l'interface graphique. #On charge les données : iterations = numpy.load("iterations.npy") iterations = int( iterations.tolist() ) #Permet de transformer le format des données, car elles sont sauvegardées sous format numpy. sigma = numpy.load("sigma.npy") sigma = float(sigma.tolist()) eta = numpy.load("eta.npy") eta = float(eta.tolist()) sigma_max = numpy.load("sigma_max.npy") sigma_max_value = float(sigma_max.tolist()) sigma_min = numpy.load("sigma_min.npy") sigma_min_value = float(sigma_min.tolist()) eta_max = numpy.load("eta_max.npy") eta_max_value = float(eta_max.tolist()) eta_min = numpy.load("eta_min.npy") eta_min_value = float(eta_min.tolist()) #=============================================================================== # Paramètres concernant les données d'apprentissage #=============================================================================== ## dimension d'un vecteur d'entrée data_shape = (1, 784) ## nombre de classes différentes disponibles data_number = 10 ## dimensions des données data_dimension = (data_number, numpy.prod(data_shape)) ## récupération des données data = training_samples #=============================================================================== # Paramètres concernant la carte auto-organisatrice et l'algorithme de Kohonen #=============================================================================== ## taille de la carte auto-organisatrice (COA) map_shape = (20, 20) numpy.save("map_shape", map_shape) #Sauvegardé car utilisé dans d'autres fonctions. ## dimensions des prototypes de la COA : une carte de MxM' [map_shape] vecteurs de dimension PxP' [data_dimension] weights_dimension = (numpy.prod(map_shape), numpy.prod(data_shape)) ## initialisation aléatoire des prototypes de la COA : distribution uniforme entre 0. et 1. weights = numpy.random.uniform(low=0., high=1., size=weights_dimension) decay_start_iter = 0.2 * iterations decay_stop_iter = 0.6 * iterations ###Kohonen : eta_var = eta sigma_var = sigma sum_bmu = 0 for curr_iter in range(iterations): ## choisir un indice aléatoirement random_idx = numpy.random.randint(training_samples.shape[0]) ## instancier l'exemple d'apprentissage courant sample = data[random_idx] ## trouver la best-matching unit (BMU) et son score (plus petite distance) bmu_idx, bmu_score = kohonen.nearestVector(sample, weights) sum_bmu += bmu_score ## traduire la position 1D de la BMU en position 2D dans la carte bmu_2D_idx = (bmu_idx // map_shape[0], bmu_idx % map_shape[0]) ## gaussienne de taille sigma à la position 2D de la BMU gaussian_on_bmu = kohonen.twoDimensionGaussian( map_shape, bmu_2D_idx, sigma) ## mettre à jour les prototypes d'après l'algorithme de Kohonen (fonction à effets de bord) kohonen.updateKohonenWeights(sample, weights, eta, gaussian_on_bmu) sigma = kohonen.constrainedExponentialDecay( curr_iter, decay_start_iter, decay_stop_iter, sigma_max_value, sigma_min_value) eta = kohonen.constrainedExponentialDecay(curr_iter, decay_start_iter, decay_stop_iter, eta_max_value, eta_min_value) #=============================================================================== # Sauvegarde des données #=============================================================================== numpy.save( "data", weights ) # On en a besoin dans d'autres fonctions (graph par exemple). mean_bmu = sum_bmu / iterations numpy.save( "mean_bmu", mean_bmu ) # De même si on veut refaire le labelling ou encore l'évaluation. ###Labelling : data = weights #changement de nom : ici, la donnée devient invariante W_associated = [ [0 for i in range(10)] for j in range(numpy.shape(data)[0]) ] #Matrice qui va compter les différentes correspondances des données de labelling avec les poids de la CAO. for j in range(labelling_labels.shape[0]): sample = labelling_samples[j] bmu_idx, bmu_score = kohonen.nearestVector(sample, data) if ( bmu_score / mean_bmu ) * 100 < 200: #Test supplémentaire destiné à ne pas compter les cas qui sont trop loin des neurones de la CAO, qui viendrait polluer le labelling. W_associated[bmu_idx][labelling_labels[j]] += 1 W_labels = [0] * numpy.shape(data)[0] for i in range(numpy.shape(data)[0]): if numpy.sum(W_associated[i]) != 0: W_labels[i] = numpy.argmax(numpy.array(W_associated[i])) else: #On ne pas mettre une étiquette sur les neuronnes qui n'ont pas été utilisés dans le labelling. W_labels[ i] = -1 #Coefficient qui indique que l'on ne pourra pas utiliser ce neurone pour les évaluations. numpy.save("labels", W_labels) ###Évaluation : #Paramètres permettant de rendre compte de l'efficacité de la CAO analysée. exclus = 0 rendu = 0 fail = 0 for j in range(testing_labels.shape[0]): sample = testing_samples[j] bmu_idx, bmu_score = kohonen.nearestVector(sample, data) label_predicted = W_labels[bmu_idx] real_label = testing_labels[j] if W_labels[ bmu_idx] != -1 and bmu_score / mean_bmu < 2: #Dernier critère supplémentaire : les données qui sont trop loin de tous les neurones utilisés seront rejetés. if real_label == label_predicted: rendu = rendu + 1 else: fail += 1 else: exclus = exclus + 1 numpy.save( "results", (rendu / testing_labels.shape[0]) * 100 ) #On sauvegarde pour que l'utilisateur puisse la consulter même après avoir lancé une autre CAO. except: affichageAllfunction['text'] = "Erreur fichier d'entrée ou paramètres"
def coa(): ''' Fonction qui réalise une carte auto-organisatrice (CAO) à partir de l'algorithme de kohonen et de la base de donnée entrée par l'utilisateur à travers la fonction du fichier read_mnist. Voir le lien plus bas pour plus de précision. Entrées : (sous forme de sauvegardes) -les paramètres que l'utilisateur souhaite appliquer (iterations, sigma, eta, sigma_max, sigma_min, eta_max et eta_min Sorties : (sous forme de sauvegardes) -l'ensemble des poids des neurones générés par la fonction -mean_bmu : la moyenne de la valeur des bmu(best matching unit) calculés lors de la réalisation de la CAO Lien wikipédia : https://fr.wikipedia.org/wiki/Carte_auto_adaptative ''' try: #Boucle de sécurité : si le fichier rentré dans le programme n'a pas le bon format ou les bonnes composantes, la fonction ne va rien faire et afficher un message d'erreur sur l'interface graphique. #On charge les données : iterations = numpy.load("iterations.npy") iterations = int( iterations.tolist() ) #Permet de transformer le format des données, car elles sont sauvegardées sous format numpy. sigma = numpy.load("sigma.npy") sigma = float(sigma.tolist()) eta = numpy.load("eta.npy") eta = float(eta.tolist()) sigma_max = numpy.load("sigma_max.npy") sigma_max_value = float(sigma_max.tolist()) sigma_min = numpy.load("sigma_min.npy") sigma_min_value = float(sigma_min.tolist()) eta_max = numpy.load("eta_max.npy") eta_max_value = float(eta_max.tolist()) eta_min = numpy.load("eta_min.npy") eta_min_value = float(eta_min.tolist()) #=============================================================================== # Paramètres concernant les données d'apprentissage #=============================================================================== ## dimension d'un vecteur d'entrée data_shape = (1, 784) ## nombre de classes différentes disponibles data_number = 10 ## dimensions des données data_dimension = (data_number, numpy.prod(data_shape)) ## récupération des données data = training_samples #=============================================================================== # Paramètres concernant la carte auto-organisatrice et l'algorithme de Kohonen #=============================================================================== ## taille de la carte auto-organisatrice (COA) map_shape = (20, 20) numpy.save("map_shape", map_shape) #Sauvegardé car utilisé dans d'autres fonctions ## dimensions des prototypes de la COA : une carte de MxM' [map_shape] vecteurs de dimension PxP' [data_dimension] weights_dimension = (numpy.prod(map_shape), numpy.prod(data_shape)) ## initialisation aléatoire des prototypes de la COA : distribution uniforme entre 0. et 1. weights = numpy.random.uniform(low=0., high=1., size=weights_dimension) decay_start_iter = 0.2 * iterations decay_stop_iter = 0.6 * iterations ###Kohonen eta_var = eta sigma_var = sigma sum_bmu = 0 for curr_iter in range(iterations): ## choisir un indice aléatoirement random_idx = numpy.random.randint(training_samples.shape[0]) ## instancier l'exemple d'apprentissage courant sample = data[random_idx] ## trouver la best-matching unit (BMU) et son score (plus petite distance) bmu_idx, bmu_score = kohonen.nearestVector(sample, weights) sum_bmu += bmu_score ## traduire la position 1D de la BMU en position 2D dans la carte bmu_2D_idx = (bmu_idx // map_shape[0], bmu_idx % map_shape[0]) ## gaussienne de taille sigma à la position 2D de la BMU gaussian_on_bmu = kohonen.twoDimensionGaussian( map_shape, bmu_2D_idx, sigma) ## mettre à jour les prototypes d'après l'algorithme de Kohonen (fonction à effets de bord) kohonen.updateKohonenWeights(sample, weights, eta, gaussian_on_bmu) sigma = kohonen.constrainedExponentialDecay( curr_iter, decay_start_iter, decay_stop_iter, sigma_max_value, sigma_min_value) eta = kohonen.constrainedExponentialDecay(curr_iter, decay_start_iter, decay_stop_iter, eta_max_value, eta_min_value) #=============================================================================== # Sauvegarde des données #=============================================================================== numpy.save( "data", weights ) # On en a besoin dans d'autres fonctions (graph par exemple). mean_bmu = sum_bmu / iterations numpy.save( "mean_bmu", mean_bmu ) # De même si on veut refaire le labelling ou encore l'évaluation. except: affichageCAO['text'] = "Veuillez rentrer tous les paramètres"
def COA(iterations, eta, sigma,y,x): #=============================================================================== # Paramètres généraux de la simulation #=============================================================================== ## nombre total d'itérations d'apprentissage #iterations = 1000 #training_samples.shape[0] ## affichage console d'information ou non verbose = False #=============================================================================== # Paramètres concernant les données d'apprentissage #=============================================================================== ## dimension d'un vecteur d'entrée data_shape = (1,784) ## nombre de couleurs différentes disponibles data_number = 10 ## dimensions des données : 'data_number' couleurs de taille 'data_shape' générées aléatoirement data_dimension = (data_number, numpy.prod(data_shape)) ## génération des données data = training_samples #=============================================================================== # Paramètres concernant la carte auto-organisatrice et l'algorithme de Kohonen #=============================================================================== ## taille de la carte auto-organisatrice (COA) map_shape = (20,20) ## valeur constante du rayon de voisinage gaussien (sigma) #sigma = 2 ## valeur constante du taux d'apprentissage (eta) #eta = 1. #METTRE 10^-3 ## dimensions des prototypes de la COA : une carte de MxM' [map_shape] vecteurs de dimension PxP' [data_dimension] weights_dimension = (numpy.prod(map_shape), numpy.prod(data_shape)) ## initialisation aléatoire des prototypes de la COA : distribution uniforme entre 0. et 1. weights = numpy.random.uniform(low=y, high=x, size=weights_dimension) decay_start_iter = 0.2*iterations decay_stop_iter = 0.6*iterations ## paramètres du rayon de voisinage gaussien (sigma) sigma_max_value = 4. sigma_min_value = .9 ## paramètres du taux d'apprentissage (eta) eta_max_value = .3 eta_min_value = .001 #=============================================================================== # Boucle d'apprentissage suivant l'algorithme de Kohonen #=============================================================================== eta_var = eta sigma_var = sigma sum_bmu = 0 for curr_iter in range(iterations): ## choisir un indice aléatoirement random_idx = numpy.random.randint(training_samples.shape[0]) ## instancier l'exemple d'apprentissage courant sample = data[random_idx] ## trouver la best-matching unit (BMU) et son score (plus petite distance) bmu_idx, bmu_score = kohonen.nearestVector(sample, weights) sum_bmu += bmu_score ## traduire la position 1D de la BMU en position 2D dans la carte bmu_2D_idx = (bmu_idx//map_shape[0], bmu_idx%map_shape[0]) ## gaussienne de taille sigma à la position 2D de la BMU gaussian_on_bmu = kohonen.twoDimensionGaussian(map_shape, bmu_2D_idx, sigma) ## mettre à jour les prototypes d'après l'algorithme de Kohonen (fonction à effets de bord) kohonen.updateKohonenWeights(sample, weights, eta, gaussian_on_bmu) sigma = kohonen.constrainedExponentialDecay(curr_iter, decay_start_iter, decay_stop_iter, sigma_max_value, sigma_min_value) eta = kohonen.constrainedExponentialDecay(curr_iter, decay_start_iter, decay_stop_iter, eta_max_value, eta_min_value) ## afficher l'itération courante à l'écran if verbose: print('Iteration %d/%d'%(curr_iter+1, iterations)) #=============================================================================== # Affichage graphique #=============================================================================== weights_reshaped = weights.reshape((map_shape[0],map_shape[1],28,28)) img = numpy.zeros((map_shape[0]*28,map_shape[1]*28)) for i in range(map_shape[0]): for j in range(map_shape[1]): img[i*28:(i+1)*28,j*28:(j+1)*28] = weights_reshaped[i,j,:,:] #plt.imshow(img, cmap = 'Greys') #plt.show() #=============================================================================== # Sauvegarde des données #=============================================================================== return weights,sum_bmu/iterations