Algorithmes Génétiques 2: Peindre Vermeer
Introduction
Packages
Les Algorithmes Génétiques 2: Peindre Vermeer est un problème dans lequel un algorithme génétique peut être appliqué. L'objectif est de créer une peinture générée par ordinateur qui ressemble à une peinture du célèbre peintre hollandais Johannes Vermeer.
Pour appliquer un algorithme génétique à ce problème, nous devons définir un ensemble de gènes, qui représentent dans ce cas la couleur et la position de chaque coup de pinceau. Chaque individu de la population serait une peinture créée en combinant les gènes d'une manière particulière. La fonction d'adaptation serait utilisée pour évaluer dans quelle mesure chaque peinture ressemble à une véritable peinture de Vermeer.
L'algorithme génétique serait ensuite appliqué de la manière suivante :
-
Initialisation : Générer une population initiale d'individus aléatoires.
-
Évaluation : Évaluer la qualité de chaque individu en utilisant la fonction d'adaptation.
-
Sélection : Sélectionner un sous-ensemble d'individus de la population pour servir de parents à la prochaine génération.
-
Croisement : Combiner les gènes des parents sélectionnés pour créer de nouveaux individus.
-
Mutation : Introduire des changements aléatoires dans les gènes des nouveaux individus.
-
Remplacement : Remplacer certains individus de la population actuelle par les nouveaux individus.
-
Condition d'arrêt : Vérifier si la condition d'arrêt a été atteinte. Si ce n'est pas le cas, revenir à l'étape 2.
Dans le cas de la peinture de Vermeer, la condition d'arrêt pourrait être un nombre maximal de générations ou un niveau d'adaptation seuil.
En appliquant ces étapes de manière itérative, l'algorithme génétique améliorera progressivement la qualité des peintures dans la population. Au fil du temps, l'algorithme peut converger vers une peinture qui ressemble étroitement à une peinture de Vermeer.
Importer les Packages
Packages
-
os : est une bibliothèque standard de Python qui permet d'interagir avec le système d'exploitation sous-jacent. Il fournit des fonctionnalités pour effectuer des opérations liées aux fichiers et aux répertoires, à l'environnement système, aux processus, etc.
-
NumPy : NumPy est une bibliothèque Python populaire pour le calcul scientifique qui fournit des structures de données pour la représentation de tableaux multidimensionnels et des fonctions pour manipuler ces tableaux.
-
random : The random module in Python provides a suite of functions for generating random numbers.
-
colour : est une bibliothèque de gestion des couleurs qui offre des fonctionnalités pour la manipulation, la conversion et la représentation des couleurs dans différents espaces colorimétriques.
-
json : cette bibliothèque permet de travailler avec des données au format JSON (JavaScript Object Notation). Le module json offre des fonctions pour la sérialisation (encodage) et la désérialisation (décodage) des objets Python en JSON et vice versa.
-
Pygame : est une bibliothèque Python populaire utilisée pour développer des jeux vidéo et des applications multimédias interactives. Elle fournit des fonctionnalités pour la création de graphismes, la gestion des événements, le traitement du son, la gestion des entrées utilisateur et bien plus encore.
1 2 3 4 5 6 |
|
Initialiser un organisme
Organism
Ce code définit la classe Organism
(Organisme) qui représente un organisme avec un ensemble de gènes. Elle a les attributs suivants :
chromosome: un tableau numpy représentant les gènes de l'organisme. Les valeurs des gènes sont limitées entre 0 et 1 à l'aide de np.clip(genes, 0, 1).
visual: une variable utilisée pour stocker une représentation visuelle de l'organisme (probablement une image).
fitness: une variable utilisée pour stocker la valeur de fitness de l'organisme.
La classe Organism
a également une méthode mutate
qui effectue une mutation sur l'organisme. Les paramètres rate, scale et add sont les taux de mutation et d'ajout, ainsi que l'échelle de mutation utilisés dans le processus de mutation. Voici ce que fait la méthode mutate
:
-
Elle effectue une copie du chromosome de l'organisme en utilisant np.copy(self.chromosome).
-
Elle détermine le nombre de mutations à effectuer en fonction du taux de mutation : num_mutations = 1 + int(rate * n_gene).
-
Elle itère sur le nombre de mutations et effectue les mutations suivantes :
-
Si le résultat de random() > add est True, une mutation sur un gène existant est effectuée.
-
Un indice i est choisi aléatoirement à partir des indices de caractéristiques (n_feat).
-
Une valeur aléatoire est ajoutée à la caractéristique sélectionnée dans un gène sélectionné aléatoirement dans le chromosome.
-
Si l'indice est 3, la valeur de cette caractéristique est modulo 1.
-
-
Sinon, une opération d'ajout ou de suppression d'un gène est effectuée.
- Si random() < 0.3, un gène est supprimé aléatoirement du chromosome. Sinon, deux gènes existants sont sélectionnés aléatoirement pour créer un nouveau gène. Le nouveau gène est obtenu en faisant la moyenne des deux gènes sélectionnés et en ajoutant une perturbation. La troisième caractéristique du nouveau gène est multipliée par 0.2.
-
-
Enfin, la méthode renvoie un nouvel objet
Organism
avec le chromosome muté.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
|
Initialiser une population
Population
La classe Population
comprend plusieurs méthodes pour simuler et faire évoluer une population d'organismes basée sur une image de référence.
Le code utilise la bibliothèque Pygame pour gérer les graphiques et la manipulation d'images. Voici un bref résumé de chaque méthode dans le code :
-
init(self, path) : Méthode constructeur qui charge une image de référence à partir d'un chemin de fichier donné en utilisant la bibliothèque Pygame, crée une surface sur laquelle dessiner et initialise une liste de population vide.
-
draw(self, organism) : Méthode pour dessiner un organisme sur la surface en itérant sur son chromosome et en dessinant des cercles avec une position, une taille et une couleur données.
-
spawn(self, pop_size=30, complexity=10) : Méthode pour générer une nouvelle population d'organismes en créant un certain nombre d'organismes avec un nombre spécifié de gènes dans chaque membre.
-
calc_fitness(self, organism) : Méthode pour calculer la forme physique d'un organisme en le dessinant et en le comparant à l'image de référence. La forme physique est calculée comme la différence absolue moyenne négative entre les pixels des deux images.
-
get_child(self, a, b) : Méthode pour générer un nouvel organisme en combinant deux organismes parents. Les gènes de chaque parent sont choisis au hasard avec une probabilité de 70% pour le premier parent et de 30% pour le deuxième parent. Les gènes communs sont mélangés dans le nouvel organisme.
-
save(self, path) : Méthode pour enregistrer la population actuelle dans un fichier JSON.
-
load(self, path) : Méthode pour charger une population à partir d'un fichier JSON.
-
mutate_and_pick(self, organism, rate, scale, add, attempts=10) : Méthode pour muter un organisme en ajoutant une valeur aléatoire à chaque gène avec une probabilité spécifiée. La méthode essaie de muter l'organisme un certain nombre de fois spécifié et renvoie l'organisme muté avec la forme physique la plus élevée.
-
step(self, time, outdir, rate=0.01, scale=0.1, add=0.3) : Méthode pour simuler une étape d'évolution en créant de nouvelles descendances, en les mutant et en conservant les plus adaptées. La méthode enregistre une image de l'organisme le plus adapté dans un fichier et enregistre la population actuelle dans un fichier JSON.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
|
Faire Evoluer la population d'organismes
evolve
La fonction evolve
effectue l'évolution de la population d'organismes en utilisant les paramètres de mutation fournis.
La fonction commence par créer une instance de la classe Population
en fournissant le chemin d'accès à l'image de référence. Ensuite, elle crée un répertoire de sortie pour enregistrer les images générées au cours de l'évolution.
Si une sauvegarde de population existe déjà, elle est chargée à partir du fichier JSON correspondant. Le numéro de l'étape de départ est également déterminé en se basant sur le nom du dernier fichier d'image enregistré.
Si aucune sauvegarde de population n'existe, une population initiale est générée en appelant la méthode spawn de l'instance de Population
.
Ensuite, la boucle principale de l'évolution démarre, itérant sur le nombre d'étapes spécifié. À chaque étape, la méthode step de l'instance de Population
est appelée pour effectuer une itération de l'évolution. Les paramètres de mutation (rate, scale, add_chance) sont transmis à cette méthode.
L'image du meilleur organisme de chaque étape est enregistrée dans le répertoire de sortie, et la population actuelle est sauvegardée dans un fichier JSON.
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
|
Exécuter le processus d'évolution de la population d'organismes
evolve(0.01, 0.1, 0.01)
La fonction evolve(0.01, 0.1, 0.01)
exécute le processus d'évolution de la population d'organismes en utilisant les paramètres suivants :
Taux de mutation : 0,01 (1% de chance de mutation)
Échelle (scale) : 0,1 (distribution normale avec un écart-type de 0,1)
Chance d'ajout ou de suppression : 0,01 (1% de chance d'ajout ou de suppression de gènes)
-
Cela signifie que lors de chaque itération de l'évolution, les organismes de la population seront soumis à des mutations avec une probabilité de 0,01 (1% de chance). Les mutations consistent à modifier les valeurs des gènes des organismes. L'échelle de mutation est définie à 0,1, ce qui signifie que les modifications de gènes seront tirées d'une distribution normale avec un écart-type de 0,1.
-
De plus, il y a une probabilité de 0,01 (1% de chance) d'ajouter ou de supprimer des gènes lors de la mutation des organismes.
-
Ces paramètres contrôlent le niveau de diversité génétique et de variation au sein de la population, ainsi que la probabilité de modifications importantes des caractéristiques des organismes au fil des étapes de l'évolution.
175 |
|
Image de test (Input)
Résultat final (Output)
Conclusion
Conclusion
Vous pouvez observer une amélioration des images générées à chaque itération. Cependant, en raison des contraintes de ressources, je n'ai pas pu poursuivre l'exécution du code car j'utilisais Google Colab, qui est limité en termes de temps. Pour obtenir le résultat final de mon algorithme, il serait nécessaire de souscrire à Google Colab Pro.