2011-02-19 7 views
8

Actuellement, je travaille sur un projet qui utiliserait des algorithmes génétiques pour optimiser les réseaux de neurones. Je me rends compte que ce n'est probablement pas la meilleure façon de les optimiser, mais je suis nouveau pour les deux, alors je voulais juste essayer de les utiliser.Utilisation d'algorithmes génétiques pour les réseaux de neurones

Mes plans sont les suivants (sujet à changement, beaucoup). Mes neurones d'entrée utiliseraient un ensemble de données qui pourrait avoir à peu près n'importe quel nombre positif (y compris des nombres décimaux jusqu'à deux places, donc ce serait vraiment des nombres à virgule flottante), mais probablement entre 0 et 20000. Parce que l'importance est dans la les nombres se comparent entre eux en valeur plutôt qu'en taille, ils seraient d'abord divisés par le nombre le plus élevé de toutes les valeurs qui seraient entrées. Ils seraient multipliés par des poids (tout flotteur positif ou négatif) avant d'aller à leur couche cachée. Chaque neurone dans la couche cachée ferait la somme de toutes ses entrées jusqu'à ce qu'elles soient calculées. Ils seraient ensuite exécutés par une fonction logistique et être édités.

Mon environnement est Visual Studio C++ 2010 Express et j'utilise le clr.

Mon problème réside dans l'algorithme génétique et son fonctionnement. Ce serait ajuster les poids. Mon problème est que quand il change aléatoirement un peu dans l'un des poids (taux de mutation), il peut rendre les poids extraordinairement élevés ou bas, provoquant un débordement ou une autre erreur lorsqu'il est multiplié par l'entrée et ajouté aux autres. Je ne sais pas non plus comment j'organiserais mes chromosomes. Alors, serait-il préférable d'effectuer la randomisation par poids de sélection plutôt que des bits au hasard et de les changer en un nombre aléatoire dans une fourchette définie? Fondamentalement, je suis à la recherche de suggestions sur la façon d'organiser cela sans causer d'erreurs avec des valeurs trop grandes ou trop petites tout en maintenant les performances.

Merci (et désolé si cela devrait être dans la science informatique théorique, mais je pense qu'il ne rentrait pas là)

+0

Je ne me souviens pas des détails, mais dans ce livre: http://www.amazon.com/Techniques-Programming-Premier-Press-Development/dp/193184108X, l'auteur fait à peu près ce que vous décrivez, c'est-à-dire utilise des valeurs de poids mutées génétiquement pour optimiser un réseau neuronal. –

+0

Il serait intéressant de voir une comparaison des performances entre la solution que vous venez de proposer et un processus plus conventionnel (peut-être même un processus non neuronal). – Predictor

Répondre

6

(artificielle) sont notoirement difficiles à optimiser les réseaux de neurones (RNAs), et les algorithmes génétiques (GAs) sont une approche raisonnablement bonne pour le faire (principalement parce que tout le reste tend à être très limité dans la façon dont cela peut fonctionner). Bien sûr, il existe des alternatives qui fonctionnent bien, mais elles sont plus compliquées et subtiles à programmer et à accorder correctement (rétropropagation avec un recuit simulé et un moment d'apprentissage). Et je comprends que vous faites ce projet principalement pour jouer avec ces choses. Vous voudrez peut-être jeter un coup d'œil aux neuro-contrôleurs évolutifs (ENC), domaine où des algorithmes génétiques (ou évolutifs) sont utilisés pour former des RNA pour des tâches de navigation complexes (par exemple, les missions spatiales interplanétaires sont l'une des applications). de cela j'ai personnellement fait des recherches sur).

Pour la partie ANN, je vous suggère de ne pas vous limiter aux fonctions logistiques (je sais que le sigmoïde est inspiré des neurones biologiques, mais cela ne veut pas dire qu'ils sont les meilleurs tout le temps). De nombreuses autres fonctions existent également, les fonctions logistiques étant en partie utilisées car elles rendent la rétropropagation beaucoup plus rapide et plus simple à faire. Mais, les fonctions Radial-Basis font aussi des merveilles (IMO et d'après ce que j'ai vu, les applications les plus réussies des ANNs ont utilisé des fonctions Radial-Basis, c'est-à-dire RBF-NN). Typiquement, les gens utilisent soit des fonctions gaussiennes, des fonctions hyper-sphériques et très souvent des fonctions triangulaires (appelées Fuzzy Networks, une autre grande classe d'ANNs). Comme pour les GA, je ne recommanderais pas ce type de mutation que vous décrivez (c'est-à-dire retourner des bits) pour les raisons que vous avez mentionnées. Les gens n'utilisent pas ce type de mutation lorsqu'ils traitent de gènes à valeurs réelles. Une méthode de mutation très simple consiste simplement à décider (avec une certaine probabilité) de muter un individu, puis de sélectionner un élément de son gène à muter puis de générer un nouvel élément pour le remplacer par un générateur de nombres aléatoires (rand()) .Avec ceci, vous pouvez limiter l'échelle des éléments de gène générés pour éviter les problèmes de transformation de votre individu dégénéré (c'est-à-dire qu'un élément de gène complètement faux peut rendre l'individu entier inutile). Quels sont les gènes? Eh bien, pour un ANN, généralement un grand vecteur contenant tous les poids de tous les neurones de votre réseau. Vous pouvez deviner que les gens appliquent rarement les GA si le nombre de neurones est trop important. Je vous recommande également d'utiliser la sélection de tournois pour sélectionner des individus à reproduire. En ce qui concerne le croisement (c'est-à-dire le mélange de deux parents pour faire un enfant), il suffit de garder l'ordre des poids et de choisir pour chaque élément de l'enfant un poids de l'un ou l'autre parent avec une probabilité égale.

J'ai personnellement fait ce que j'ai décrit ci-dessus et cela fonctionne très bien pour certains problèmes (taille réduite et complexité élevée, c'est-à-dire aucune solution optimale évidente).

Enfin, ne vous attendez pas à ce que cela fonctionne aussi facilement. Typiquement, il faudra une taille de population et un nombre de générations beaucoup plus élevé que ce à quoi on pourrait s'attendre (après tout, l'évolution est un processus très lent!). Donc, n'essayez pas une population de 10 individus et courez pendant 50 générations, et dites tristement "OH je suppose que cela ne fonctionne pas ...". Essayez plus de l'ordre de milliers d'individus dans la population et de plusieurs milliers à cent mille générations, en fonction de l'ampleur du problème auquel vous l'appliquez, bien sûr.

+0

Je comprends beaucoup de ce que vous dites, et merci pour la réponse très élaborée, mais j'ai une question. En ce qui concerne la génération de nombres aléatoires, quel est le meilleur générateur aléatoire qui produira des nombres aléatoires à virgule flottante dans une plage incluant des nombres décimaux, plutôt que seulement des nombres entiers (.net, bibliothèque C standard, boost, etc.). – contrapsych

+0

Boost.Random est une solution "sophistiquée". Mais, le plus simple, consiste simplement à utiliser une formule de rand(), comme 'double num = (rand()% 10000) * 0.001;'. Cela produira un nombre de 0 à 10 avec une précision décimale jusqu'à 0,001. C'est aussi simple que ça. Mais si vous avez un peu de fond dans les statistiques et les fonctions de distribution de probabilité, vous pourriez trouver que Boost.Random est un peu plus élégant. –

3

Votre problème réside dans la représentation des chromosomes. Il est connu comme Hamming Cliff Problème. Vous pouvez utiliser Gray Code pour la représentation des chromosomes qui n'a pas Hamming Cliff Problème

+0

Euh, pourriez-vous expliquer plus? Je n'ai pas compris comment "Gray Code" se rapporte aux ANNs ou GAs ... –

Questions connexes