第135回 解禁 マインド・エンジンソースコード


第135回 解禁 マインド・エンジンソースコード

このチャンネル、AIエンジニアとかをターゲットにしてたんですけど、どうもうまく届かないみたいです。
このチャンネルを本にした「ドラえもんの心のつくり方」、アマゾンで出して、嬉しいレビューももらうんですけど、そうでないレビューを書いてる人って、AIに携わってる人が多いみたいなんですよ。

優秀な技術者は、みんなこう言ってます。
これからはAIの時代だって。

それで、GoogleのTensorFlowとか勉強してます。
プログラム言語はPythonです。
そうやって最新の技術を身に着ければ、キャリアアップ、転職の世界で引っ張りだこになるわけです。

そう言う人からみれば、僕の書いてること、何の役にも立たないっての、よく分かります。
僕の書いてることって、いまのAIで、意識は生まれるのかとか、
コンピュータで言葉の意味を理解できるのかとか。
根本的な問題を投げかけてるわけです。

でも、AIエンジニアにとっては、AIが意識を持つかどうかなんて、あんまり興味ないんですよね。
そんなこと勉強しても、転職に有利にならないですから。
だから、僕のチャンネルや本に興味がある人って、AIに興味がある人は少ないんです。
じゃぁ、どんな人が多いかって言うと、バラバラなんですよ。
哲学だったり、教育だったり、お医者さんだったり、たぶん、普通のサラリーマンが一番多いと思います。
いろんな分野に、たぶん、数%だけ、こんな根本的なことに興味がある人がいるみたいです。
だから、僕のチャンネルは伸びないんですよ。

えーと、そういう話がしたかったわけじゃないです。
今回は、前回の続きです。
前回の第134回「意味とは、こういうことだったのか!」で紹介したマインド・エンジン第4弾です。
ついに、マインド・エンジン第4弾のソースコードをお見せします!

ただ、このチャンネルを真剣に見てくれてる人は、どうも、プログラムのソースコードなんか見たこともない人が多いみたいんですよ。
だから、そういう人に配慮して、初心者でもわかるように説明しようと思います。

これを見れば、人が無意識に行ってる処理を、どうやって解明して、プログラムで実現するかが分かってくると思います。
いままで、哲学者や言語学者が頭の中だけで考えていたこと。
それを、コンピュータっていう、超具体的なもので、検証できるってことが分かると思います。
意識とか心とかって曖昧なものが、じつは、めちゃくちゃシステマティックに動いてるってことに気づくと思います。
僕が一番、見てもらいたいのは、ここなんです。
何千年と人類が頭の中で考えてきたことを、人類史上、初めて、客観的に、頭の外につくり出して検証できるようになったんですよ。
めちゃくちゃ、興奮するでしょ。
それでは、始めます。

今回、取り上げるのは、超絶簡単な文です。
「鉛筆を筆箱に入れる」
これだけです。

簡単すぎて、理解もなにもないって思うでしょ。
この、簡単すぎる文っていうのが、じつは、一番難しいんです。
読んでも何も感じないから、つい、何も処理してないって思うんですよ。
でも、違うんですよ。
裏で、めちゃくちゃ、いろんな処理をしてるんですよ。

でも、いろんな処理してるって、どうやったら実感できるでしょう?
それは、「それ、おかしない?」って思うときです。

筆箱より大きな箱を用意して、
「箱を筆箱に入れる」って文を読んだら、
「そんなの、入るわけないよ」って思いますよね。
「鉛筆を筆箱に入れる」じゃ、何ともおもわなかったのに、それ、おかしいよって思ったわけです。
つまり、何も感じないから、何も処理してないってことじゃないんです。
無意識で、いくつか判断をして、それが問題ないから何にも感じないわけです。
その無意識で判断してることを、丁寧にプログラムで作ろうってわけです。

筆箱に鉛筆が入るのは、問題なくて、筆箱に箱が入るのはおかしいって思うこと。
それって、大きさを見てるわけでしょ。
頭の中んで、どっちが大きいかを判断してるわけです。
大きさの判断って、3Dデータを使えばできますよね。
だから、3Dゲームの開発環境を使って、大きさの判断を行うわけです。

まず、全体の動きの確認からしましょう。
マインド・エンジンは、マインド・エンジン本体と、3次元世界から構成されていて、3次元空世界が3Dゲーム開発環境のUnityで作られています。
マインド・エンジン本体は、C#で作られています。

