J'ai écrit le traitement de base de l'algorithme génétique et du réseau neuronal de Python. Puisque l'algorithme génétique n'est pas un expert, c'est un algorithme génétique.
C'est une méthode de calcul qui imite le réseau de cellules nerveuses des organismes vivants. [Lien vers Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%8B%E3%83%A5%E3%83%BC%E3%83%A9%E3%83%AB% E3% 83% 8D% E3% 83% 83% E3% 83% 88% E3% 83% AF% E3% 83% BC% E3% 82% AF)
C'est une expression logique qui produit 1 si les deux entrées sont identiques et 0 si elles sont différentes.
Entrée 1 | Entrée 2 | production |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
Ce que je sais des algorithmes génétiques ・ Sélectionnez des individus avec de bonnes caractéristiques -Créer un nouvel individu qui hérite des caractéristiques d'un individu avec de bonnes caractéristiques. ・ Répétez les changements de génération pour trouver des individus avec de meilleures caractéristiques et trouver des réponses. à propos de ça. Il semble y avoir différentes méthodes, mais cette fois je suis amateur ・ Trier les populations par grade ・ Remplacez les 10% inférieurs par des individus nouvellement générés ・ Généré par croisement (décrit plus loin) + 50% avec les 50% supérieurs et d'autres individus ・ Répétez ce processus pour trouver une personne qui obtient la réponse la plus appropriée. J'ai pris la méthode.
Je comprends qu'il s'agit de retirer les caractéristiques de deux individus et d'en créer un nouveau. Il imite un enfant héritant du gène de ses parents dans le monde réel des êtres vivants. L'héritage réel est une image de l'héritage numérique du gène de l'un ou l'autre parent petit à petit, Cette fois, nous avons arrangé les poids synaptiques (type float) du réseau neuronal. En prenant la division interne de chaque valeur numérique des deux séquences montrant les poids synaptiques des deux individus J'ai imité l'héritage des caractéristiques de deux individus. Exemple
w1 | w2 | w3 | w4 | |
---|---|---|---|---|
Poids synaptique de l'individu 1 | 1 | 1 | 3 | 4 |
Poids synaptique de l'individu 2 | 0 | 0 | 1 | 1 |
Similitude avec l'individu 1 | 1 | 0 | 0.5 | 0.1 |
Similitude avec l'individu 2 | 0 | 1 | 0.5 | 0.9 |
Nouveau poids synaptique individuel | 1 | 0 | 2 | 1.3 |
Cependant, comme il est possible qu'elle converge vers une solution locale, nous avons décidé de prendre la valeur de la division externe des deux poids.
sample.py
from numpy.random import *
import numpy as np
import math
import sys
class Body: #Chaque individu
#Nombre de couches d'entrée
nn_input=2
#Nombre de couches intermédiaires
nn_hidden=3
nn_output=1
#Gamme de poids de synapse initial
w_range=10
#Nombre de synapses
w_length=(nn_input+1)*(nn_hidden+1)+(nn_hidden+1)*(nn_output)
#Valeur minimale à saisir dans la fonction sigmoïde
sigmoidinputmin=math.log(sys.float_info.min)
#Valeur maximale à saisir dans la fonction sigmoïde
sigmoidinputmax=math.log(sys.float_info.max)
#Combien l'héritage au moment du croisement doit être divisé en interne et externe
#0 ... moyenne de deux poids
#1 ... L'un ou l'autre des deux poids
#1 ou plus ... Une division externe (pas une valeur entre deux poids) est possible
crossRatio=2
def __init__(self):
self.w=None #Poids synapse
self.score=-1 #Résultats de l'évaluation
self.result=None #Résultat du calcul
#Créer un nouveau
def createNewBodyAtInit():
body=Body()
body.w=np.random.uniform(-Body.w_range,Body.w_range,Body.w_length)
body.calc()
return body
#Voir les résultats
def showResult(self):
aaa= str(self.score) + ":" + str(self.result)
print(aaa)
#Traversée
#Argument: croisement d'individus
#Valeur renvoyée Individu généré
def cross(self,otherBody):
w1=self.w
w2=otherBody.w
newW=[]
for i in range(len(w1)):
a=np.random.random()*Body.crossRatio
newW.append(w1[i]*a+w2[i]*(1-a))
newBody=Body()
newBody.w=newW
newBody.calc()
return newBody
#Calcul d'évaluation
def calc(self):
result=[]
for _in in in_sample:
result.append(self.nn(_in))
_ = out_sample-result
error = _*_
self.result=result
self.score=sum(error)
#Fonction Sigmaid
def sigmoid(self,x):
#Renvoie 1 car l'entrée est trop petite pour déborder
if x<Body.sigmoidinputmin :
return 1
#Si c'est trop gros, il n'y a pas de débordement,
#Même processus que ci-dessus (non requis)
if Body.sigmoidinputmax<x :
return 0
a=math.log(sys.float_info.max)
return 1/(1+math.e**-x)
#Calcul du réseau neuronal
def nn(self,inp):
w=self.w
w_num=0
hidden_o=[]
for i in range (Body.nn_hidden):
o=0
for j in range(Body.nn_input):
o+=w[w_num]*inp[j]
w_num+=1
o+=w[w_num]
w_num+=1
hidden_o.append(self.sigmoid(o))
o=0
for i in range (Body.nn_hidden):
o+=w[w_num]*hidden_o[i]
w_num+=1
o+=w[w_num]
w_num+=1
return self.sigmoid(o)
def main():
#Valeur d'entrée
global in_sample
in_sample=np.array([[0,0],
[0,1],
[1,0],
[1,1]])
#Valeur cible de sortie
global out_sample
out_sample=np.array([0,1,1,0]);
#Nombre d'individus
body_counts=100
#Nombre de générations
loop=1000
#Population
bodies=[]
#Génération initiale de population
for i in range(body_counts):
body=Body.createNewBodyAtInit()
bodies.append(body)
#L'évaluation en changeant de génération
for i in range(loop):
print("***")
bodies=generate(bodies)
bodies[0].showResult()
#Régénération de la population
#Argument: population pré-générationnelle
#Valeur de retour: population après changement de génération
def generate(bodies):
bodies=sort(bodies)
a1=0
length=len(bodies)
newgennum=length-1
#Pourcentage d'individus mutants
mutationRatio=0.1
stop=newgennum-int(length*mutationRatio)
#Génération d'individus mutants
while stop<newgennum :
body = Body.createNewBodyAtInit()
bodies[newgennum]=body
newgennum += -1
#Taux de génération d'individus croisés
crossRatio=0.5
#Traversée
stop=newgennum-int(length*crossRatio)
while stop<newgennum :
a2=int(length*np.random.random())
body = bodies[a1].cross(bodies[a2])
bodies[newgennum]=body
a1 += 1
a2 += -1
newgennum += -1
return bodies
#Trier les populations par grade.
#Argument: population pré-triée
#Valeur de retour: Population après tri
def sort(bodies):
di = {}
for body in bodies:
di[body.score]=body
keys = sorted(di.keys())
li=[]
for key in sorted(di.keys()):
li.append(di[key])
return li
if __name__ =="__main__":
main()
Recommended Posts