アソシアトロン の原理

人工知能の分野では、ディープラーニングなどの階層的ニューラルネットワークが脚光を浴びている。確かに、驚くべき成果を挙げているのだから、それは当然のことである。しかし、それが人間の脳のニューラルネットワークをシミュレートしているかといえばそうではないだろう。ディープラーニングが、その基礎的パーツとして神経回路網的構造を持っていることは確かだが、人間の脳もそのようにシステマティックに階層化されたネットワーク層を積み重ねているとは到底思えない。

人間の脳は、もっと非構造的システムのはずだ。脳には、領域ごとに違った機能を果たしていることはわかっている。しかし、その領域そのものが莫大な冗長性を持ったものであり、漠然とした機能の瞬間的作用から、人間の意識を想像している感じなのである。

そのように考えていた時、アソシアトロン というものに出会った。実は、私が30年以上前、岩手大学にいた頃、今のディープラーニングにつながるニューラルネットワークを研究していた頃、すでにこのアソシアトロン というものは世に出されていた。名前は知っていたのだ。が、当時の、バックプロぱゲーションなどを実装した並列処理システム、ニューラルネットワークの勢いの中で、真剣に考えてみたいテーマではなかったから、具体的にどのように実装するなどというところまでは全く行かなかった。

しかし、今この時に、改めてその内容を捕まえてみると、とても興味深い。そうだ、人間の脳は、きっとこんな感じなのだと思わせる、単純で、それでいてニューラルネットワークらしい漠然として機能を有している気がしてきた。

改めて、その理論の中身を捉えてみた。それは以下にまとめておいた。

アソシアトロン の原理
アソシアトロン の原理

この原理説明のpdf文書を見ていただければ明らかなように、このアソシアトロン が必ずしもそのものではない情報から記憶を再現できるのは、パターンが、そのパターンの次元倍のネットワークの中に、パターン情報を分散させるからなのである。原理的なアイデアはこれに尽きると思う。

今日のコンピュータ機能の進化した状況の中で、この単純さと優れた機能は改めて見直されるべきだと思う。

prolog化した『羅生門』を二分木検索する

prologのファクト文に変換した「羅生門」をどう使っていくか、使う過程で、さらにprolog化の方法をどう改良していくかが、次の課題となっている。

どう使っていくかの手始めに、先の羅生門の全文二分木化したものを検索するルールを使ってみよう。先の二分木を改良したもの(したがってJAVAプログラムそのものも改良)に、ルールを加えたswi-prolog用のスクリプトをzipで圧縮したものを以下においておく。

rashomon.zip

ダウンロードし、unzipする。冒頭に、検索のprologルールが記載され、その後、羅生門全文の二分木になっている。冒頭のルールだけを再掲すると以下のようなものである。

%%%%%%%%%%%%%%%%%%%%%%%%%
%% 「羅生門」の二分木探索
%%%%%%%%%%%%%%%%%%%%%%%%%
%%% 節(1)
% 右葉の探索
% 見つけたら、その語以外(AおよびB)を取得する
rsearch(S,node(A,B,S),A,B).
% リストの場合も受け入れる
rsearch(S,node(A,B,L),A,B) :- member(S,L). %% リストの場合の処理
% 上で一致しなかったら、左右のノードの内側を調べる
rsearch(S, node(_, Y, _), A, B) :- rsearch(S, Y, A, B).
rsearch(S, node(_, _, Z), A, B) :- rsearch(S, Z, A, B).
% 左葉の探索:基本右葉と同じ
lsearch(S,node(A,S,B),A,B).
lsearch(S,node(A,L,B),A,B) :- member(S,L).
% ここは、右と全く同じになる
lsearch(S, node(_, Y, _), A, B) :- lsearch(S, Y, A, B).
lsearch(S, node(_, _, Z), A, B) :- lsearch(S, Z, A, B).

%%% 検索、表示(2)
% 検索語を右側にした部分文章
right(X) :- rashomon(P,T),rsearch(X, T, A, B),write(P),write(': '),printnode(B),printnode(A),printnode(X),nl.
% 検索語を左側にした部分文章
left(X) :- rashomon(P,T),lsearch(X, T, A, B),write(P),write(': '),printnode(X),printnode(A),printnode(B),nl.

%%% ノードの表示(3)
% 対象がatomならば、そのまま表示
printnode(N) :- atom(N),write(N).
% 対象が空でないリストならば、最初の項の表示
printnode(N) :- [X|_] = N,printnode(X). 
% 対象が空リストならば'/'(半角スラッシュの表示)
printnode(N) :- [] = N,write('/'). %% 空リストでもtrueにする
% 対象がnodeならば、元の言葉の順序で表示(葉がnodeならば再帰的に表示する:ただし、node語がnodeは含まない)
printnode(N) :- node(X,Y,Z) = N,printnode(Y),printnode(X),printnode(Z).