それでは、「鉛筆を筆箱に入れる」を、マインド・エンジン本体から実行します。
ドン
Unity側では、まず、鉛筆オブジェクトを作って、次に、筆箱オブジェクトを作って、その後、筆箱に鉛筆を入れます。
このとき、鉛筆が中に入ったことを分かりやすくするために、筆箱を半透明にします。
そして、入った鉛筆の中心座標を返します。
これが成功したときの動きです。

次は、失敗するときです。
「箱を筆箱に入れる」です。
箱オブジェクトと筆箱オブジェクトが登場するとこまでは同じです。
その後、筆箱オブジェクトに入らないと判断すると、それぞれの大きさを表示して、入らないことを示します。
結果は、「result:failure」「Size mismatch」が返ります。

それでは、先ほどの「鉛筆を筆箱に入れる」をもう一度、詳しく見ていきましょう。

マインド・エンジン本体からUnityに送られるコマンド文がこれです。
「鉛筆を筆箱に入れる」って日本語を、マインドエンジンが理解できる言葉に変換したものです。

まずは、この文を解説します。
Trajector:Name:7707ってあるでしょ。
Trajectorが中に入れる物です。
つぎは、7707です。
マインド・エンジンでは全ての単語を、この概念ツリーで管理してます。

文房具の下の鉛筆系概念の下に鉛筆があるでしょ。
TGIDが7707ってなってるでしょ。
TGIDってのは、単語概念IDってことです。
だから、Trajector:Name:7707は、入れる物が鉛筆って意味なんですよ。

その次にLandmark:2026ってありますけど、Landmarkは入れ物のことです。

2026は、容器・収容具概念以下の机の収納具の中にある筆箱のことです。

それから、一番重要なのが、”Command:Put In”です。
これが、「入れる」です。
つまり、この文は、「鉛筆を筆箱に入れる」って意味を表してるんです。
これをUnityで実行するわけです。

これが、UnityのPutIn関数です。
つまり、「入れる」のプログラム、その物です。

それでは、中身を見て行きましょう。
InstantiateObjectsってのが、オブジェクトを生成するってことです。

オブジェクトは、元々はどこにあるかと言うと、Prefabsってフォルダ以下に、ファイルとして保存されてるわけです。
これが、それをUnityでみた画面です。

これを7707とかって名前を指定して、呼び出すとメモリ上に鉛筆オブジェクトが生成されるわけです。

これって、人間で言うと、長期記憶ってわけです。
意味記憶ですね。
鉛筆って名前を聞いたとき、名前でファイルを検索して、見つかったらメモリ上に3Dオブジェクトを生成するわけです。
3Dオブジェクトは、3D形状のデータを持っているので、どんな形か、長さはどのくらいか、先っぽが尖ってるかといったことが理解できるわけです。
ファイルのままじゃ、中身はわからないです。
メモリ上に展開して、初めて、形や大きさがわかるんです。
大脳皮質にあるデータを取り出して前頭葉で展開して、それを意識が認識するって感じです。
ね、ゲーム開発環境を使えば、人間が頭の中で行ってることを、そっくりそのまま実現できるって意味、これで、わかりますよね。

次は、この文を解説します。
if (GetContainerObject().PutIn(_Trajector))
return ReturunPosition(_trajector);

じつは、今回のメインはここなんですけど、まずは、全体の流れを先に説明しときますね。
GetContainerObjectってのは、コンテナーオブジェクトを取得しろって意味です。
ここでいうコンテナーオブジェクトが何を指すかと言うと、容器・収納具概念なんです。
これです。

容器収容具概念がPutInって動詞の実質的な中身を持っていて、_Trajector、つまり、鉛筆を中に入れるって処理を行うわけです。

ifってありますけど、これがプログラムで必須のif文っていうやつです。
もし、次のかっこ内の文を、実行したらって意味です。
実行して、成功したら次の行に進んで、失敗したらその次の行に進むってわけです。

次の行のreturnってのは、結果を返すって意味です。だから、
return ReturnPosition(_Trajector);
ってのは、中に入った鉛筆の位置を返すってことです。

その次の行、
ShowSize();
ってのは、PutInに失敗したとき、大きさを表示するってことです。

それじゃぁ、一番重要な説明に進みましょう。

少し戻って、3Dオブジェクトの生成のとこです。
入れ物オブジェクトですけど、単に3Dオブジェクトを生成するだけじゃないんですよ。
その部分のソースコードがこれです。

