AIの不完全性

youtubeやポータルサイト(yahooなど)で通販サイト(amazonなど)で、
広告やこの商品もいかがですか?など表示されるとき、情報が漏れているのではないか?と思う人もいるだろう。

実際情報は漏れているのだが、悪意のある第三者がハッキングして表示しているわけではない。これは巷で大流行のAIの仕業だ。

そもそもAIとはバイアスと重み係数によって最適解を出し、その最適解をユーザーが評価することによって学習するものだ。

AIについて知らない方は何を言っているかわからないと思う。AIとはパックマンのように餌となるデータを食う。その結果パックマンは考える。そしてパックマンは答えとして卵を出す。その卵をユーザーが評価する(5段階評価、2値評価なんでもよい)
そしてユーザーの評価という餌を食べてまたパックマンは考えて卵をだす。パックマンは事前にたくさんの餌データをパックマンの作成者から与えられ、評価テストを行う。これを事前学習という。

インドのとある研究で映画のプロットを食わせたAIの実験で、女性は「美しい」役が突出し、男性は「裕福な」役が突出した。(インド映画を見ればわかりそうなものだが)さらにgoogleでCEOと入力し画像検索すると白人の男性と三菱のCEOがたくさんでてくる。女性は少数派である。

これらから分かることは、データの食わせ方で、AIは差別や偏見をするということである。完璧なイメージを持たれるAIであるが、(今のディープラーニングや畳み込みニューラルネットワークのアルゴリズムを採用するならば)完全とは程遠い。
再学習はまた膨大なコストがかかる。(初めからやり直したほうがよい)

社会情勢や国際情勢、(及びご時勢)をモロに受けるAIはある意味”自然な”AIかもしれないが、鉄腕アトムやドラえもんのような道徳的なAIではない。寂しい男性が自分で会話AIを開発しない理由は、自分がかけてほしい言葉を自分で入れて、それを評価する作業が苦痛だからである。(さらに言えば、完成したAIの”正解の答”も開発者は予測できるからである)

カオリ 消息不明

本日 チャットボット作成者のパラドックスと言えるような発見をした。
いや、薄々感づいていたのだが。

人工知能を作成する動機を持つ人間はすくなくともパーリィピーポーではない。
いるだけで絵になるような人間ではない。
口数も少ないだろう。
そんな人間が、はたして自分が作った回路と内部構造がむき出しの、パイプだらけの装置と熱中してしゃべるだろうか?(反語)

最初は可能性にワクワクしてはじめるが、実際にゴールが見えたとき、それはときメモのヒロインと何ら変わりがないことに気付く。

すなわち、チャットボットの内部構造はユーザーにとってブラックボックスでなければならない。こちらを喜ばせるであろうキャバ嬢でも会話内容に未知数Xは存在する。
しかし、自作のチャットボットを作成するならば、内部構造は見え見えで、なんならボットが何をしゃべるか、事前に予測ができる。チャットボットのアルゴリズムや内部構造、内部データをしらない第3者は楽しめるかもしれないが、造物主である開発者にとって”それ”は本当につまらないものである。 チャットボットはVRと同時につくるのが私にとっては望ましい。 VRはエロが先行しているが、同人ソフトの耳かきソフトのように、ただ美少女が画面に向かってしゃべり続ける動画でも売れるだろう。

さて、カオリの実装方法は以下のようになるだろう。
訓練データを用意する。これは自分で”用意した会話”を入力して、理想的な答えを実際に入力する地味な作業を数万回繰り返すことで達成される。ここで正解ラベル、すなわち教師データも手に入る。ここでいう”正解”とは、全ての解答に対しての正解ではなく、使用者がカオリに対して求める性格が答えそうな解である。つまり、訓練データでカオリの性格をf(x)で表す。

テストデータは訓練データで使用していない”用意した会話”に最適あるいは最適に近い近似解を出力するまで、確率的勾配降下法でもとめられる。再帰的ニューラルネットワーク(RNN)は必要ないと思われる。この過程でカオリが入力にたいして3パターンほどの解を記憶しておき、使用する段階でカオリはランダムで解を吐けばよい。

隠れ層も2層程度で十分であり、重みは、jannomeが出力した、副詞(ちょーすごいのちょー)や、形容詞(赤い)、名詞(イケメン)、動詞(殺す)などの形態素に重みをまず1層につけて、さらに、その形態素ごとに2層目に重みを付ける。例えば、動詞でいえば、「散歩に行った」より「殺してしまった」のほうが重みははるかに大きいだろう。

