2008-11-08  Excel/Visioでニューラルネットワーク

連休中に多層パーセプトロン型のニューラルネットワークの実験をしました。

「唐突に何言ってるの?ニューラルネットワークって何?」と思った人がいるかもしれません。ニューラルネットワークは,生物の脳の神経細胞を数理的なモデルにしたものだそうです。説明しているサイトは山ほどあるので,興味のある人は検索してみてください。

ニューラルネットワークは,学術的には人工知能のひとつだとされています。人工知能ってコトバは何やら怪しげで,別世界の高度な処理を指しているかのように思えるかもしれません。なんてことはありません。細部を見れば数値を足したり・引いたり,メモリをコピーしたり,処理を条件分岐しているだけです。現在のコンピュータで実現できるのですから,当然なのです。

私は今後,人工知能サービスを整備していくつもりでいます。人工知能と呼ばれているものには数種類ありますが,「ニューラルネットワーク」「制約充足問題」「遺伝的プログラミング」の3本柱をぜひ習得したいと思っています。得られた成果物は,アルゴリズム株取引の売買判定や,アルゴリズム・アフィリエイトの商品の最適化などに使います。

第一弾として,Microsoft Officeにニューラルネットワークを実装してみました。経緯と実験結果をお話します。

準備

じつは私,ニューラルネットワークと無縁だったわけではないのです。学生時代,お向かいの研究室のお題がニューラルネットワークだったのです。何度かそのゼミの研究発表を見ていたので,どんなものなのかはだいたい知っていました。でも当時は大した興味はなくて,「これって何に使うんだろうね」くらいにしか思っていませんでした。

時は流れて2008年,私は自力でニューラルネットワークを実装してみることにしました。今回,主に参考にした本は「臼井支朗」先生らによる「基礎と実践ニューラルネットワーク」です。この本もそうなのですが普通の専門書では,ニューラルネットワークを数式で説明しています。見慣れない用語もいっぱい出てきて,私の能力で理解できるのか心配になってしまいました。以下に,遭遇した専門用語を並べてみますね。

  • ニューロンの値
  • ニューロンの学習率
  • エラー値
  • モーメンタム因数
  • 重み
  • 重み変更係数
  • バイアス重み
  • バイアス値

最初の難関は「これらの要素が何に属するものなのか」を正確に理解することでした。ニューラルネットワークは,広義にはグラフ(度数分布表のことではなくて「頂点と辺の集合」のこと)です。要素は,「頂点」または「辺」のどれかに属するのです。数式の意味を紐解いて,グラフに当てはめていくことにしました。

つぎの難関は「何をどうやって作るのか,何ができれば良いのか,何をやらないのか」を決めることでした。この手のシステムは,目指すべき世界がはっきりしていないといけません。曖昧なままでは,できたものが役に立たなかったり構造が歪になったりしてしまうのです。要件を箇条書きにします。

  • 抽象度を落さない
  • 処理速度,メモリ効率は重視しない
  • 学習方法には誤差逆伝搬法(バックプロパゲーション法,Error Back Propagation Method)を使う
  • 扱うニューロンの数は100未満
  • 学習中の過程,学習結果,ニューラルネットワークの特性をグラフィカルに表現・出力できるようにする
  • ニューラルネットワークを数式に展開し,Excelで使える関数を出力する機能

Excel VBA/Visio VBAでニューラルネットワーク

ニューラルネットワークの数理的なモデルと,ソフトウェアの要件が分かったような気分になったところで,実装方法を詳しく検討することにしました。

巷には,C/C++言語で書かれたニューラルネットワークのサンプルプログラムが溢れています。これを活用しない手はありません。オライリージャパンの「ゲーム開発者のためのAI入門」と「集合知プログラミング」という本にニューラルネットワークのサンプルプログラムが載っていたので,VBAで実装する際はこれらのコードを参考にすることにしました。

つぎはデータ構造のお話です。たいていのニューラルネットワークのサンプルプログラムは,隣接行列表現(ようは2次元配列)で書かれているようです。私は隣接行列表現ではなくて,隣接リスト表現を採用することにしました。ニューロンとニューロン同士の関係をオブジェクトにして,モデルの抽象度をほどんと変えずに実装することにしました。しかし,データ構造を大胆に変えたがために,入手したサンプルプログラムはほとんど役に立たなくなってしまいました。

どうして,わざわざ遠回りしたのかというと「ニューロンに自律的な振る舞いをさせたい」という思惑があったのです。ニューロンを指して「あなたのいまの値は?」と尋ねれば,値が返ってくるようにしたかったのです。学習中にはニューロンオブジェクトが能動的に描画オブジェクトを書き換えて,ニューラルネットワークの様子をグラフィカルに構築するようにしたかったのです。

静的構造図

<画像の説明>ソフトウェアの静的構造です。UML風に描いてみましたが,UMLの細かい決まりを意識しているわけではありません。しかも,このままではVBAの言語仕様から逸脱しているのです。実際にはVBAに合わせながら実装しました。

静的構造が決まったところで,Excel VBAで実装してみることにしたのだが,大問題に気づきました。辺(Edge)を表現する描画オブジェクトに「コネクタ」を使っていたのだが,Excelのコネクタにはテキスト属性が存在しないのです。これでは辺の値を表示できません。いやはや調査不足でした。急遽,Visio VBAに載せ替えることにしました。

余談ですが,ExcelとVisioでは描画周りのフレームワークにほとんど共通点がないのですね。派生元の文化の違いを垣間見た気がしました。

XOR問題を解かせてみたら

ソフトウェアが仕上がったので,2入力のXOR(排他的論理和)をニューラルネットワークで解いてみることにしました。

XORのニューラルネットワーク 入出力の特性

<画像の説明>学習後のニューラルネットワークと,入出力の特性を図にしてみました(ニューラルネットワークはVisio上に半自動で描画されます)。

「普通,XORの入出力は2値なんだから,入出力が連続値(実数)なのはおかしい」と思った人がいるかもしれません。どんな形の関数なのか見たかったので,連続値を入力してみたのです。

「XOR演算できたからといって,何の意味があるの?ニューラルネットワークなんか使わなくても計算できるんじゃないの?」と思った人もいるかもしれません。XOR演算は,この業界の基本例題なのです。例題は例題であって,それ以上の意味はありません。

ついでにニューラルネットワークをVisual Basic相当の式に展開してExcel VBAの関数にしてみました(下のコード)。あまり見かけない形式かもしれません。

Public Function nnxor(i1 As Double, i2 As Double) As Double

    Dim h1, h2, o1 As Double

    h1 = 1 / (1 + Exp(-(i1 * 5.75629288124718 + i2 * 5.87868353255397 - 2.3117209662348)))
    h2 = 1 / (1 + Exp(-(i1 * 2.91199452973333 + i2 * 2.93085382671416 - 4.39555060504074)))
    o1 = 1 / (1 + Exp(-(h1 * -6.92972808917433 + h2 * 7.85290876041432 + 2.83947285639982)))

    nnxor = o1

End Function

最後に,気づいたことと残された課題を箇条書きにして終わりにします。

  • ソフトウェアが正確に仕上がっているのか,十分に検証できていない
  • 学習過程をグラフィカルに表現する必要はなかったようです。グラフが書き換わる様子をアニメーションで見られるのは面白いはずだと思っていたのだが,実際にやってみるとネットワークが成熟していくようには見えませんでした。期待外れ