ちょっとニューラルネットワークで試したいことがあるので,最初の段階として,PyBrainを用いてニューラルネットワークというものを使用してみる.
階層型ニューラルネットワークの例題としてXOR演算を学習させる.
以下,コード
from pybrain.datasets import SupervisedDataSet from pybrain.tools.shortcuts import buildNetwork from pybrain.supervised.trainers import BackpropTrainer # Set teaching signals target = SupervisedDataSet(2, 1) target.addSample([0, 0], [0]) target.addSample([0, 1], [1]) target.addSample([1, 0], [1]) target.addSample([1, 1], [0]) network = buildNetwork(2, 2, 1) trainer = BackpropTrainer(network, target) # Training for n in range(100000): error = trainer.train() print "%d %f" % (n, error) if error < 0.0001: break print "f(0, 0) = %f" % network.activate([0, 0]) print "f(0, 1) = %f" % network.activate([0, 1]) print "f(1, 0) = %f" % network.activate([1, 0]) print "f(1, 1) = %f" % network.activate([1, 1])
PyBrainはコードが簡単なのはいいですね.
何回か試して見たが,重み関数の初期条件よっては収束しないことが結構あるようだ.横軸が学習回数で,縦軸がエラーである.
最初,急に誤差が減ってきて,減り方が緩やかになって,再び急になるという気持ち悪い学習の仕方をしている.
エラーが0.0001の場合の出力値は以下.
f(0, 0) = 0.020374 f(0, 1) = 0.987520 f(1, 0) = 0.987359 f(1, 1) = 0.007329
思ったより誤差が大きい.
収束しなかった場合の出力値は
99999 0.064225 f(0, 0) = 0.002815 f(0, 1) = 0.499337 f(1, 0) = 0.996132 f(1, 1) = 0.502938
と
99999 0.064870 f(0, 0) = 0.004271 f(0, 1) = 0.998503 f(1, 0) = 0.500618 f(1, 1) = 0.504393
どちらもエラーが0.064ぐらいで,出力のうち2つが0.5となっている.なんか対称的な点でぐるぐる回ってそう.
(追記 多分,最急勾配法で解いてるから普通に別の極地点極値点にハマっただけか?)
差分法で流体の方程式と解く時のチェッカーボード不安定性とか,有限要素法で構造解析するときの(名前忘れたけど)扇型の変形モードが要素ごとに交互に起こって,エネルギーが吸収される現象を連想する.
PyBrainが古いだけなのか,まだ安定な解法が見つかっていないだけなのか.
大規模になると大変そうだな.
追記2 2014-12-30
pybrainのbuildNetworkで作られる出力層がデフォルトだとLinearLayerになっている. LinearLayerは活性化関数がf(x)=xである.つまり重みを足し合わせるだけで何もしない. つまり多層パーセプトロンでない. なんでこれでXORが学習できたのだ?今度考える.
参考
Pybrainでsin関数を学習させるサンプル | anopara
- 作者: C.M.ビショップ,元田浩,栗田多喜夫,樋口知之,松本裕治,村田昇
- 出版社/メーカー: 丸善出版
- 発売日: 2012/04/05
- メディア: 単行本(ソフトカバー)
- 購入: 6人 クリック: 33回
- この商品を含むブログ (16件) を見る
- 作者: 平野廣美
- 出版社/メーカー: パーソナルメディア
- 発売日: 2008/06/10
- メディア: 単行本
- クリック: 17回
- この商品を含むブログ (4件) を見る