ニューラルネットワーク作ってみた。

マッチ箱の脳が面白そうだったので、マッチ箱で作る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になるように収束するみたいだ。


面白いのは、値に対して学習してる訳じゃなくて、怒られたからマッチの数を変えてるって所。

全く計算をしてないのに、正しい解を返せるようになる。不思議だ。

おぉっと

おもろい記事を見つけた。

人工知能も深いな。