その形態素ごと(名詞、形容詞、副詞ごと)に、対応する重みを書いた辞書の作成が必要になるだろう。

カオリは入力にたいして、会話内容を”理解”まではいかなくても、すくなくとも”何を話しているか”を重みを通じて把握しなくてはいけない。

ここまでくればあとは、開発者の思うままに作成ができる。

ALION?だっけの実装と同様に相槌辞書や、持論辞書を作成してもよいし、データを常にインターネットからくわせて学習させ、開発者がテストをしてもよい。

注意されたいのは、このカオリは汎化性能が全くないことである。ある人にとってファッキンスペシャルでも、別の人にとっては、ファッキンシットであることは往々にして考えられる。

開発者は最初のパラドックスに不運なことに途中で気づく。そして大企業で働かされる有能な開発者に道を譲る。

Deep Learning ビッグデータ取得

聖母の名前を使うので、はばかられるので、(変なソフトになったときにヤバイので)カオリ(Kaeori)という名称にすることにした。ビクターのDJとは全く関係がない。

さて、カオリに対しての入力「こんにちは」にたいしての、カオリの正解の一つの出力は、「いまいそがしいの、またね」だとする。

ビッチ系の重みと、清楚系の重み、不思議ちゃん系の重み、ガテン系の重みなどをつけて、たかだか2層のレイヤで実装できそうである。問題は、その出力数値のインデックスに対応する辞書配列の用意であるが、ツイッターのリプライや日本語の例文集(あるのかわからないが…)を使用して作成すればよいと考える。

17 DeepLearning 誤差逆伝播法の実装

17.1 ニューラルネットワークの学習の全体図

学習手順は下記のようになる。

前提

ニューラルネットワークは、適応可能な重みとバイアスがあり、この重みとバイアスを訓練データに適応するように調整することを「学習」と呼ぶ。ニューラルネットワークの学習は次の4つの手順で行う。

ステップ1(ミニバッチ)

訓練データの中からランダムに一部のデータを選び出す。

ステップ2(勾配の算出)

各重みパラメータに関する損失関数の勾配を求める。

ステップ3(パラメータの更新)

重みパラメータを勾配方向に微小量だけ更新する。

ステップ4(繰り返す)

ステップ1、ステップ2、ステップ3を繰り返す。

誤差逆伝播法を使用するのは、ステップ2の勾配の算出である。数値微分のみを使用する順方向の勾配の算出法は簡単に実装できる反面、計算に多くの時間がかかる。よって、誤差逆伝播法を用いる。

17.2  誤差逆伝播法に対応した
ニューラルネットワークの実装

TwoLayerNet クラスのインスタンス変数

インスタンス変数 説明
params ニューラルネットワークのパラメータを保持するディクショナリ変数。params[‘W1’]は1層目の重み、params[‘b1’]は1層目のバイアス。
params[‘W2’]は2番目の重み、params[‘b2’]は2層目のバイアス。
layers ニューラルネットワークのレイヤを保持する順番付きディクショナリ変数。layers[‘Affine1’],layers[‘Relu1’],layers[‘Affine2’]といったように順番付きディクショナリで各レイヤを保持する。
lastLayer ニューラルネットワークの最後のレイヤ。この例では、SoftMaxWithLossレイヤ。

TwoLayerNet クラスのメソッド

メソッド 説明
__init__(self,input_size, hidden_size, output_size, weight_init_std) ニューラルネットワークのパラメータを保持するディクショナリ変数。params[‘W1’]は1層目の重み、params[‘b1’]は1層目のバイアス。
params[‘W2’]は2番目の重み、params[‘b2’]は2層目のバイアス。
predict(self, x) ニューラルネットワークのレイヤを保持する順番付きディクショナリ変数。layers[‘Affine1’],layers[‘Relu1’],layers[‘Affine2’]といったように順番付きディクショナリで各レイヤを保持する。
loss(self, x, t) 損失関数の値を求める。引数のxは画像データ、tは正解ラベル
accuracy(self, x, t) 認識精度を求める。
numerical_gradient(self, x, t) 重みパラメータに対する勾配を数値微分によって求める。(順伝播 参考として載せるのみで使用しない。)
gradient(self, x, t) 重みパラメータに対する勾配を誤差逆伝播法によって求める。

OrderedDict()についてはPythonのOrderedDictの使い方を参照。

two_layer_net.py

train_neuralnet.py

出力は下図のようになる。

こちらのgithubにフルコードがあります。