http://www.neuromuse.org/lefrigo/pulse3G-learn(demo).lisp
;Ce fichier est
a l'origine destine a etre execute dans MCL (Macintosh Common Lisp,
Digitools), sans ;OpenMusic (IRCAM).
;L'interface est
donc le niveau commandes lisp, a executer les unes apres les autres.
;premiere ligne :
(defvar
test-score '(#(0.1 0.9 0.9 0.1) #(0.9 0.9 0.1 0.9) #(0.1 0.9 0.9 0.1)
#(0.9 0.9 0.1 0.9) #(0.1 0.9 0.9 0.1) #(0.9 0.9 0.1 0.9) #(0.1 0.9 0.9
0.1) #(0.9 0.9 0.1 0.9))
)
;ou je defini
une partition arbitraire sur 4 temps : 0.1 pour un temps faible, 0.9
pour les termps forts.
;Les marques
rythmiques- arbiraires - sont ainsi definies sur 4 temps.
;ensuite avec la
commande
(setf pulse3g
nil) ; definition d'une variable "pulse3G"
;puis on defini un mlp a la
jordan, recurrent, 8 inputs (4 + 4 re-injectes de la couche recurente),
4 outputs, et une couche de 4 cellules
(mlpJ pulse3g 8
4 4)
; on defini
l'architecture recurrente du reseau :
(setf
(recurrent-layer pulse3g) 0) ; rang de la couche cachee recurente
(setf
(in-size pulse3g) 4) ; taille reelle de l'entree du reseau
(setf
(recurrent-layer-activation pulse3g) #(0 0 0 0)) ; activation
inititale de la couche cachee
;a ce stade, si
on est dans OM, le reseau pulse3g doit pouvoir etre trouve et instancie
dans OM (avec la fonction find-net par exemple dans neurOMuse)
(setf *MAINSTOP*
nil) ; variable de stop general pour la boucle d'apprentissage
(defvar
*memlost* 0) ; variable liee a la perte de memoire du reseau
(inspect
pulse3g) ; permet de voir le contenu lisp du mlp pulse3g
(make-instance
'main-ann-window :ann pulse3g) ; fenetre interface du mlp
(make-trace-window
*history-error* 1 50 "") ; trace de l'erreur, a executer pour
chaque mise a jour
;et maintenant
on lance la boucle d'apprentissage:
;pour chaque
mesure de 4 temps, on apprend la mesure suivante:
(loop until
*MAINSTOP*
do
(dotimes (k 50)
(format t "~%STEP K = ~S~%" K)
(when (null *MAINSTOP*)
(learn pulse3g
(butlast test-score)
(cdr test-score)
:temp .005
:slope (+ .99 (random .02))
:learn (+ .05 (random .1))
:error .001
:stop 100 ;(- 500 (floor (* 10 k)))
:thresh 1.0
:input-func nil
:out-func #'logistic
:hidden-func #'logistic
:method 'sequence
:monitor t
:verbose nil))
)
)
|#
;ensuite on fait
une copie pour bckp du mlp
;et on regarde
ce qu'il fait dans differents contextes de temperature, de perte de
memoire, de souplesse (fonction transfert) :
(make-trace-window
(apply
#'append (mapcar #'(lambda (x) (coerce x 'list)) test-score))
6
100 "test-score")
(make-trace-window
(let ((r
(list (elt test-score 0))))
(setf (recurrent-layer-activation pulse3g) #(0 0 0 0))
(dotimes (n 50 (apply #'append (lvectors->ldl (reverse r))))
(push (run-mlpj pulse3g (car r)
:out-func #'logistic ;
;<- fonction de transfert des couches de sortie
:hidden-func #'logistic ;
;<- fonction de transfert des couches cachees
:thresh 1. ;
;<- seuil d'activation
:temp .0 ;
;<- temperature du reseau
:slope .9) ;
;<- pente des courbes de transfer des "neurones"
r)))
6 100
"pulse3g run")
(make-trace-window
(let ((r
(list (elt test-score 0))))
(setf (recurrent-layer-activation pulse3g) #(0 0 0 0))
(dotimes (n 100 (apply #'append (lvectors->ldl (reverse r))))
(dotimes (n (length (recurrent-layer-activation pulse3g)))
(setf (elt (recurrent-layer-activation pulse3g) n)
(+ (elt (recurrent-layer-activation pulse3g) n)
(- (random *memlost*) (/ *memlost* 2)))))
(push (run-mlp pulse3g (car r)
:out-func #'logistic
:hidden-func #'logistic
:thresh 1.
:temp .0
:slope .99)
r)
))
6 100
"pulse3g run")
;; jouer avec le
coeff de perte de memoire : bruit sur les connections !
(setf
*memlost* .0)
(setf
*memlost* .4)
(setf
*memlost* 3.0)
;; on
peut recuperer l'etat precedent avec la fonction
(setf (net
pulse3g) (previous pulse3g)) ; au cas ou...
(save
pulse3g) ; on sauve le reseau...
;fred