最近ニューラルネットワークにはまってます。小さなノード群が数学的問題を脳のように解決するなんて、夢があるじゃないですか。Schemeで実装してみようと思い立ったのが数日前の話だが、なかなか実装が思い通りにいかない。階層状のデータ構造を扱うのはSchemeを筆頭としたLISP語族では得意な処理だけど、NNは「Neural」の語義通り網目状のデータ構造を持ってる。階層と言うより重みつきグラフのような代物だ。NLPの動作原理さて、ここで改めてMLPについて解説しようと思います。layer)、出力層の三層に分かれており、複数の計算ノードが不可視層と出力層に配されています。それぞれのノードは無限個の入力と唯一の出力を持ちます。ノードは入力の個数に対応した「重み」を保持しており、それぞれの入力に重みを掛けた数値の和、つまり入力と重みの内積(ドット積)から、さらにバイアス数値を引き、それを判断関数に通したものを出力として返します。バイアス数値はノードの判断の閾値を決定し、判断関数によってノードの解答は0から1までの数値に正規化されます。判断関数にはシグモイド関数がよく利用されるようです。入力層には数値のリスト(場合によってはペア)が与えられます。不可視層のノードは入力層の数値を入力に取り、計算した値を出力します。同じように出力層のノードは不可視層のノードと接続されており、入力を計算して最終的な数値を出力します。実装まずノード単体のふるまいを関数にする。入力のリスト、重みのリスト、バイアス数値を受け取り、数値を返す関数を作成。あとはどんどん下層から上層に向かってfoldしていけばいい(?)実装上の課題ここでいくつかの問題が浮上する。多対多の網構造はGaucheでは扱いにくいので一対多の平坦な木構造に展開する必要がある。複雑な網だと莫大なメモリを消費する。重みは固定だがノードの入力は下層ノードの計算を待たなければならない。これによってノードの構造の記述が静的でなくなる。できたらノードの構造記述と計算処理は分離したい。この二つの問題が解決すべきものはおおよそ共通している。網構造というのは暗黙のうちに参照先をメモ化しているはずだ。木構造に展開したときの問題は、前もって下層の解答を用意しておき、それを後から参照させることで解決できる。いうわけで網構造を完全に分解して「このノードはこのノードを参照しているよー」「ノードの重みリストはこれだよー」というふうにしてしまう。これを動的にパースしていけば、求めている解を導出できる。ついでに第二の問題も半分解決できる。グラフの構造をグラフィカルにS式で記述して、これをパーサにかけて先述の形式に変換する。これで明快にノードの構造を記述できる。これによりマクロな分析は困難になるが、ミクロな方向に計算をシフトすることで問題は解決できた。入力パラメータをミクロ形式/マクロ形式に代入する関数まとめこのコーナーはまだ(当分)つづくと思う。週間)Web開発者です。Lisp/Perl/Goまわりの話題が多いです。月別アーカイブスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。