データベースを使っておもしろいことをする

木下靖文氏:(AIの)付加価値のポイントはデータベースにある。やっとデータベースの話に戻ってくるわけね。ここにね。

データベースを使っておもしろいシステムを、なにかをするのがやっぱり重要かなと思っています。そういうことを考えてシステム化を、AI系専門じゃないけれどもこういう新しい技術を利用して新しいものを作っていこうという人向けの話をします。

「じゃあAI系の技術の中でデータってなんなんだ?」という話があるんですけれども、そのヒントは「オートエンコーダー」の考え方にあると思います。オートエンコーダーって、さっきDeep Learningのもとになってる話なんですけれども、それがなんなのか? 

ちょっと僕も理解が完全にできていないところがあるので、これはもしかしたら間違ってるかもしれないですけども、乱暴な説明としては、入力の一番最初の層が青・緑・赤・オレンジというふうになって、最初の層で入出力のパラメータ調整をするときに、可逆変換を保持するようにパラメータを調整する。そういうふうに勾配をここでやるんですね。

そうすることで次元圧縮したときに情報量が欠落しないバイアスをかけていこう、というものなんだと思います。あくまで、これはトレーニングするデータの範囲内で情報が落ちないようなものだったと思います。

これはモデル間をつなぐときもある程度当てはまる話で、なにか画像なりなんなりが来て、それをフラグで判別できるような最後のエッセンスの情報というのは、一番最後の層に詰まっているはずなので、そういうものを次のモデルの入力にして、次の段の処理の分類フラグに、どんどん高度なフラグ分けをさせていくという、段階的に作ればよくなるだろうということもあるし。

あるいは、1段階目にもう既存のモデルを使って、2段階目は自分のモデルで、さらにもう1回分類し直させるフラグ付けを覚えさせたりとか。あとは横に広げっちゃってもいいですよね。座標を取れるようにしてトラッキングするようにしたり、いろいろ広がると思います。

多次元索引の重要性

とにかく、AI系技術の中のコンポーネント間のやりとりは、異論はあると思いますけど、とりあえず多次元ベクトルだと思っておけば齟齬は少ない。そうじゃなくても、多次元ベクトルにして考えることは、たぶんできるんじゃないかなと思います。

結局、一番最後の層の手前のところに情報が凝縮されていることが、一応僕が使ってみたモデルの中では多かったかなと思います。

DB化すると索引が必要だというのはわかるでしょうけど、例ですね。Word2vecという単語のvectorizeの話は有名なので、ご存知の方も多いと思いますが、あれは、次元としては多くて100次元で数万語なので、全行走査でもそんなに1秒単位でかかるような処理ではないんですけれども、もっと次元が上がってくるとスケールが変わってきます。

簡単な検証として、2048次元の単精度のベクトルに対して、それと同じ型の大量のデータの中から、大量のデータってここでいうと215万件ぐらいですけど、その中からトップ100の近いものを取ってこようとする処理を考えます。

テストコードはあとで。Pythonでこういうふうにやりますよ、という話です。

結果としては、かたや全行走査してトップ100を取ってくると1.7秒ぐらいかかるけれども、索引があれば5msecかからないという感じで、数万回検索するんだったら10時間以上かかっちゃうので、これはバッチ処理でも数時間かけても、索引を1回作ったほうがいいぐらい違うわけですね。

多次元索引って大事ですよ、という話なんですけど。ネット上にもいろいろあって、過去いろんなものがありましたけど、今使いやすいものとしては、NMSLIBとか。それをすごいリスペクトしている元SpotifyのErikさんという人がいるんですけれども、その人のブログにもちょろっと(書いて)あります。

この人自身もなにかのハッカソンで「Annoy」というまた変な名前の近傍プログラムを作って、Spotifyの中ではAnnoyのほうが使われているらしいんですよね。なにがいいかというと、Annoyはたしか索引が小さくなる。作ってもメモリ上に食うメモリ量が少ないという話があるみたいで、精度とかよりも、そういうデータ量のほうを取ってるんだと思います。

そのErikさんがベンチマークをいっぱいして、あれだこれだって言ってるのが、GitHubのところにそのベンチマーク自体のプログラムが載っていて、その結果自体が常に更新されているので、興味のある方は見てみたらいいかなと思います。

私がなにを使っているかというと、HNSWを自分で改造して使っています。一応公開もしているので、あとでこの資料があれば、見てもらえればいいと思います。

ちょっと事情があって、1.5の頃から使っていて、(今は)1.6になっちゃったので、この1.5ベースに無理やり戻して使っているところだけがちょっと不満なところかと思いますけど、いろいろ現状のNMSLIBを改造して使う参考にはなるかなと思います。

HNSWの精度と速度のバランス

HNSWのポイントとしては、精度と速度が速いのと、精度と速度のバランスですね。バランスがいいというのがあります。相反する要素なので。索引作成も我慢できるぐらいのもので。なんでかというと、単純なアルゴリズムだからというのがあります。

いろいろ不満な部分は直しながら使っていますが、今、結局オンメモリでしか使えないのが大きな問題なんですけれども、いずれ直していきたいなと思っています。

HNSWって、多次元索引をどうやってやるのかなというのをイメージしづらいのかもしれないですけど、結局は普通のB-treeみたいなもので。一番下のレベルには全部のデータが入っていて、一部のデータだけ上のほうに手が伸びてて、それ同士がつながっているようなものを想像していただければいいと思います。

