ニューラルネットワーク作ってみた。
マッチ箱の脳が面白そうだったので、マッチ箱で作るNNを作ってみた。
紹介されてるニューラルネットワークは、凄く単純な仕組みで、
- 判断が間違ってたら怒る。
- 情報を修正(学習)する。
繰り返せば正しい判断をするようになる。というもの。
ふむふむ。実装してみる。
(define (make-node name point value) (letrec ((study (lambda (my-method child-medhod l) (display "study...") (my my-method) (display (format " ~a : ~a" name point)) (for-each (lambda (node) (node child-medhod) (display (format " ~a : ~a" (node 'get-name) (node 'get-point)))) l))) (my (lambda (m) (case m ('get-name name) ('get-value value) ('get-point point) ('inc! (set! point (+ point 1))) ('dec! (set! point (- point 1))) ('master (lambda l (let ((point-sum (fold (lambda (node acc) (+ (node 'get-point) acc)) 0 l)) (value-sum (fold (lambda (node acc) (+ (node 'get-value) acc)) 0 l))) (if (< point-sum point) (begin (display "買います。 ") (if (<= value-sum value) (display " : OK") (begin (display " : NG : ") (study 'dec! 'inc! l)))) (begin (display "買いません。") (if (<= value-sum value) (begin (display " : NG : ") (study 'inc! 'dec! l)) (display " : OK"))))))))))) my))
アドバイザは外にあったほうがいい気もする。まぁいいや。
サンプルと同じように500円のお菓子問題を解いてみる。
(define a (make-node 'a 6 500)) (define b (make-node 'b 1 310)) (define c (make-node 'c 3 220)) (define d (make-node 'd 8 70)) ((a 'master) b c d) ; 買いません。 : OK ((a 'master) b c ) ; 買います。 : NG : study... a : 5 b : 2 c : 4 ((a 'master) b d) ; 買いません。 : NG : study... a : 6 b : 1 d : 7 ((a 'master) b ) ; 買います。 : OK ((a 'master) c d) ; 買いません。 : NG : study... a : 7 c : 3 d : 6 ((a 'master) c ) ; 買います。 : OK ((a 'master) d) ; 買います。 : OK ((a 'master) b c d) ; 買いません。 : OK ((a 'master) b c ) ; 買います。 : NG : study... a : 6 b : 2 c : 4 ((a 'master) b d) ; 買いません。 : NG : study... a : 7 b : 1 d : 5 ((a 'master) b ) ; 買います。 : OK ((a 'master) c d) ; 買いません。 : NG : study... a : 8 c : 3 d : 4 ((a 'master) c ) ; 買います。 : OK ((a 'master) d) ; 買います。 : OK ; ... ((a 'master) b c d) ; 買いません。 : OK ((a 'master) b c ) ; 買いません。 : OK ((a 'master) b d) ; 買います。 : OK ((a 'master) b ) ; 買います。 : OK ((a 'master) c d) ; 買います。 : OK ((a 'master) c ) ; 買います。 : OK ((a 'master) d) ; 買います。 : OK (a 'get-point) ; 7 (b 'get-point) ; 4 (c 'get-point) ; 4 (d 'get-point) ; 2
数回繰り返すと、正しい判断を返すようになる。
実行する順番によって、値は変わるみたいだけど、b + cはNG。b + d, c + dはOKになるように収束するみたいだ。
面白いのは、値に対して学習してる訳じゃなくて、怒られたからマッチの数を変えてるって所。
全く計算をしてないのに、正しい解を返せるようになる。不思議だ。