重要なとこだけ説明します。ます、この行、
var tg = obj.GetComponent();
で、TGIDを取得するわけです。
このとき取得するのは、単に筆箱のTGIDだけじゃないんですよ。
筆箱の上位概念のTGIDを全部取得するんですよ。
ほんで、次の行で、Container.TGIDが含まれるかチェックするわけです。
Containerってのは、容器・収納具概念の意味を表すコンテナークラスのことです。
クラスってのは、プログラムをまとめたものです。
容器・収納具概念のTGIDは、2825です。

この行でやってるのは、筆箱が、容器・収納具概念以下かどうかを判断して、容器収容具概念以下なら、次の行を実行します。

これは、筆箱にコンテナクラスを追加してるわけです。
正確に言うと、動的に追加したんです。

動的の反対は静的です。
静的に追加ってのは、最初っから追加してることです。
動的に追加ってのは、プログラムの実行の途中で追加したってことです。

この意味、わかりますか?
筆箱には、最初は、PutInって意味は持ってないんですよ。
「鉛筆を筆箱に入れる」って意味を解析するときになって、初めて、PutInの意味を追加したんですよ。
なんで、最初っから、追加しておかないんでしょう?
それは、容器収納具概念以下の全ての単語にPutInのプログラムを追加してたら、プログラムが重くなりますし、効率的じゃないですよね。
必要なものだけ、必要なタイミングで追加するのが一番ですよね。

じゃぁ、必要なタイミングっていつでしょう?
それは、「入れる」って言葉の意味を解釈するときです。
同じ筆箱でも、物入れとして使わないときもありますよね。
たとえば、机の上で、教科書を開けておく重しとして使うとかです。
重しとして使うには、ある程度の重さと、硬さが必要です。
鳥の羽じゃぁ、重しにらならいですしね。
文の意味を理解するって、その文脈に応じた役割をちゃんと果たすかってことを確認することなんです。

じゃぁ、その文で、その物の役割って、何で決まるんでしょう?
それは、「動詞」です。
「入れる」とか、「重しとして置く」って動詞です。
その動詞の役割を果たすかってことを、無意識でチェックするプログラムがあるわけです。

じゃぁ、そのプログラムは、どこに書くのが一番、無駄がないでしょう。
それは、その動詞に対応する概念です。
「入れる」なら「容器・収容具概念」に書くんです。
そうすれば、その下位概念や、単語、全てに同じプログラムを書く必要はないですしね。

まとめます。
「入れる」って動詞が出てきて、筆箱が容器収納具概念以下だったら、そのタイミングで、PutInってプログラムをもってるコンテナークラスを、筆箱オブジェクトに動的に追加するんです。
これは、概念が意味を定義してるってことなんです。
意味は、その物、その物体に固定されてるわけじゃないんです。
その物の使われ方、もっと言えば、文脈で変わるんです。
文脈を判断するのは、対象とする単語と動詞の組み合わせです。
「筆箱」と「入れる」という組み合わせです。
これ、人間が普段、頭の中で自然とやってることと同じです。
それを、概念ツリーってデータ構造と、3Dシミュレーション機能を組み合わせれば実現できたってことです。

それから、もう一つ。
第129回「脳とプログラム言語の進化」でアフォーダンスの話をしました。
人は、ドアの取っ手の形で、押すのか引くのか認識してるって話です。
つまり、人の頭の中では、オブジェクトが、その物の動きをもってるってわけです。
「入れる」の場合も同じです。
最終的に「入れる」の動詞が追加されるのが「筆箱」です。
今、認識してる具体的なオブジェクトに、そのオブジェクトの動詞を持たせるわけです。
決して、抽象的な「容器・収容具概念」なんてものを思い浮かべて、その動詞を適用しようなんて、意識は考えてないんです。
バックグラウンドで、そうなっていても、意識が認識するのは、筆箱の中に鉛筆を入れるって動作だけです。
こうやって、意識が認識する世界、バックグラウンドで動いてるもの、そういったものをプログラムで忠実に再現することができたんです。

こうやって、人間が世界を認識する仕組みを、プログラムで客観的に再現できるようになったわけです。
プログラムで再現することで、心をエンジニアリング的に扱えるようになったんです。
でも、実際のAIエンジニアは、心の仕組みなんか興味がないみたいで、それが寂しいですけどねぇ。
だから、哲学とか興味ある人が、プログラムの世界に来て欲しいなぁって思ってるんです。
心の仕組みをシステマティックに理解したいと思ってる人は、チャンネル登録、高評価ボタンもお願いしますね。
それから、冒頭で紹介した「ドラえもんの心のつくり方」の本、説明欄にリンクをはってますので、興味ある方は、そちらからお読みください。
それでは、次回も、お楽しみに!