脳神経系をモチーフにした言語Neuronyを作りました

…と言いたいところですが、教師あり学習教師なし学習が同じ構造のニューラルネットワークで実現できることを示したところでタイムアップになってしまいました。昨日の「遺伝子をモチーフにした言語「Genomy」を作りました」にかぶせるネタの予定だったのに…。

機械学習と一言で言ってもいろいろな種類がありますが、その中の大きな分類に「教師あり学習」と「教師なし学習」があります。教師あり学習はザックリいえば「データと、それがどう分類されるべきかの正解情報を渡して学習させて、データを分類できるようになる」ことが目的で、教師なし学習は「正解なしでデータだけたくさん与えられて、その中からなんとなく似ているものをまとめて分類を作り出す」ことが目的です。

で、同じ形のネットワークに対して、3つの基本操作(シナプス[Wikipedia]を通した興奮の伝搬、長期増強[Wikipedia]、側抑制[Wikipedia])の組み合わせ方を変えることで教師あり学習教師なし学習の両方を作り出すことができます。っと言うのを今回実際にコードを書いて確認しました。

実際に教師あり学習教師なし学習ソースコードを比較してみると、教師ありの方で「出力ニューロンに正解の値をset」している部分が、教師なし学習では「入力ニューロンから出力ニューロンに興奮を伝搬(propagate)し、出力ニューロンに側抑制を掛ける(winner_takes_all)」という処理に置き換わっているだけなのがわかります。

--- supervised	2011-12-27 19:27:36.000000000 +0900
+++ unsupervised	2011-12-27 19:26:56.000000000 +0900
@@ -1,16 +1,16 @@
-def supervised():
+def unsupervised():
     input = Neurons(mapper=LEDMapper())
     output = Neurons(mapper=CharMapper("01"))
     net = Network(input, output)
-    answer = "010101"
     for i in range(100):
-        for d, ans in zip(DATA, answer):
+        for d in DATA:
             input.set(d)
-            output.set(ans)
+            net.propagate()
+            output.winner_takes_all()
             net.learn()
 
     for d in DATA:
         input.set(d)
         net.propagate()
         print d, output.get()
         print

これを実際に実行してみると、教師あり学習でも、教師なし学習でもちゃんと動くことがわかります。

下が教師あり学習で識別した例:

++++.
+..+.
+..+.
+..+.
++++. 0

..+..
.++..
..+..
..+..
..+.. 1

.++++
.+..+
.+..+
.+..+
.++++ 0

..+..
.++..
..+..
..+..
.+++. 1

下が教師なし学習で分類した例(教師なし学習の方は0の形をした入力が0である旨を教えないので、この例では、1をクラスタ0、0をクラスタ1に分類しています):

++++.
+..+.
+..+.
+..+.
++++. 1

..+..
.++..
..+..
..+..
..+.. 0

.++++
.+..+
.+..+
.+..+
.++++ 1

..+..
.++..
..+..
..+..
.+++. 0

とまあこういうモデル部分を作った上で、ニューロンとその間のネットワークがプリミティブであるような言語を作って「じゃあ加算器を作りましょう。まず加算の学習データを作って1000回くらい学習させます。はいadd関数に相当するネットワークが出来ました」みたいなことを言うつもりだったけど時間がなくなってしまったので今回はここまで。

ソースコードはこちら: https://github.com/nishio/neurony/blob/master/main.py