このprologは、二分木の右の葉から語句を検索するものと、左の葉から検索するものの、二つのルールからなっている。

実行例を以下に示そう。

$ swipl ← ターミナルからswirl-prologを起動する
Welcome to SWI-Prolog (threaded, 64 bits, version 7.6.4)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit http://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

1 ?- ['rashomon.swi']. ← 解凍したRashomon.swiを読み込む
true.

2 ?- left(下人). ←  左の葉から、「下人」を検索する、パラグラフ、行番号とともに結果が出力される。1行しか示されないので、次を示すためには; セミコロンを入れる
line_0_1: 下人が羅生門の下で雨やみを待っていた/
line_3_6: 下人は七段/ある/石段の一番上の段に洗い/ざらした/紺の襖の尻を据えて/右の頬に出来た//大きな面皰を気にしながらぼんやり/雨のふるのを眺めていた/
line_4_0: 下人が雨やみ
line_4_1: 下人は雨がやんでも格別/どう/しようと云う/当てはない//
line_4_6: 下人が雨やみ
line_4_6: 下人が行き所がなくて/途方にくれていたと云う/方が適当である//
line_4_7: 下人のSentimentalismeに影響//
line_4_9: 下人は何をおいても差当り明日の暮しをどうにか/しようと云わば/どうにも/ならない事をどうにか/しようととりとめもない/考えをたどりながらさっきから朱雀大路にふる/雨の音を聞くともなく/聞いていたのである/
line_6_3: 下人の考え
line_6_5: 下人は手段
line_7_0: 下人は/大きな嚔をして/それから大儀/そうに立/上った//
line_8_0: 下人は頸をちぢめながら山吹の汗袗に重ねた/紺の襖の肩を高くして門のまわりを見まわした/
line_8_4: 下人はそこで腰にさげた/聖柄の太刀が鞘/走らないように気をつけながら藁草履をはいた/足をその/梯子の一番下の段へふみかけた/
line_9_4: 下人は始め
line_10_0: 下人は守宮のように足音をぬすんで/やっと/急な/梯子を一番上の段まで這うようにして上り//
line_12_0: 下人はそれらの死骸の腐爛/した/臭気に思わず/鼻を掩った/
line_13_0: 下人の眼はその/時/はじめて/その/死骸の中に蹲っている人間を見た//
line_14_0: 下人は六分の恐怖と四分の好奇心とに動かされて暫時は呼吸をするのさえ忘れていた/
line_15_0: 下人の心から
line_16_0: 下人には勿論/何故/老婆が死人の髪の毛を抜くかわからなかった/
line_16_2: 下人にとってはこの/雨の夜にこの/羅生門の上で死人の髪の毛を抜くと云う/事がそれだけで既に/許す/べからざる悪であった/
line_17_0: 下人は両足
line_20_0: 下人は老婆が死骸につまずきながら慌てふためいて/逃げようと行手を塞いで/こう/罵った//
line_20_2: 下人はまたそれを行かすまいと押しもどす//
line_20_5: 下人はとうとう/老婆の腕をつかんで/無理に/そこへ○/じ/倒した//
line_22_0: 下人は老婆
line_22_3: 下人は始めて/明白に/この/老婆の生死が全然/自分の意志に支配れていると云う/事を意識//
line_22_6: 下人は老婆
line_26_0: 下人は老婆の答が存外/平凡なのに失望//
line_29_0: 下人は太刀を鞘におさめて/その/太刀の柄を左の手でおさえながら冷然として/この/話を聞いていた/
line_29_2: 下人の心には/ある勇気が生まれて来た/
line_29_5: 下人は饑死をするか盗人になるかに迷わなかったばかりではない/
line_31_0: 下人は嘲るような声で念を押した//
line_33_0: 下人はすばやく/老婆の着物を剥ぎとった//
line_33_3: 下人は剥ぎとった/檜皮色の着物をわきにかかえて/またたく間に/急な/梯子を夜の底へかけ/下りた//
line_35_0: 下人の行方は誰も知らない/

3 ?- right(下人). % 続いて、右の葉から「下人」を検索する
line_4_5: 今/この/下人
line_15_4: この/下人
line_15_4: 恐らく/下人
line_16_3: 勿論/下人
line_20_1: それでも下人
line_24_0: その/下人
line_24_4: 喘ぎ喘ぎ/下人

左の葉から下人を選択すると、下人についてのアクティブな文章を出力される。右の葉の場合は、もっと、受動的なものとなるが、下人がそのような受動的な扱いをされている文章がより少ないことがわかる。それがどこの文章に当たるかは、冒頭の line_XX_XX の部分でわかる。

どのような文章を引き出すかは、その文章に関するリスト構造と、ルートフレーズをどのように設定してあるかに依存する。