ニューラルネットワーク応用
明日から一泊かけて、数万円の金を払って出張のような旅行のような、
よくわからない理科の学習会に行く。うちの市は今年はホストなので強制参加である。
楽しいのだろうか・・。
いまいち不安。で、ふと気がつくともうずいぶんと日にちがたっている。
今日は、学校にカメラを取りに行くついでに草抜きや、金魚のえさや、
読書をしたりした。夏休みは土日はほとんど誰もいない。
SE時代から比べると考えられん。
と、現在SEやPGな方に自慢しておくことにする。
その代わり残業代がないのがつらい。
あと、話は変わって、難関突破の神社で武蔵坊弁慶がいたので、写真で撮った。
久しぶりにきれいに撮ることができた。
私の写真で撮った重たいデータは↓。
http://ymlabo.ddo.jp/~ymlab/picture/P7291720.JPG
OLYMPUS E-330 f/6.3 1/160s ISO-100 f=180mm
■
ニューラルネットワーク応用。
やっと学習した後、解く。という意味がわかった。
つまり、out値が教師信号と一致していたら、学習したことになる。
ということである。
これを今日理解するまで1年かかった。
やはりSUGSIのシステム上しかたがないことなのかもしれないが、
学習する相手がいないのはつらい。
教えたり教えてもらったりする人が絶対に必要である。
と、昔の指導教官の先生もいってたなぁ。
「だから、京大っていうのは、ドクターからマスターまでいるから、そこで、
教え、教えられる風土があるから強い。」と。
今、ものすごく身にしみて感じている。
おそらく、SUGSIの先生もそれがわかっているので、
SUGSIの掲示板サービスを作ったのだろうが、
http://cai.cs.shinshu-u.ac.jp/cgi-bin/bbs/Yorozu/mqbbs.cgi
いまいち、そういう系には機能していないのが、現実である。
これを、簡単なRSSで配信とかしてくれるだけで相当違うと思うが・・。
また、各教科ごとに一覧で確認できる掲示板がほしい。これはWikiで実装することにしよう。
そういうわけで、超簡単な
http://ipr20.cs.ehime-u.ac.jp/column/neural/chapter4.html
をプログラミングできた。
<?php //4.2節 誤り訂正学習法の学習例 //http://ipr20.cs.ehime-u.ac.jp/column/neural/chapter4.html $isContinueRoutine = 1; $w = array(0,0,0); //荷重 $x = array(1,-500,-500);//入力信号 (x0は、常に1) $y = array(0,1,1,1); //教師信号 これになったらOK $iLearnNum = 0; //学習回数. while ( $isContinueRoutine != 0 ) { $iLearnNum++; $isContinueRoutine = 0; $net = 0; //net値を一応初期化する. //入力パターンは4つある. $isContinueRoutine = 0; $x[0]=1;$x[1]=0;$x[2]=0; $isContinueRoutine += trial($w, $x, $y[0]); $x[0]=1;$x[1]=0;$x[2]=1; $isContinueRoutine += trial($w, $x, $y[1]); $x[0]=1;$x[1]=1;$x[2]=0; $isContinueRoutine += trial($w, $x, $y[2]); $x[0]=1;$x[1]=1;$x[2]=1; $isContinueRoutine += trial($w, $x, $y[3]); print "isContinueRoutine is ". $isContinueRoutine."\n"; } print "$iLearnNum 回の学習で終了しました.\n"; print "実際に確かめてみましょう.\n"; $x[0]=1;$x[1]=0;$x[2]=0; print "■x=($x[0],$x[1],$x[2])=\t".f(getNET($w,$x))."\n"; $x[0]=1;$x[1]=0;$x[2]=1; print "■x=($x[0],$x[1],$x[2])=\t".f(getNET($w,$x))."\n"; $x[0]=1;$x[1]=1;$x[2]=0; print "■x=($x[0],$x[1],$x[2])=\t".f(getNET($w,$x))."\n"; $x[0]=1;$x[1]=1;$x[2]=1; print "■x=($x[0],$x[1],$x[2])=\t".f(getNET($w,$x))."\n"; //重みの変更の確認まで. function trial(&$w, $x, $y){ $isChangeWeight = 0; print "----------x[0]=$x[0] x[1]=$x[1] x[2]=$x[2]----------\n"; $net = getNET($w, $x); print "net = $net\n"; $out = f($net); $val = $out-$y; print "out-y = ".$out."-".$y."=[$val]\n"; print "old w = ($w[0],$w[1],$w[2])\n"; if ( $val > 0 ) { print "重みの変更あり.減らす方向で。\n"; $isChangeWeight = 1; $w = reChangeWeight(-1, $w, $x); } else if ( $val < 0 ) { print "重みの変更あり.増やす方向で。\n"; $isChangeWeight = 1; $w = reChangeWeight(1, $w, $x); } else { print "重みの変更なし\n"; } print "new w = ($w[0],$w[1],$w[2])\n"; return $isChangeWeight; } // } /** 重みの変更をする. * @param plusminus 増やす方向か、減らす方向か. */ function reChangeWeight($plusminus, $w, $x) { for ( $iCounter = 0; $iCounter < count($w); $iCounter++ ) { $w[$iCounter] = $w[$iCounter]+$plusminus*$x[$iCounter]; } return $w; } /** net値を求める. * net値は、 w1*x1+w2+x2である. * @param w 重み * @param x 入力 * @return iRet net値. */ function getNET ($w, $x) { $dwRet = 0.0; for ($i = 0; $i <= count($w); $i++) { $dwRet += $w[$i]*$x[$i]; } return $dwRet; } /** net値をもとに、f関数にかけてoutを求める. * @param $net net値 * @return iRet out値 */ function f($net) { $iRet = -100; if ( $net >= 0 ) { $iRet = 1; } else { $iRet = 0; } return $iRet; } ?>