Neuronal network type perceptron by Atbidal2nd Aug 2011 4:33
|
---|
Summary This program can learn some symbol like alphabet and reconize a symbol writer. If symbol a is learn, and you write a different, He reconize symbol a Description Code pour darkBasic Pro Code ` This code was downloaded from The Game Creators ` It is reproduced here with full permission ` http://www.thegamecreators.com ` --------------------------------------------------- ` Janvier 2007 ` Auteur : Yoann CURE ` Licence : Libre ` Des questions : yoanncure@gmail.com ` ou modifications interessantes set window on set window size 800,600 set window title "Schmilblik" ` ------- Pour tracer en 3D ------- `Tableau des objets des entrees des neurones ` Le neurone 1 correspond à l'objet 1 ` Mais les entrées sont stocké de 65000 à 65000-entree type matr neurone as integer entree as integer endtype dim objet_entree(0) as matr type glo x as float y as float z as float cax as float cay as float nb_objet endtype locale as glo global vitesse_deplacement# vitesse_deplacement#=6.0 ` Vitesse de déplacement dans la 3D locale.nb_objet=65000 ` indice des objets -entree- Ne pas toucher ` ------- Pour tracer les graphiques ------- ` Les variables à renseigner global G_X as integer ` position X global G_Y as integer ` position Y global G_TX as integer ` Taille X global G_TY as integer ` Taille Y global nb_graphe as integer ` Nombre de graphiques simultanés -1<nb_graphe <4 G_X=10 G_Y=10 G_TX=200 G_TY=100 nb_graphe=0 dim G_rouge(G_TX) as float global G_r as integer ` Indice dans G_Rouge global Rmaxvar as float ` Variation maximum dans G_rouge dim G_vert(G_TX) as float global G_v as integer global Vmaxvar as float dim G_bleu(G_TX) as float global G_b as integer ` Indice dans G_Rouge global Bmaxvar as float ` Variation maximum dans G_rouge dim G_blanc(G_TX) as float global G_bl as integer global BLmaxvar as float inc G_r inc G_v inc G_b inc G_bl Rmaxvar=0.0 ` Valeur supposée max (pas obligatoire) ` ------- Analyse phrasé ------- dim nieme_mot(100) as string global indice_nieme=0 `console dim console(0) as string global Limit_p=100 `N'est pas utilile dans le cas du perceptron ` MEMBLOCK DU SYSTEM =255,254 ` 255 pour gestion futur des neurones ou gestion image ` 254 pour interface utilisateur (retine/stimulis) `Layer correspond au signe à lui faire apprendre. ` global layer=100 `heu ça je sais plus pourquoi mais faut le laisser global nb_boolean=200 ` Taille max du tableau (12*15) global limit_poid as float `Inutile pour l'instant limit_poid=0.9 dim stimulis(layer,nb_boolean) as boolean type stimulus chaine_dossier as string fichier as string type as string type2 as integer xg as integer yg as integer Resultat_espere as string ` resultat sur plusieurs neurone endtype `Tableau pour typer les stimulis dim sti(layer) as stimulus sti(0).chaine_dossier="Stimuli/Visuel/bol5x5" ` Inutil pour l'instant sti(0).fichier="+" ` Inutil pour l'instant `ne sert pas pour l'instant sti(0).type="boolean" sti(0).type2=0 global pointeur_layer ` la ou en est la lecture du signal ` Indice_layer = nb_de stimulis (ou d'exemple) en mémoire global indice_layer as integer ` TABLEAU POUR DESSINER ou transformer UN STIMULIS dim Grille(20,20) global xg global yg xg=5 yg=5 global xy xy=xg*yg `tableau stockant le neurone correspondant au memblock. Non utilisé pour l'instant ` MB(1)=no neurone dim MB(256) as integer ` Liste des neurones créés le plus recement ` list_MB(0)= le memblock le plus recement créé dim list_MB(255) as integer type neuro KP as integer ` memblock Stock poid et lien entree/sortie sortie as float ` Memorise la valeur de la sortie nb_entree as integer ` fonction as string ` Fonction de transfert Erreur as float S as integer ` Si le neurone est une sortie (personne n'a d'entrée connecté à lui) indice_entree as integer ` pointe vers le tableau des objet_entree 3D endtype Global Limite_P as float ` Limite de la valeur du poid Limite_P=1 ` Utilisation d'entrées binaires dim Neurone(0) as neuro `neurone vide doit exister mais doit rester vide rem array insert at bottom neurone(0) `Creation du tableau reseau type link forme as integer nb_neurone as integer sortie as integer ` renvoi le neurone de sortie le plus concerné nb_sortie as integer pas_apprentissage as float Sorties_adaptees endtype `forme=1 --> backprop dim reseau(10) as link global nb_reseau as integer `création du tableau pour ordonner l'ordre de consultation et d'apprentissage dim ordre(10,3,255) as integer `POUR LE WORDPAD global f_console as string f_console="_console_.txt" `--------------------------------------------------------------------------- ` Boucle principale `--------------------------------------------------------------------------- init_console() do deplace_camera() evenement_console() loop function init_console() rem if file exist(f_console) then delete file f_console execute file "notepad.exe","",get dir$() endfunction function evenement_console() if file exist(f_console) auto(f_console) delete file f_console endif endfunction ` --------------------------------------------------------------- ` TOOLS ` --------------------------------------------------------------- `Outils pour creer, modifier reseau/neurone... function console2(commande$) backdrop off nb_et=extraire_mot(commande$,"&") dim ET(nb_et) as string for i=0 to nb_et-1 ET(i)=nieme_mot(i) next i while no_et<nb_et nb_mot=extraire_mot(ET(no_et)," ") if lower$(nieme_mot(0))="rem" then exitfunction remstart for i=1 to indice_nieme Cprint(0,nieme_mot(i),0) next i remend select indice_nieme case 1 if commande$="debug" if file open(32) then close file 32 if file open(31) then close file 31 endif if commande$="auto" then auto("_tempo_lk") if commande$="cmd" then auto("test") if commande$="FSV" then Fabrique_stimulis_visuel(0) if commande$="?" print "CN F$:Créer un neurone avec F$ en fonction de transfert" print "CE N :Ajouter une entrée au neurone N" print "CL N E S :Créer un lien entre entree et neurone." print " N doit etre ici le neurone de l'entrer à connecter" print " E, le n° de l'entrée et S le n° du neurone dont la sortie est connectee à cet entree" print "--- Commande lecture ---" print " " print "FSV L :Fabriquer Stimulis Visuel no L" print "DG n :Dessiner la grille(layer) n° n" print " " print "APPR nb_fois reso layer St:Fais apprendre le réseau des impulsions St. si layer=-1 --> aleatoire" print " " print "CONR reso St Layer : Consulte le reseau " print "réseau ---------------------------" print "CRBack no nb_entree_sti nb_neurone_entree nb_neurone_cache nb_neurone sortie fonction$" print " Crée un réseau perceptron" print "VR reso : Ecrit dans reso.txt les connection est poid de tout" print "SS fichier : Sauvegarde tous les stimulis" print "CS fichier : Charge tous les stimulis du fichier" print "IR reso mode$: réinitialise les poid du reseau. mode$=rnd alors aléatoire sinon 0.0" print "3D reso : Donne une representation 3D de reso" print "MPA reso valeur(float) : modifie la valeur du pas d'apprentissage du reseau. default:0.1" print "graphe n : n=-1 pas de graphe temps réel mais 3D, n=0 graphe rouge n=1 graphe vert ..." print "CINOB layer fichier$ : Charge une image dans un layer" print "quit ou exit :fin programme" endif endcase case 2 if nieme_mot(0)="NS" neurone_est_sortie(val(nieme_mot(1))) endif if lower$(nieme_mot(0))="graphe" nb_graphe=val(nieme_mot(1)) endif if nieme_mot(0)="3D" representation_reseau(val(nieme_mot(1))) endif if nieme_mot(0)="SS" sauvegarder_stimulis(nieme_mot(1)) endif if nieme_mot(0)="CS" charger_stimulis(nieme_mot(1)) endif if nieme_mot(0)="VR" verifie_reseau(val(nieme_mot(1))) endif if nieme_mot(0)="FSV" then fabrique_stimulis_visuel(val(nieme_mot(1))) if nieme_mot(0)="DG" then reciproque_transformer_stimulis_visuel(val(nieme_mot(1))):dessiner_grille(20,5) if nieme_mot(0)="CN" then print add_neurone(nieme_mot(1)) if nieme_mot(0)="CE" N$=nieme_mot(1) N=val(N$) add_entree(N) endif endcase case 3 if nieme_mot(0)="CINOB" charger_image_N_ou_B(val(nieme_mot(1)),nieme_mot(2)) endif if nieme_mot(0)="IR" then reset_reseau(val(nieme_mot(1)),nieme_mot(2)) if nieme_mot(0)="MPA" then change_pas_apprentissage(val(nieme_mot(1)),val(nieme_mot(2))) endcase case 4 if nieme_mot(0)="CONR" Consulte_reseau(val(nieme_mot(1)),val(nieme_mot(2)),val(nieme_mot(3))) endif if nieme_mot(0)="CL" Creer_lien(val(nieme_mot(1)) ,val(nieme_mot(2)) ,val(nieme_mot(3))) Cprint(0,"Lien crée",0) endif if nieme_mot(0)="RL" N$=nieme_mot(1) N=val(N$) if N=0 then CPrint(0,"Vous devez specifier un numéro de neurone.",6) :exitfunction a$=nieme_mot(2) a=val(a$) b$=nieme_mot(3) b=val(b$) endif endcase case 5 if nieme_mot(0)="APPR" apprendre(val(nieme_mot(1)),val(nieme_mot(2)),val(nieme_mot(3)),val(nieme_mot(4))) endif endcase case 7 if nieme_mot(0)="CRBack" Creer_reseau_backprop(val(nieme_mot(1)),val(nieme_mot(2)),val(nieme_mot(3)),val(nieme_mot(4)),val(nieme_mot(5)),nieme_mot(6)) console2("auto") endif endcase endselect inc no_et endwhile endfunction `Fonction automatique de commande function auto(file$) free=free_file():open to read free,file$ read string free,commande$ cls set cursor 250,0 Cprint(0,"Commande :"+commande$,6) while commande$<>"fin" console2(commande$) read string free,commande$ Cprint(0,"Commande :"+commande$,6) endwhile close file free endfunction `Renvoi un fichier libre function free_file() for i=1 to 32 if file open(i)=0 then exitfunction i next i endfunction i function CPrint(a as float,phrase$,mode) select mode case 6 lon=len(phrase$) for i=1 to lon a$=mid$(phrase$,i) if a$="#" p$=left$(phrase$,i-1)+" : "+str$(a)+" " if i<lon then phrase$=p$+right$(p$,lon-i-1) : else : phrase$=p$ i=lon endif next i CPrint_Console(phrase$) endcase endselect `Pour debugguer sur fichier remstart case 7 if file open(31)=0 if file exist("debug.txt") then delete file "debug.txt" open to write 31,"debug.txt" endif lon=len(phrase$) for i=1 to lon a$=mid$(phrase$,i) if a$="#" p$=left$(phrase$,i-1)+" : "+str$(a)+" " if i<lon then phrase$=p$+right$(p$,lon-i-1) : else : phrase$=p$ i=lon endif next i write string 31,phrase$ endcase remend endfunction function CPrint_Console(phrase$) backdrop off ink rgb(255,255,255),rgb(0,0,0) if array count(console(0))<15 array insert at bottom console(0) else array delete element console(0),0 array insert at bottom console(0) endif console(array count(console(0)))=phrase$ cls set cursor 0,250 for i=0 to array count(console(0)) print console(i) next i endfunction function Extraire_mot(phrase$,separateur$) `Enleve les separateurs en mettant les mots dans un tableau `Nieme(nieme mot) indice_nieme=0 lon=len(phrase$) ancien_espace=0 for i=1 to lon a$=mid$(phrase$,i) if a$=separateur$ nieme_mot(indice_nieme)=mids(phrase$,ancien_espace+1,i-ancien_espace-1) inc indice_nieme ancien_espace=i endif next i nieme_mot(indice_nieme)=right$(phrase$,len(phrase$)-ancien_espace) inc indice_nieme endfunction indice_nieme ` Fonction mid$ pour version 6 function mids(s$ as string ,indice as integer,longueur as integer) if s$="" then exitfunction "" long=len(s$) s$=right$(s$,long-indice+1) long=len(s$) s$=left$(s$,longueur) endfunction s$ `Fonction pas belle pour dessiner ma grille function dessiner_grille(taille_carre,espacement) backdrop off cls for i=0 to xg for j=0 to yg if grille(i,j)=0 box i*taille_carre+espacement,j*taille_carre+espacement,i*taille_carre+taille_carre,j*taille_carre+taille_carre,rgb(0,0,0),rgb(0,0,0),rgb(0,0,0),rgb(128,128,128) else box i*taille_carre+espacement,j*taille_carre+espacement,i*taille_carre+taille_carre,j*taille_carre+taille_carre,rgb(255,255,255),rgb(255,255,0),rgb(0,0,0),rgb(255,255,255) endif next j next i endfunction ` Fonction pas belle pour dessiner dans ma grille function dessiner_dans_grille(taille_carre,espacement) backdrop off dessiner_grille(taille_carre,espacement) while spacekey()=0 mc=mouseclick() if mc>0 mx=mousex() : my=mousey() for i=0 to xg for j=0 to yg left=i*taille_carre+espacement top=j*taille_carre+espacement right=i*taille_carre+taille_carre bottom=j*taille_carre+taille_carre if mx>left if mx<right if my>top if my<bottom if mc=2 grille(i,j)=0 box i*taille_carre+espacement,j*taille_carre+espacement,i*taille_carre+taille_carre,j*taille_carre+taille_carre,rgb(0,0,0),rgb(0,0,0),rgb(0,0,0),rgb(128,128,128) else grille(i,j)=1 box i*taille_carre+espacement,j*taille_carre+espacement,i*taille_carre+taille_carre,j*taille_carre+taille_carre,rgb(255,255,255),rgb(255,255,0),rgb(0,0,0),rgb(255,255,255) endif wait 50 endif endif endif endif next j next i endif endwhile endfunction ` ------------------------------------------------------------------------ ` NEURONES ` ------------------------------------------------------------------------ FUNCTION Consulte_Neurone(N,layer,St) `N = Neurone ` On ne modifie rien dans le neurone. On le consulte `` Ici, si le neurone n'est pas ouvert,on l'ouvre `completement sans utiliser de MB temporaire valeur as float Somme as float entree as integer poid as float sortie as float `Le n° du MB est dans Liste_MB(0) for i=1 to neurone(N).nb_entree poid = Lit_poid(N, i) entree = lit_liaison(N,i) if entree=St valeur = stimulis(layer,pointeur_layer) inc pointeur_layer else valeur=neurone(entree).sortie endif Somme = Somme + valeur * Poid next i ` Ici, ca depend de la fonction de Transfert `du neurone. Sortie = _H(N,somme) CPrint(sortie,"Sortie #",4) neurone(N).sortie=Sortie ENDFUNCTION Sortie ` FONCTION DE TRANSFERT ` Cette fonction est appelée logistique. function _H(N,sortie as float) sortie=1.0/(1.0+exp(-sortie)) endfunction sortie function add_neurone(f_Transfert$ as string) `lien et ensuite poid `Taille de la memoire : 1+ 1float+1dword par entree array insert at bottom neurone(0) no=array count(neurone(0)) fm=free_memblock() MB(fm)=no array insert at top List_MB(0) array delete element List_MB(255) List_MB(0)=fm make memblock List_MB(0),1 neurone(no).Fonction=f_Transfert$ neurone(no).Erreur=0.5 endfunction no function detruire_tout() `Pas opérationnelle for i=0 to 255 List_MB(i)=0 next i for i=1 to 252 if memblock exist(i) then delete memblock i next i for i=1 to 65000 if object exist(i) then delete object i next i endfunction function Add_Entree(N) `Ajoute une entrée au neurone N rn as float nmb=N if nmb>0 make memblock 255,get memblock size(N) + 8 + 4 copy memblock nmb,255,0,0,get memblock size(N) delete memblock nmb make memblock nmb,get memblock size(255) copy memblock 255,nmb,0,0,get memblock size(255) delete memblock 255 neurone(N).nb_entree=neurone(N).nb_entree+1 rn=initialise_poid("rnd") Ecrit_poid(nmb,neurone(N).nb_entree,rn) else CPrint(0,"Le neurone "+str$(N)+" doit être ouvert pour ajouter une entrée !",6) endif endfunction function initialise_poid(mode$) ` Initialise un poid rn as float if mode$="rnd" rn=rnd(100) rn=rn/100 if rnd(1)=1 then rn=-rn else rn=0.0 endif endfunction rn Function Creer_Lien(N ,entree , sortieNP as integer) ` Crée un lien entre une entree existante et un neurone existant write memblock dword N , (entree-1)*4+8*entree+1, sortieNP endfunction function ecrit_poid(N, entree , poid as float) ` Ecrit le poid correspondant à l'entree du neurone write memblock float N , (entree-1)*(8+4)+1, Poid endfunction function lit_poid(N, entree) ` Renvoi le poid de l'entree du neurone poid as float poid=memblock float(N , (entree-1)*(8+4)+1) endfunction poid function lit_liaison(N, entree) `Renvoi le neurone connecté à l'entré liaison as integer liaison=memblock dword(N ,(entree-1)*4+8*entree+1) endfunction liaison function neurone_est_sortie(N) neurone(N).S=1 endfunction function cherche_entree(N,Ne) `recherche l'entrée connectée à Ne for i=1 to neurone(N).nb_entree if lit_liaison(N,i)=Ne then exitfunction i next i endfunction 0 function free_memblock() `Retourne -1 si tous les memblocks sont utilisés `Sinon no_memblock for i=1 to 252 if memblock exist(i)=0 then exitfunction i next i endfunction -1 ` ----------------------- NEURONE 3D -------------------------- function representation_reseau(reso) couche=0 N=0 Erreur as float while couche<3 while ordre(reso,couche,N)>0 select couche case 0 `couche entree make object sphere ordre(reso,couche,N),50 position object ordre(reso,couche,N),X0,0,couche*300 Erreur=neurone(ordre(reso,couche,N)).erreur inc X0,300 dec locale.nb_objet Line3D(locale.nb_objet, object position x(ordre(reso,couche,N)),object position y(ordre(reso,couche,N)),object position z(ordre(reso,couche,N)),object position x(ordre(reso,couche,N))-300,object position y(ordre(reso,couche,N)),object position z(ordre(reso,couche,N))-300 , rgb(10,128,255)) neurone(ordre(reso,couche,N)).indice_entree=locale.nb_objet endcase case default make object sphere ordre(reso,couche,N),100 position object ordre(reso,couche,N),X0,0,couche*300 Erreur=neurone(ordre(reso,couche,N)).erreur NC=couche-1 NN=0 neurone(ordre(reso,couche,N)).indice_entree=locale.nb_objet-1 while ordre(reso,NC,NN)>-1 dec locale.nb_objet Line3D(locale.nb_objet, object position x(ordre(reso,couche,N)),object position y(ordre(reso,couche,N)),object position z(ordre(reso,couche,N)), object position x(ordre(reso,NC,NN)),object position y(ordre(reso,NC,NN)),object position z(ordre(reso,NC,NN)), rgb(255,255,255)) inc NN endwhile inc X0,300 endcase endselect inc N endwhile N=0 inc couche X0=0 endwhile sync endfunction FUNCTION Line3D(Num_Objet, X1,Y1,Z1, X2,Y2,Z2, RGBValue) make object triangle Num_Objet, X1,Y1,Z1,X1,Y1,Z1, X2,Y2,Z2 SET OBJECT WIREFRAME Num_Objet,1 set object ambient Num_Objet,0 SET OBJECT EMISSIVE Num_Objet, RGBValue ENDFUNCTION function deplace_camera() if mouseclick()=2 backdrop on mmx=mousemovex() mmy=mousemovey() while mouseclick()=2 mmx=mousemovex() mmy=mousemovey() ocay#=locale.cay ocax#=locale.cax locale.cay=wrapvalue(locale.cay+mmx*0.2) locale.cax=wrapvalue(locale.cax+mmy*0.2) if upkey()=1 locale.x=newxvalue(locale.x,wrapvalue(locale.cay),vitesse_deplacement#) locale.z=newzvalue(locale.z,wrapvalue(locale.cay),vitesse_deplacement#) locale.y=newyvalue(locale.y,locale.cax,vitesse_deplacement#) position camera locale.x,locale.y,locale.z endif if downkey()=1 locale.x=newxvalue(locale.x,wrapvalue(locale.cay-180),vitesse_deplacement#) locale.z=newzvalue(locale.z,wrapvalue(locale.cay-180),vitesse_deplacement#) locale.y=newyvalue(locale.y,wrapvalue(locale.cax-180),vitesse_deplacement#) position camera locale.x,locale.y,locale.z endif a#=curveangle(locale.cay,ocay#,100) b#=curveangle(locale.cax,ocax#,100) yrotate camera a# xrotate camera b# sync endwhile Trace_graphique() endif endfunction ` ------------------------------------------------------------------------------------------ ` STIMULIS ` ------------------------------------------------------------------------------------------ function Fabrique_stimulis_visuel(layer) backdrop off print "Type de stimulis : Visuel" input "Taille de la grille en X :",xg input "Taille de la grille en Y :",yg dec xg dec yg dessiner_dans_grille(20,5) transformer_stimulis_visuel(layer) wait 150 input "Resultat attendu ?",a$ sti(layer).Resultat_espere=a$ backdrop on endfunction function transformer_stimulis_visuel(layer) Cprint(0,"Transformation du stimulis...",0) for i=0 to xg for j=0 to yg stimulis(layer,k)=grille(i,j) inc k next j next i if sti(layer).type2=0 then inc indice_layer sti(layer).type2=k-1 sti(layer).xg=xg sti(layer).yg=yg endfunction function reciproque_transformer_stimulis_visuel(layer) xg=sti(layer).xg yg=sti(layer).yg k=0 for i=0 to xg for j=0 to yg grille(i,j)=stimulis(layer,k) inc k next j next i endfunction function sauvegarder_stimulis(fichier$) free=free_file() if file exist(fichier$) then delete file fichier$ open to write free,fichier$ write string free,str$(indice_layer) for i=0 to indice_layer-1 write string free,sti(i).chaine_dossier write string free,sti(i).fichier write string free,sti(i).type write string free,str$(sti(i).type2) write string free,str$(sti(i).xg) write string free,str$(sti(i).yg) write string free,sti(i).Resultat_espere for a=0 to sti(i).type2 write string free,str$(stimulis(i,a)) next a next i write string free,"fin" close file free CPrint(0,"Stimulis sauvés",6) endfunction function charger_stimulis(fichier$) free=free_file() if file exist(fichier$)=0 then CPrint(0,"Le fichier n'existe pas !",6):exitfunction open to read free,fichier$ read string free,b$ indice_layer=val(b$) for i=0 to indice_layer-1 read string free,sti(i).chaine_dossier read string free,sti(i).fichier read string free,sti(i).type read string free,b$ sti(i).type2=val(b$) read string free,b$ sti(i).xg=val(b$) read string free,b$ sti(i).yg=val(b$) read string free,sti(i).Resultat_espere CPrint(0,"RE "+sti(i).resultat_espere,0) for a=0 to sti(i).type2 read string free,b$ stimulis(i,a)=val(b$) next a next i close file free endfunction function charger_image_N_ou_B(layer,fichier$) `Les fichiers images seront chargés et traité en tant que stimulis `Ici, on modifie l'image pour quelle n'est que des 0 ou 1 if file exist(fichier$)=0 then CPrint(0,"Le fichier n'existe pas !",6) : exitfunction load bitmap fichier$,1 if memblock exist(255) then delete memblock 255 ` On fabrique un memblock pour extraire les couleurs make memblock from bitmap 255,1 largeur=bitmap width(1)-1 hauteur=bitmap height(1)-1 for i=0 to largeur for j=0 to hauteur couleur=Couleur_Pixel(255, i, j) couleur=int((rgbr(couleur)+rgbg(couleur)+rgbb(couleur))/3) if couleur>127 couleur=0 else couleur=1 endif grille(i,j)=couleur next j next i delete bitmap 1 delete memblock 255 xg=largeur yg=hauteur transformer_stimulis_visuel(layer) CPrint(0,"Image transformee en stimulis.",6) if nb_reseau>0 then adaptation_sortie(reso) `Pour adapter le nombre de chose à apprendre avec le reseau endfunction Function Couleur_Pixel(nMB, x, y) `Merci au messieur qui a fait cette fonction, simple, efficace. Largeur_Image = MemBlock DWord(nMB,0) Position = 12 + (4 * ((y * Largeur_Image) + x)) Sortie = MemBlock DWord(nMB, Position) EndFunction Sortie ` ------------------------------------------------------------------------------------------ ` RESEAU ` ------------------------------------------------------------------------------------------ ` Fonctions relatives a la creation d'ensemble de neurones ` types de reseaux ` Backpropagation : Toutes les entrées du stimulis sont ` reliés à chaque entrée de chaque neurone ` Si l'on prend 010 equivalent à + ` 111 ` 010 ` Ce qui fait 010111010 ` on choisit le nombre de neurone d'entrée ` chaque neurone aura donc 9 entrées donc 9 poids ` Ce qui nous fait deja 81. ` ensuite on fabrique une couche intermédiaire de neurone ` appelé couche caché ` puis une derniere couche avec 1 neurone par caractere à apprendre ` Et biensure toute les entrées de chaque neurone sont reliés à toute les sorties ` des neurone de la couche caché ` Consultation: on consulte normalement chaque neurone d'entrée H(poid * entrée) ` On mettra ici une fonction sigmoide c'est a dire Sortie=1/(1+exp(-la phrase du dessus)))))) ` Pour l'apprentissage, on calcul l'erreur de la derniere couche (on connait les valeurs qu'elles doivent prendre) ` pour les propager selon le poid de l'entree reliant chaque neurone de la couche précedente . ` function Creer_reseau_backprop(no,nb_entree,nb_neurone_entree,nb_neurone_cache,nb_neurone_sortie,fonction$) ` Fonction permettant la création d'un fichier reseau backdrop inc nb_reseau if file exist("_tempo_lk")=1 then delete file "_tempo_lk" free=free_file():open to write free,"_tempo_lk" write string free,"rem Création des neurones d'entrée" for i=1 to nb_neurone_entree write string free,"CN "+fonction$ next i write string free,"rem Création des entrées et des liens" for a=1 to nb_neurone_entree for i=1 to nb_entree write string free,"CE "+str$(a) write string free,"CL "+str$(a)+" "+str$(i)+" 254" next i next a write string free,"rem -------------------" write string free,"rem Couche cachée" for i=1 to nb_neurone_cache write string free,"CN "+fonction$ next i write string free,"rem Création des entrées" for a=nb_neurone_entree+1 to nb_neurone_entree+nb_neurone_cache for i=1 to nb_neurone_entree write string free,"CE "+str$(a) write string free,"CL "+str$(a)+" "+str$(i)+" "+str$(i) next i next a write string free,"rem -------------------" write string free,"rem Couche de sortie" for i=1 to nb_neurone_sortie write string free,"CN "+fonction$ next i write string free,"rem Création des entrées" for a=nb_neurone_entree+nb_neurone_cache+1 to nb_neurone_entree+nb_neurone_cache+nb_neurone_sortie write string free,"NS "+str$(a) for i=1 to nb_neurone_cache write string free,"CE "+str$(a) write string free,"CL "+str$(a)+" "+str$(i)+" "+str$(nb_neurone_entree+i) next i next a write string free,"rem stipule que l'ordre du reseau est sauvé dans ordre" write string free,"Ordre" write string free,"REM pour avoir une representation 3D du reseau" write string free,"3D 0" write string free,"fin" close file free if file exist("ordre") then delete file "ordre" open to write free,"Ordre" ind=0 for i=1 to nb_neurone_entree ordre(no,0,ind)=i inc ind write string free,str$(i) next i write string free,"-1" ordre(no,0,ind)=-1 ind=0 for i=nb_neurone_entree+1 to nb_neurone_entree+nb_neurone_cache ordre(no,1,ind)=i inc ind write string free,str$(i) next i write string free,"-1" ordre(no,1,ind)=-1 ind=0 for i=nb_neurone_entree+nb_neurone_cache+1 to nb_neurone_entree+nb_neurone_cache+nb_neurone_sortie ordre(no,2,ind)=i inc ind write string free,str$(i) next i ordre(no,2,ind)=-1 write string free,"fin" close file free reseau(no).nb_neurone=nb_neurone_entree+nb_neurone_cache+nb_neurone_sortie+2 ` +2 car on met des 0 a chaque couche reseau(no).forme=1 reseau(no).pas_apprentissage=0.1 reseau(no).nb_sortie=nb_neurone_sortie endfunction ` Fonction généraliste prenant en compte la forme du reseau function Consulte_reseau(reso,Sti,layer) select reseau(reso).forme case 1 : Consulte_RBack(reso,Sti,layer) : endcase endselect endfunction `COnsultation propre au RBack function Consulte_RBack(reso,Sti,layer) sortie as float couche=0 N=0 while couche<3 select ordre(reso,couche,N) case -1 inc couche N=-1 endcase case default pointeur_layer=0 sortie=consulte_neurone(ordre(reso,couche,N),layer,Sti) endcase endselect inc N endwhile ` On ecrit les sorties dans la console couche=2 N=0 while ordre(reso,couche,N)>-1 Cprint(ordre(reso,couche,N),"Neurone #",6) CPrint(neurone(ordre(reso,couche,N)).sortie,"Valeur #",6) inc N endwhile ` On ecrit dans la 3D for i=1 to array count(neurone(0)) if neurone(i).S=0 SET object emissive i,rgb(0,255*neurone(i).Sortie,0) else SET object emissive i,rgb(0,0,255*neurone(i).Sortie) endif next i sync endfunction function verifie_reseau(reso) if file exist("Reseau.txt") then delete file "Reseau.txt" free=free_file():open to write free,"Reseau.txt" couche=0 N=0 poid as float while couche<3 while ordre(reso,couche,N)>-1 write string free,"Neurone "+str$(ordre(reso,couche,N)) for i=1 to neurone(ordre(reso,couche,N)).nb_entree write string free,"Entree "+str$(i) ll=lit_liaison(ordre(reso,couche,N),i) write string free,"Reliée à "+str$(ll) Poid = lit_poid(ordre(reso,couche,N),i) write string free,"Poid = "+str$(poid) next i inc N endwhile N=0 inc couche endwhile close file free endfunction ` ------------------------------------------------- ` APPRENTISSAGE ` ------------------------------------------------- function apprendre(nb_fois,reso,layer,Sti) if reseau(reso).forme=1 then apprendre_back(nb_fois,reso,layer,Sti) endfunction `fonction d'apprentissage par backpropagation function apprendre_back(nb_fois,reso,layer,Sti) if reseau(reso).sorties_adaptees=0 then adaptation_sortie(reso) if layer=-1 then layer=rnd(indice_layer-1):ly=-1 poid as float ll as integer Erreur as float sortie as float TOTAL_ERREUR as float `Extraction des résultats à obtenir `A modifier plus tard, lent... nb_mot=extraire_mot(sti(layer).resultat_espere," ") dim result_espere(indice_layer,nb_mot+1) as float for i=0 to indice_layer-1 nb_mot=extraire_mot(sti(i).resultat_espere," ") for m=0 to nb_mot result_espere(i,m)=val(nieme_mot(m)) next m next i ` S'il y a 6 stimulis a différencier, 6 tours=1 apprentissage complet for nbf=1 to nb_fois `CONSULTATION DU RESEAU couche=0 N=0 while couche<3 select ordre(reso,couche,N) case -1 inc couche N=-1 endcase case default pointeur_layer=0 sortie=consulte_neurone(ordre(reso,couche,N),layer,Sti) pointeur_layer=0 endcase endselect inc N endwhile ` Boucle de propagation de l'erreur ` On démarre de la couche de sortie pour comparer ` ce que l'on doit avoir et ce que l'on a. couche=2 N=0 while couche>-1 select ordre(reso,couche,N) case -1 dec couche N=-1 endcase case default select couche case 2 ` couche de sortie Erreur = (result_espere(layer,N) - neurone(ordre(reso,couche,N)).Sortie) Erreur = Erreur /(2*(1+Hcos(neurone(ordre(reso,couche,N)).Sortie))) Ajoute_graphique(N+1,Erreur) TOTAL_ERREUR=TOTAL_ERREUR+abs(Erreur) Neurone(ordre(reso,couche,N)).Erreur=Erreur endcase case 1 ` Couche cachée ` On regarde le poid des entrees des neurones de sortie ` Que l'on multiplie par son erreur(du neurone de sortie) ` On fait la somme de tous ça NC=2 NN=0 Erreur = 0 while ordre(reso,NC,NN)>-1 entree=cherche_entree(ordre(reso,NC,NN),ordre(reso,couche,N)) Erreur = Erreur + neurone(ordre(reso,NC,NN)).erreur*lit_poid(ordre(reso,NC,NN),Entree) inc NN endwhile ` On applique la dérivé de H sur l'erreur Erreur = Erreur /(2*(1+Hcos(neurone(ordre(reso,couche,N)).Sortie))) neurone(ordre(reso,couche,N)).Erreur=Erreur endcase case 0 `Couche d'entrée ` Identique à l'autre couche. elle est séparée pour améliortion ulterieure NC=1 NN=0 Erreur = 0 while ordre(reso,NC,NN)>-1 entree=cherche_entree(ordre(reso,NC,NN),ordre(reso,couche,N)) Erreur = Erreur +neurone(ordre(reso,NC,NN)).erreur*lit_poid(ordre(reso,NC,NN),Entree) inc NN endwhile ` On applique la dérivé de H sur l'erreur Erreur = Erreur /(2*(1+Hcos(neurone(ordre(reso,couche,N)).Sortie))) neurone(ordre(reso,couche,N)).Erreur=Erreur endcase endselect endcase endselect inc N endwhile `Modification des poids `formule : poidNi=poidNi+pa_app*erreurNi*sortie_du neurone avant ` Ni est le poid du neurone en question ` pa_app est le pas d'apprentissage ` Sortie du neurone avant c'est le neurone relié à l'entrée du neurone en question couche=0 N=0 while couche<3 while ordre(reso,couche,N)>0 select couche case 0 `couche entree car neurone avant=stimulis for i=1 to neurone(ordre(reso,couche,N)).nb_entree poid=lit_poid(ordre(reso,couche,N),i) poid=poid+reseau(reso).pas_apprentissage*neurone(ordre(reso,couche,N)).erreur*stimulis(layer,i-1) ecrit_poid(ordre(reso,couche,N),i,poid) next i endcase case default for i=1 to neurone(ordre(reso,couche,N)).nb_entree poid=lit_poid(ordre(reso,couche,N),i) ll=lit_liaison(ordre(reso,couche,N),i) poid=poid+reseau(reso).pas_apprentissage*neurone(ordre(reso,couche,N)).erreur*neurone(ll).Sortie ecrit_poid(ordre(reso,couche,N),i,poid) next i endcase endselect inc N endwhile N=0 inc couche endwhile if ly=-1 layer=rnd(indice_layer) else inc layer endif if layer=indice_layer layer=0 Ajoute_graphique(0,TOTAL_ERREUR) ` on met a jour la sortie sur la 3D if nb_graphe=-1 for i=1 to array count(neurone(0)) if neurone(i).S>0 erreur=abs(neurone(i).Erreur) SET OBJECT EMISSIVE i,rgb(255*erreur,255*(1-erreur),0) else SET object emissive i,rgb(255*(1-neurone(i).Sortie),255*neurone(i).Sortie,255*(1-neurone(i).Sortie)) endif next i sync else `Ou bien l'erreur sur le graphe Trace_graphique() endif TOTAL_ERREUR=0.0 endif next nbf Trace_graphique() CPrint(0,"Apprentissage terminé",6) endfunction `Remet les poids à rnd ou zero function reset_reseau(reso,mode$) couche=0 N=0 while couche<3 while ordre(reso,couche,N)>0 for i=1 to neurone(ordre(reso,couche,N)).nb_entree ecrit_poid(ordre(reso,couche,N),i,initialise_poid(mode$)) next i inc N endwhile N=0 inc couche endwhile CPrint(reso,"Initialisation du reseau #",6) endfunction function adaptation_sortie(reso) `Fonction inscrivant le resultat espere dans sti `Par exemple, si on a 4 lettre à lui faire apprendre, il faut 4 sorties ` Il stocke dons dans sti de la lettre a : 1 0 0 0 `Dans sti de la lettre b : 0 1 0 0 if indice_layer<>reseau(reso).nb_sortie CPrint(0,"Incompatibilité du nombre de stimulis",6) exitfunction endif dim sortie(reseau(reso).nb_sortie) as string for i=0 to reseau(reso).nb_sortie for a=0 to reseau(reso).nb_sortie if i<>a sortie(a)=sortie(a)+"0 " endif next a sortie(i)=sortie(i)+"1 " next i for i=0 to indice_layer-1 sti(i).resultat_espere=left$(sortie(i),len(sortie(i))-1) next i reseau(reso).sorties_adaptees=1 CPrint(0,"Adaptation du reseau terminée",6) undim sortie(0) endfunction function change_pas_apprentissage(reso,pas as float) reseau(reso).pas_apprentissage=pas endfunction `--------------------------------------------------------------------------- ` TRACE DES GRAPHIQUES `--------------------------------------------------------------------------- ` Fonction permettant de tracer des graphiques d'une variable quelquonque ` Elle s'adapte en X et en Y ` Par contre, vous perdez la linéarité d'une fonction mathématique lorsque vous dépassez G_TX valeurs. ` Attention quand meme, cette fonction est gourmande et ralentit bcp le programme ` Mais elle peut être très utile pour débuguer un programme ` Par exemple, vous voulez connaitre la valeur que prend tableau a chaque modification de tableau ` Vous avez juste à faire dans l'editeur, remplace ` remplace : tableau= par Trace_graphique(0,tableau) : tableau= ` Mais attention, dans ce cas, vous tracer la valeur precedente... ` Ou simplement le mettre manuellement dans le code ex: tableau=x à remplacer par tableau=x:Trace_graphique(0,tableau) function Ajoute_graphique(couleur as integer,valeur as float) rem if couleur=-1 then exitfunction ` Couleur représente la no de la courbe ` couleur=0 --> rouge ` couleur=1 --> vert ` couleur=2 --> bleu ` couleur=3 --> blanc `si vous tracer un seul graphique (nb_graphe=0) dans ce cas, si vous mettez couleur=1 alors le graphique ne sera pas tracé ` mais la valeur sera quand meme enregistré ` Valeur est tous simplement la valeur à ajouter au graphe(couleur) select couleur case 0 if G_r=G_TX then compresse_rouge() G_rouge(G_r)=valeur inc G_r if abs(valeur)>Rmaxvar then Rmaxvar=abs(valeur) endcase case 1 if G_v=G_TX then compresse_vert() G_vert(G_v)=valeur inc G_v if abs(valeur)>Vmaxvar then Vmaxvar=abs(valeur) endcase case 2 if G_b=G_TX then compresse_bleu() G_bleu(G_b)=valeur inc G_b if abs(valeur)>Bmaxvar then Bmaxvar=abs(valeur) endcase case 3 if G_bl=G_TX then compresse_blanc() G_blanc(G_bl)=valeur inc G_bl if abs(valeur)>BLmaxvar then BLmaxvar=abs(valeur) endcase endselect endfunction function Trace_graphique() Backdrop off cls ink rgb(255,255,255),rgb(0,0,0) line G_x,G_y,G_x+G_Tx,G_y line G_x,G_y,G_x,G_y+G_Ty line G_x+G_Tx,G_y,G_x+G_Tx,G_x+G_Ty line G_x,G_y+G_Ty,G_x+G_Tx,G_y+G_Ty GT as integer GT1 as float GT2 as float GT3 as float GT4 as float GT=(G_TY+G_Y) GT1=G_Ty/Rmaxvar GT2=G_Ty/Vmaxvar GT3=G_Ty/Bmaxvar GT4=G_Ty/BLmaxvar ` On dessine le graphe rouge ink rgb(255,126,126),rgb(0,0,0) line G_X+1,GT,G_X+G_Tx,GT ink rgb(255,0,0),rgb(0,0,0) for i=1 to G_Tx if G_rouge(i)>0 y=G_rouge(i)*GT1 dot G_X+i,GT-y else `Cas d'un valeur négative: A VERIFIER y=G_rouge(i)*GT1+G_TY dot G_X+i,GT-y endif next i if nb_graphe>0 `On dessine le graphe vert ink rgb(0,255,0),rgb(0,0,0) for i=1 to G_Tx if G_vert(i)>0 y=G_vert(i)*GT2 dot G_X+i,GT-y else y=G_vert(i)*GT2+G_TY dot G_X+i,GT-y endif next i if nb_graphe>1 `On dessine le graphe bleu ink rgb(0,0,255),rgb(0,0,0) for i=1 to G_Tx if G_bleu(i)>0 y=G_bleu(i)*GT3 dot G_X+i,GT-y else y=G_bleu(i)*GT3+G_TY dot G_X+i,GT-y endif next i if nb_graphe>2 `On dessine le graphe blanc ink rgb(255,255,255),rgb(0,0,0) for i=1 to G_Tx if G_blanc(i)>0 y=G_blanc(i)*GT4 dot G_X+i,GT-y else y=G_blanc(i)*GT4+G_TY dot G_X+i,GT-y endif next i endif endif endif sync endfunction function compresse_rouge() for i=0 to G_Tx-2 array delete element G_rouge(0),i+1 array insert at bottom G_rouge(0) next i G_r=int(G_Tx/2) endfunction function compresse_vert() for i=0 to G_Tx-2 array delete element G_vert(0),i+1 array insert at bottom G_vert(0) next i G_v=int(G_Tx/2) endfunction function compresse_bleu() for i=0 to G_Tx-2 array delete element G_bleu(0),i+1 array insert at bottom G_bleu(0) next i G_b=int(G_Tx/2) endfunction function compresse_blanc() for i=0 to G_Tx-2 array delete element G_blanc(0),i+1 array insert at bottom G_blanc(0) next i G_bl=int(G_Tx/2) endfunction |