123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- ## Fichier : incubateur.py
- # Auteur : Jovian Hersemeule
- # Classe python. Se charge d'entrainer un réseau de
- # neurones par algorithme génétique.
- from ReseauNeurones.cerveau import Cerveau
- from ReseauNeurones.generation import Generateur
- from Outils.IA_alphabeta import IA_minmax_alpha_beta
- from random import randint
- from os import system
- class Incubateur :
- def __init__(self): # Jovian 21 mars 2017
- """
- Construit l'incubateur.
- """
- self.population = None # Cerveau list
- self.iter = 0 # int
- self.nom_structure = None # int
- self.nom_session = None # string
- self.tournoi = None # fonction de tournoi
- self.nom_tournoi = "Pas de tournoi" # nom du tournoi
- self.save_rate = None # nombre de générations entre chaque sauvegarde
- #(None pas de sauvegarde avant la fin)
- self.nb_elite_kept = 1
- self.nb_elite_cross = 1
- self.nb_mixte_cross = 1
- self.nb_elite_mutate = 1
- self.nb_weak_mutate = 1
- self.nb_rd_generated = 1
- self.generator = Generateur()
- def start_session(self, nom_structure, nom_session = "BasicTraining", nb_gen_max = None, nb_pop = 20, debug = False ): # Jovian 21 mars 2017
- """
- Permet de démarrer une session d'entraînement.
- Attention cela est une fonction blocante.
- Arg nom_structure : le nom de la structure du réseau.
- Arg nom_session : permet de choisir le nom du dossier pour cette session.
- Arg nb_gen_max : le nombre maximal de générations avant l'arrêt. Si None pas de limite.
- Arg nb_pop : nombre d'individus par génération.
- Arg debug : affiche des informations si vaut True.
- """
- # Initialisation des attributs
- self.nom_structure = nom_structure
- self.nom_session = nom_session
- # Création des population
- self.population = []
- self.iter = 1
-
- for i in range(nb_pop):
- individual = Cerveau()
- individual.charger_structure( nom_structure, debug = debug )
- individual.generer_poids( inf = -1.0, sup = 1.0, debug = debug )
- individual.build_network( debug = debug )
-
- self.population.append( individual )
- # Sauvegarde des individus originaux
- self.save_population(debug = debug)
- # Ecriture du protocole
- self.write_protocole(debug = debug)
- # Entrainement
- self.train( nb_gen_max = nb_gen_max, debug = debug )
- # Sauvegarde de la population
- self.save_population(debug = debug)
-
- def save_population(self, debug = False): # Jovian 30 mai 2017
- """
- Sauvegarde la totalité de la population.
- """
- # Dossier
- chemin = "ReseauNeurones\\Base_Poids\\" + self.nom_session + "\\"
- chemin += "Generation" + str(self.iter)
- system("mkdir " + chemin)
- # Fichier
- chemin += "\\individu"
- chemin = chemin.replace("\\", "/")
- # Parcours
- for tp in enumerate(self.population) :
- k, individual = tp
- with open( chemin + str(k) + ".pds", "w" ) as flux :
- for v in individual.liste_poids :
- flux.write( str(v) + "\n" )
- # Annonce
- if debug :
- print("|")
- print("Population sauvegardée.")
-
-
- def sort(self, debug = False): # Jovian 6 juin 2017
- """
- Classe la population par un système de tournoi.
- """
- if debug :
- print("|\nClassement des individus.")
-
- # Création des intelligences à patir des cerveaux
- liste_IA = [ IA_minmax_alpha_beta(self.nom_session, brain.fct_eval, 1) for brain in self.population ]
- #liste_IA = [ IA_minmax_alpha_beta(self.nom_session, lambda x,y : 0, 1) for brain in self.population ]
- # Classement par tournoi
- tab_scores = self.tournoi( liste_IA )
- if debug :
- print("Tableau des scores : ", tab_scores )
- # Etablissement d'un classement à partir des scores :
- n = len(self.population)
- tab = [(tab_scores[i],i) for i in range(n)]
- tab.sort()
- tab_classement = [0] * n # Tableaux de rangs
- for i in range(n) :
- tab_classement[tab[i][1]] = n - 1 - i
- if debug :
- print("Rang des joueurs : ", tab_classement )
- # Ordonnancement de la population en conséquence :
- nouveau = n*[None]
- for i in range(n) :
- nouveau[tab_classement[i]] = self.population[i]
- self.population = nouveau
-
-
- def generate(self, debug = False): # Jovian 2 juin 2017
- """
- Génère la génération suivante d'individus.
- """
- # Annonce
- if debug :
- print("|\nGénération en cours de création : ", self.iter)
- # Liste des nouvaux chromosomes
- chrom_list = []
-
- # Séparation faibles / forts
- mid = len(self.population) // 2 + 1
- # Garder les meilleurs
- if debug and self.nb_elite_kept > 0 :
- print("On garde les ", self.nb_elite_kept, " meilleurs.")
-
- for k in range( self.nb_elite_kept ):
- chrom_list.append( self.population[k].liste_poids )
- # Croiser les meilleurs
- if debug and self.nb_elite_cross > 0 :
- print("On croise les ", self.nb_elite_cross, " meilleurs.")
-
- for k in range( self.nb_elite_cross ):
- # Choisir deux individus à reproduire
- indA = randint(0, mid)
- indB = randint(0, mid)
- # Opérations génétiques
- chromA = self.population[indA].liste_poids
- chromB = self.population[indB].liste_poids
- chromCross = self.generator.cross_random( chromA, chromB )
- # Ecriture du résultat
- chrom_list.append( chromCross )
- # Croiser des individus aléatoirement
- if debug and self.nb_mixte_cross > 0 :
- print("On croise aléatoirement ", self.nb_mixte_cross, " individus.")
-
- for k in range( self.nb_mixte_cross ):
- # Choisir deux individus à reproduire
- indA = randint(0, len( self.population ) )
- indB = randint(0, len( self.population ) )
- # Opérations génétiques
- chromA = self.population[indA].liste_poids
- chromB = self.population[indB].liste_poids
- chromCross = self.generator.cross_random( chromA, chromB )
- # Ecriture du résultat
- chrom_list.append( chromCross )
- # Mutation des élites
- if debug and self.nb_elite_mutate > 0 :
- print("On mute les ", self.nb_elite_mutate, " meilleurs.")
-
- for k in range( self.nb_elite_mutate ):
- # Choisir
- indA = randint(0, mid)
- # Opérations génétique
- chromA = self.population[indA].liste_poids
- chromMuted = self.generator.mutate_total( chromA, nb = 1 )
- # Ecriture du résultat
- chrom_list.append( chromMuted )
- # Mutation des faibles
- if debug and self.nb_weak_mutate > 0 :
- print("On mute les ", self.nb_weak_mutate, " plus faibles.")
-
- for k in range( self.nb_weak_mutate ):
- # Choisir
- indA = randint(mid, len( self.population ) )
- # Opérations génétique
- chromA = self.population[indA].liste_poids
- chromMuted = self.generator.mutate_total( chromA, nb = 1 )
- # Ecriture du résultat
- chrom_list.append( chromMuted )
-
- # Mise à jour des réseaux
- for k in range( self.nb_elite_kept, len(chrom_list) ) :
- self.population[k].donner_poids( chrom_list[k] )
- self.population[k].build_network()
- # On complète la population en générant des membres aléatoirement
- if debug and len(self.population) - len(chrom_list) > 0 :
- print("On rajoute ", len(self.population) - len(chrom_list), " générés au hasard.")
-
- for k in range( len(chrom_list), len(self.population) ) :
- self.population[k].generer_poids()
- self.population[k].build_network()
-
-
- def train(self, nb_gen_max = None, debug = False): # Jovian 31 mai 2017
- """
- Entraîne le réseau.
- int nb_gen_max : Le nombre de générations avant l'arrêt (None pour boucle infinie)
- bool debug : Affichage d'informations de suivi
- """
- last_save = self.iter
- if debug :
- print("Démarrage de l'entraînement à partir de la génération ", self.iter )
-
- # Itération
- while self.iter < nb_gen_max :
- self.iter += 1
- print("\n> Génération ", self.iter, " pour la session ", self.nom_session,".")
- # Classement
- self.sort(debug = debug)
- # Génération suivante
- self.generate(debug = debug)
- # Sauvegarde
- if self.save_rate != None and self.iter - last_save >= self.save_rate :
- last_save = self.iter
- self.save_population(debug = debug)
- # Fin de l'entraînement
- return None
- def write_protocole(self, debug = False): # Jovian 6 juin 2017
- """
- Sauvegarde les paramètres utilisés dans le dossier
- qui contient les résultats de l'entraînement.
- bool debug : Affichage d'informations de suivi
- """
- # Chemin
- chemin = "ReseauNeurones/Base_Poids/" + self.nom_session
- chemin += "/Protocole.txt"
- # Ecriture
- with open( chemin, "w" ) as flux :
- flux.write( "Nom du tournoi : " + str(self.nom_tournoi) + "\n" )
- flux.write( "Nombre de générations maximal : " + "inconnu" + "\n" )
- flux.write( "Taille de population : " + str(len(self.population)) + "\n" )
- flux.write( "\n\n" )
- flux.write( "nb_elite_kept = " + str(self.nb_elite_kept) + "\n" )
- flux.write( "nb_elite_cross = " + str(self.nb_elite_cross) + "\n" )
- flux.write( "nb_elite_kept = " + str(self.nb_mixte_cross) + "\n" )
- flux.write( "nb_elite_mutate = " + str(self.nb_elite_mutate) + "\n" )
- flux.write( "nb_weak_mutate = " + str(self.nb_weak_mutate) + "\n" )
- flux.write( "nb_rd_generated = " + str(self.nb_rd_generated) + "\n" )
-
- # Annonce
- if debug :
- print("|")
- print("Protocole enregistré.")
-
|