手を伸ばしていると言いましたけど、それぞれのデータを代表するノードには、近いデータのTOPランキングが入っていて、片方向リンクで保持していると。だから検索は一番上のエントリーポイントに降りて、その中の片方向リンクリストを見てどんどん辿っていって、自分に一番近いものがトップに来るノードを探してどんどん動くと。それが見つかったら下へ下へと降りていくと、結果一番近いデータにたどり着くというようなものです。

索引の追加をするときは、どれぐらいのどこのレベルにまで顔を出すかというのはどうも乱数で、今これは本家は分布を決めているみたいです。それに対して、まずその点からのそれぞれのレベルのノードのTOPリストを作って、そのTOPリストにあたるところに対しても、自分自身のデータをランキングに参加させて、ランキングを更新するというやり方で、インデックスを更新していくみたいなかたちなんですね。

そういうふうな多次元索引とAI系技術を使うと、おもしろいサービスができるよという例にしたいんですけど、個人的にはだんだん見ているうちに不満になってきちゃうんですが、(スライドを指して)これは似ているファッションアイテムを探そうとするアプリです。

欠点としては、収録していない商品が出せないので、自由に写真を撮って、それに一発で近い商品を出せといっても、そもそもかなり無茶なところがあります。あるものを検索できた人は「すげえ」と言ってくるんですけど、だいたい、ないもの、珍しいものを検索しようといじわるをして、出てこなくて、「出てこないじゃないか」って話になっちゃうというのがあるんですけれども。こういうふうにいろいろなものを組み合わせてできています。

特徴量判別のところだけちょこっと、確かパーセプトロンの程度のものをトレーニングして使っています。

大きく分けて2段階あって、1個目は商品のカテゴリの画像がどこにあるのかというのと、商品画像を探してくるデータベースの部分。そこに多次元索引を使っています。

人間の五感とインターフェース

もう1つ、「じゃああるものから探すようなインターフェースを作ったらどうだ?」ということで、今年に入ってからちょっと実験的なインターフェースのサイトを作っています。「画像で旅する」って調べてもらえれば、たぶん出てくると思うんですけれども、言語情報によらずに人間がおもしろい画像を探索できるものを作ろうとしています。

これはどうやって作ろうとしているかというと、さっきのHNSWの索引は、機械がたどるにはいい索引なんですけど、人間にとってはちょっとピンとこないんですね。上に確率的に乗せてくるデータが。

なので、人間にとってもたどりやすくするような索引のかたちでなんとか作って、それを一番下のレイヤーの探索結果からその上にといって出してあげると、まぁ適度に、近いものはギュッと、遠いものはうまい具合にバラけて出せるので、そうやって人間がたどりやすいものにしたり。

ここで一場面だけ見ても説明しづらいんですけれども、わかる人にはすごく伝わると思うので、使って見ていただければおもしろいかなと思います。

これからAI技術を組み込んでなにができるかということなんですけど、やっぱりコストを決める大きなポイントはインテリジェンスじゃなくて、けっこう直感的にAI系技術というものと、人間とのインターフェースをどうするかというところがコストを決めるポイントになるんじゃないかと。

だから人間が論理的なコンテキストを、例えばAIスピーカーみたいに会話にしようとか、そういうところに……けっこうコンテキストが複雑なものを扱おうとすると、どんどん無理が出てくるので、不可能になってくるというのもあります。

とはいえ、共感できる部分は、AI系技術というのはデータの入出力の組をただバーッと見せられて調整したものであるんですけど、それに対して人間はリアルワールドで五感を持って生きているので、(AIは)一部分しか共感できるところがない。そういうものをうまく妥協して、インターフェースを作っていけたらおもしろいものができるんじゃないかなと。

多次元データ×AIで新しいものづくりを

直感を扱う意識が大事なんじゃないかなということと、ちょっと私見が強くなるんですけれども、人間側からも歩み寄って使い方を考えていけるようなものを作れば、できるもののコストが下がって、おもしろいものになるんじゃないかなと思います。

システム化するポイントとしては、AI系技術の中間ベクトルを引っこ抜いてきて組み合わせたりとか、データベースに打ち込んだりすると、けっこうおもしろいものができる可能性がありますよ。「みなさんも試してみましょう」というところですね。

知性的なものを求めても無理なので、諦めて地道にプログラミングするしかないのかなというのが、今のところだと思います。最短用途としては、人間の直感の拡張というか、人間が入出力できるものの補助をして、人間が判断する助けになるのが、やっぱり一番簡単な応用方法なんじゃないかなという感じがしています。

あと、一応システムを作る上での肝はいくつかあったんですけれども、GPUリソースという新しいボトルネックになる計算資源が出てきます。

あと、これまた残念なんですけれども、商用のAI系のサービスってあるじゃないですか。ちょっと名前は伏せますけど。だいたいデータを入れてあげると、「〇〇は〇〇」みたいな、やっぱり表みたいなものを覚えさせて、結局出力はそのフラグしか取れないという。「これはAです・Bです」みたいな。

自分のAI系技術みたいなものを、自分のモデルを上にくっつけようとすると、やっぱり途中の内部データを抜きたいんですね。そうじゃないと情報量が落ちてしまう。なので、今のところ商用系のAIサービスは、どこ見てもやっぱり拡張性が低いかなという印象を受けていますので、そこは改善が望まれるところかなと。関係者の方いないですよね(笑)。

というわけで、こんな感じで「多次元データをうまく使って、AI系技術で新しいモノづくりをみなさんもしていきましょう!」というお誘いでした。ありがとうございました。

(会場拍手)