セマンティックウェブ・ダイアリー

小出誠二の個人的な業務日誌

2016年09月

人工知能プログラミングの本を執筆中ですが,その第22章は「Elizaまたの名を人工無脳」というタイトルです(20章まではCommon Lispプログラミングの話,21章以下が人工知能の話です).以下は第22章のまとめの節の内容です.


Elizaのしていることは,入力パターンに応じた出力をしているだけで,文の意味を理解しているわけではない.短期記憶も長期記憶も無ければ,世界に関する知識もない.短期記憶がなければ直前の会話の内容を踏まえた応答もできないわけで,人工知能ならぬ人工無脳と言われる所以である.しかし1960年代に作られたElizaは,人間の認知メカニズムについての知見が大きく進んだ現在でも,知能とは何かという根本的な問いを我々に投げかけている.対話エージェントの原型とも言えるこのプログラムに,形態素解析機能をつけ,構文解析機能をつけ,照応解析機能をつけ,意味解析機能をつけたら,それは人工知能と言えるのだろうか?

短期記憶のない認知症の患者でも,一見認知症とは思えないほどの会話のやりとりをするのを見ると,短期記憶のないElizaでもElizaルールを次々と拡張して,一体どこまで行けるのか,軽度の認知症患者を真似るところまで行けるのかという疑問がわく.逆に,何ができれば人工知能といえるのか,Elizaに何を追加すれば人工知能になるのか,記憶は必要だろうが,そのほかの機能は何が必要なのか,一体会話を理解するとはどういうことなのかという疑問も.

一方,この程度のプログラムでも,人間の振る舞いを真似るプログラムに人間の側が大きく動かされてしまうという事実も,人間と人工知能との関係に注意すべき点があるということを教える.会話動作を含めて外見上行動が人間的でありさえすれば,ヒトは人工物でも相手を同類と捉えてしまう.Siriは少し会話を進めるとたちまち馬脚を現わしてしまって,Siriに没入する人はいないが,会話型エージェントの代表格は今では映画「her」に登場するサマンサであろう.この映画では主人公とサマンサとの感情の交流とサマンサの成長・進化が軸となってストーリーが展開していく.つまり,ヒトは人工物と感情の交流が可能であることが前提とされている.この場合問題となるのが個体性の問題である.一見相手は自分と唯一の関係を持っているように見えながら,実はサマンサは同時に8316人の人間と個別の会話をし,641人の自分と同じような恋人がいることを知ったとき,主人公は愕然としてしまう.はたしてエモーショナル・エンジンを持つエージェントに個体性は必然なのか.

人間に分かりやすくするために,対話型システムでは時々擬人化エージェントが利用される.たとえば,映画「A.I.」では歓楽街Rouge Cityの中でどんな質問にも答えてくれるエージェントDr. Knowが登場するが,それはいかにもそれっぽい「博士」みたいな風貌をしているし,スカリー時代のAppleが作ったプロモーションビデオ「Knowledge Navigator」に登場するエージェントは「執事」という位置づけになっている.一方,スタートレックやSpace OdysseyのHALのように,宇宙船全体を統括するような全体制御システムは,インタフェースとしての対話機能があっても擬人化されないようだ.それはシステム全体を代表する存在なのだ.CortanaやSiri APIがデベロッパーにも公開されることになって,改めてこれから知的インタフェースとしての対話機能や個別タスク用擬人化エージェントの研究開発が進むであろうが,1960年代に開発されたElizaは対話機能の原型を提示したものとして,歴史的な意義がある.


Elizaのプログラムもあるこの本を入手したいかたはPayPal経由でこちらから入手できます.

世の中にクロージャについてどう使えばいいのか理解したいという要求があるようです.

クロージャというのは,言うまでもなく関数の一種ですが,引数のみでなく,関数定義時に見える変数も環境として内部に含むものです.と言っても分からないひとにはやっぱり分からないわけで,以下に私が最近出版した電子書籍からの該当部の一部抜粋を示します.ただし,これを読んでも最適な使用例がないので,どういうものかは分かってもどう使えばよいか分からないだろうということに気が付きました.


7.1 関数閉包

第4章で特殊変数,大域変数を導入し,静的束縛と動的束縛の議論をした.本章ではさらにその議論を深めて,最初に関数閉包(closure)について知ってもらい,そのうえで変数の参照に関するスコープと値確立に関するエクステントの概念を理解してもらう.

論理の世界では論理式に現れる論理変数が全称記号∀や存在記号∃により限量されているとき,これを変数束縛と言う.論理変数がその式中では変数束縛されていないとき,その変数を自由変数と言う.論理式では自由変数があるとそれだけでは論理式の真偽値は定まらない.ラムダ計算における式においても,λ変数(たとえば λx P(x) の場合の x )を束縛変数と呼び,そうでないもの(たとえば λx P(x, y) の場合の y )を自由変数と言う.

Lisp 関数においても自由変数の値が定まらない限りは,関数が評価できない.たとえば,次のように関数 foo と関数 bar があった場合,変数 x は関数 foo にとっては束縛変数だが,関数 bar にとっては自由変数である.

cl-user(13): (defun foo (x) 
(print x))

foo
cl-user(14): (defun bar ()
(print x))

bar

だから,関数 foo は常に実行できても,関数 bar は実行できない場合がある.

cl-user(15): (foo 1)
1
1
cl-user(16): (bar)
Error: Attempt to take the value of the unbound variable `x'.[condition type: unbound-variable]

では,次のようなコードではどうだろうか.

cl-user(1): (defun make-foo-bar ()
(let ((x 10))
(defun foo (x) (print x))
(defun bar () (print x)))
)

make-foo-bar
cl-user(2): (make-foo-bar)
bar
cl-user(3): (foo 1)
1
1
cl-user(4): (bar)
10
10

Common Lisp では関数の中で関数を定義することもできる.defun による定義は必ずしもトップレベルで行わなくてもよいが,その効果は常にグローバルである.つまりdefunで定義された関数はどこからでも参照され得る.この例では関数 bar における x は bar にとっては自由変数であるが,それは静的スコープにおいて make-foo-bar 中に現れる let 変数 x であることは実施例からも明らかである.つまり,関数 bar を定義した時,その自由変数 x として,その時の静的スコープで決まる変数が捕捉される.このとき値が捕捉されるのではなく,あくまでもその変数そのものが捕捉されることに注意されたい.次の例を見られたい.

cl-user(5): (defun make-bar1 ()
(let ((x 10))
(defun bar1 ()
(print x))
(setq x 100)
))

make-bar1
cl-user(6): (make-bar1)
100
cl-user(7): (bar1)
100
100

let 変数としての x は初期値 10 であるが,それが関数 bar1 に捕捉される.これはもちろん make-bar1 が実行されたときに,関数 bar1 が定義されて起こることである.同時にそのとき, x の値は 100 に関数 bar1 の外で,設定しなおされる.結果はご覧のとおり.つまり,静的変数ならば関数定義時の自由変数はその関数によってそのときの値が捕えられるのではなく,変数そのものが捕えられて,関数ごとどこへでも持ちまわられることになる.それが関数閉包というものである.




やっぱりこれではだからどうなのという感はぬぐえませんね.

私の意見では,変数の秘匿+変数の共有+外部環境依存の手続き=クロージャ です.つまり複数の関数集合が他の関数からは見ることができない変数を共有することができて,しかもその変数の値によって関数集合のふるまいを変えることができる,そういう最適な事例を思いついたら,上記内容に追加修正を行いたいと思います.

このページのトップヘ