「AIの考えることはわからん」という言葉がある。あるかどうか知らない。今、思いついた。
前々回「その4」と前回「その5」でグラフを描画した後にダンプした重み W1、W2 と バイアス b1、b2 の値を、Excel シートにまとめてみた。Excel の表はホームページビルダーに貼りつけると html に自動変換してくれるので、ホームページビルダー経由でブログにも貼り付けてみる。
まずは「その5」すなわち初期値重み0.1の場合。丸めなしと丸め7~3桁のデータを採ったが、スペースの都合で今回の記事には丸め5桁までを載せる。
| 丸めなし | 7桁 | 6桁 | 5桁 | |
| W1[0][0] | 4.00632453 | 3.44539626 | -1.86501773 | 3.84608801 |
| W1[0][1] | 0.74621904 | 0.73045915 | -4.61775425 | 0.18855283 |
| W1[0][2] | -4.45154713 | -4.26451676 | 3.55631742 | -4.60571661 |
| W1[1][0] | -4.41780543 | -4.25213382 | -1.88107736 | -4.37482109 |
| W1[1][1] | 0.3158155 | 0.51924299 | -4.61879971 | 0.4782215 |
| W1[1][2] | 4.06376368 | 3.47807515 | 3.55773063 | 3.94866908 |
| b1[0] | 2.88515978 | 3.72557846 | -1.10349328 | 2.90711841 |
| b1[1] | 3.49637772 | 4.69945879 | 1.53527639 | 3.87535165 |
| b1[2] | 2.9176136 | 3.73723392 | -5.55997762 | 3.17658877 |
| W2[0][0] | 7.52188442 | 11.62101214 | 1.26900181 | 7.4825227 |
| W2[0][1] | -7.51900942 | -11.61813714 | -1.26612681 | -7.4796527 |
| W2[1][0] | 5.85674287 | 11.18154668 | 4.25877394 | 6.49566576 |
| W2[1][1] | -5.84908476 | -11.17388848 | -4.25111594 | -6.48800576 |
| W2[2][0] | 7.60501813 | 11.66302433 | 4.42342661 | 7.59086115 |
| W2[2][1] | -7.57634126 | -11.63434753 | -4.39474961 | -7.56218115 |
| b2[0] | -17.24374337 | -30.40488191 | -2.23040188 | -17.8918042 |
| b2[1] | 17.24374337 | 30.40488191 | 2.23040188 | 17.8918042 |
次に「その4」すなわち初期値重み50の場合。これはもともとデータを間引いて載せたんだった。
| 丸めなし | 6桁 | 4桁 | 2桁 | |
| W1[0][0] | 3.10715279 | 3.10715289 | 3.10710145 | 3.09749693 |
| W1[0][1] | -6.92996836 | -6.92996828 | -6.92997272 | -6.92642448 |
| W1[0][2] | -8.0399468 | -8.03994567 | -8.04005328 | -8.03894874 |
| W1[1][0] | -3.65469687 | -3.65469717 | -3.6547279 | -3.65772763 |
| W1[1][1] | -2.36826359 | -2.36826367 | -2.36824909 | -2.36530438 |
| W1[1][2] | 7.24733878 | 7.24733962 | 7.2472656 | 7.2475458 |
| b1[0] | -2.79170761 | -2.79170755 | -2.79167077 | -2.78123196 |
| b1[1] | 1.27328557 | 1.27328572 | 1.27327315 | 1.27206239 |
| b1[2] | -4.31921463 | -4.3192158 | -4.31912361 | -4.32347713 |
| W2[0][0] | -6.51184203 | -6.51184149 | -6.51186187 | -6.50319204 |
| W2[0][1] | 7.94933953 | 7.94933949 | 7.94936187 | 7.94319204 |
| W2[1][0] | 6.5981932 | 6.59819307 | 6.59822748 | 6.60072934 |
| W2[1][1] | -2.7691377 | -2.76913807 | -2.76912748 | -2.77072934 |
| W2[2][0] | 1.59700312 | 1.59700329 | 1.59701523 | 1.59685762 |
| W2[2][1] | 12.74142788 | 12.74142871 | 12.74138477 | 12.74314238 |
| b2[0] | 1.84055305 | 1.8405531 | 1.84053306 | 1.83860683 |
| b2[1] | -1.84055305 | -1.8405531 | -1.84053306 | -1.83860683 |
「その4」の結論部分で述べた通り、まずは「その4」のほうは初期値を丸めた桁数の範囲まで W1、W2、b1、b2 の結果がもれなく一致していることを確認したかった。「その5」では、そのような現象はいっさい見られない。
せっかく Excel に貼り付けたので、もう少しいじってみた。
Excel ではクリックで簡単に表示桁数を変更できる。「その4」の表の小数点以下を1桁表示にしてみた。
| 丸めなし | 7桁 | 6桁 | 5桁 | |
| W1[0][0] | 4.0 | 3.4 | -1.9 | 3.8 |
| W1[0][1] | 0.7 | 0.7 | -4.6 | 0.2 |
| W1[0][2] | -4.5 | -4.3 | 3.6 | -4.6 |
| W1[1][0] | -4.4 | -4.3 | -1.9 | -4.4 |
| W1[1][1] | 0.3 | 0.5 | -4.6 | 0.5 |
| W1[1][2] | 4.1 | 3.5 | 3.6 | 3.9 |
| b1[0] | 2.9 | 3.7 | -1.1 | 2.9 |
| b1[1] | 3.5 | 4.7 | 1.5 | 3.9 |
| b1[2] | 2.9 | 3.7 | -5.6 | 3.2 |
| W2[0][0] | 7.5 | 11.6 | 1.3 | 7.5 |
| W2[0][1] | -7.5 | -11.6 | -1.3 | -7.5 |
| W2[1][0] | 5.9 | 11.2 | 4.3 | 6.5 |
| W2[1][1] | -5.8 | -11.2 | -4.3 | -6.5 |
| W2[2][0] | 7.6 | 11.7 | 4.4 | 7.6 |
| W2[2][1] | -7.6 | -11.6 | -4.4 | -7.6 |
| b2[0] | -17.2 | -30.4 | -2.2 | -17.9 |
| b2[1] | 17.2 | 30.4 | 2.2 | 17.9 |
さらに久しぶりに Microsoft Mathematics を使って検算してみたくなった。
Python でもできるが GUI の視覚的な快適さはやはり魅力なのだ。
正直に言うと、最初は手計算で検算しようとしたが計算間違いが多発して収拾がつかなくなったためキカイに頼ることにしたのだが。私は学生時代からずっとそんな調子だ。
やろうとしていることは、上掲各表の数値が、排他的論理和 EOR を実現していることの確認である。
まずは「その5」結果の小数点以下1桁表示の表から「丸めなし」データを使って、入力 x と1層重み W1 の積を計算させたところ。上掲スクリーンショットの計算結果ウインドウに表示されているものと同じである。
数式で書くと「x・W1」である。Micosoft Matimatics のスクショも数式だけど。

上掲スクショの結果にバイアス b1 を加算したところ。
数式で書くと「x・W1+b1」である。

Python ではブロードキャスト演算(斎藤康毅『ゼロから作るDeep Learning 』(O'LEILLY) P14 参照)を行うが Microsoft Mathematics にはブロードキャスト機能はないので、b1 は1行目の値を2~4行目にコピペしている。
2層ニューラルネットワークシステムでは活性化関数として1層目と2層目の間にシグモイド関数(『ゼロから作るDeep Learning 』P45)を噛ませるが、ここはざっくり行列要素が正なら 1、負なら 0 で近似する。
その上で、W2 との行列積を計算する。

上掲スクショ入力欄の1項目は「xW1 + b1」のシグモイド関数出力を前述の方法で近似したもので、これを「Z1」と呼称する。これまで載せた Python コードでも、同じ変数名を使用している。
Z1 を眺めるだけでも、何をしようとしているか見当つく。1列目と3列目の AND をとれば目的の排他的論理和が得られるはずである。
そうすると2列目は余分のはずだが、W1、b1 の列数を2にすると結果が安定的に得られなかったことは「その1」で述べた通り。3列以上が必要だったのだ(実際に試したのは弊ブログに書いた3、4列以上は5列だけだが。5列でも結果が得られた)。
「自由度が足りない」というやつだろうか? 「自由度」という用語を定義することは今の私には不可能で、感覚的に言っているだけなのだが。
話が長くなった。ひとつ上のスクショでやっていることを数式で書くと「Z1・W2」である。
次のスクショでは「Z1・W2+b2」の演算を行っている。出力の直前である。b2 は Python ではブロードキャストだが、1行目を各行にコピペしているのは b1 のときと同じ。

最終出力はソフトマックス関数(『ゼロから作るDeep Learning』P66)を噛ませているが、1列目が EOR の否定を、2列目が EOR を構成しているのは一目瞭然だ。
追記:
なんで1行目をEORの否定、2行目をEORにしたかというと、タネ本『ゼロから作るDeep Learning』が出力にもう一段 numpy の argmax() 関数というのを噛ませているのを踏襲したため(P80)。ちゃんと意味があるのだが、うっかり忘れていて自分でも軽く混乱した。
追記おわり
以上の結果は、それでも比較的わかりやすい部類ではないかと思っている。 逆に言うと、後でわけのわからない結果が出てくる。
「その5」にグラフが奇妙な動きを見せたと書いた6桁丸め(decimals=6)のケース。
やはり Excel で小数点以下1桁表示させた値を使用している。
x・W1 の計算結果。

x・W1 + b1。

今回もシグモイド関数のおおざっぱな近似として各要素が正なら 1、負なら 0 と置き換えて Z1 とした。そして W2 との積をとった。

丸めなし(計算は示さなかったが7桁丸め、5桁丸めもそう)では2列目が余剰次元だったが、今回の6桁丸めの場合、余剰次元が1列目に変化していることが目を引く。余剰次元という言葉も定義なしで語感だけで使っています。余剰次元にちょっとはみ出すことができると収束しやすくなる、みたいな。理論物理学にそんな学説あるのかな? 全くの思いつきで言ってます。
丸めなしの余剰次元は1で埋まっていたが、今回は0で埋まっている。
念のため + b2 の計算結果も。
私自身あんまりわかっていない、いい加減な定義の用語をもう一つ持ち出したい。カオス理論に「アトラクター」という概念がある。「引っ張るもの」という意味で、恒星のまわりを惑星や彗星や小惑星が周回するイメージを持てばいいのではないだろうか。アトラクターの周囲で規則正しい周回運動をする天体もあれば、古典的なカオスとして有名な「三体問題」の理論に基づき極めて不規則な動きをする天体もある。
排他的論理和を構成する各変数を多次元空間の座標と見ると、この多次元空間にはアトラクターが複数存在するはずである。例えばかりにW1の1行目の三次元座標 (x, y, z) がアトラクターだったとすると、式の対象性から順番を入れ替えた (y, z, x) と (z, x, y) もアトラクターになるはずだ(ただし x ≠ y、y ≠ z、z ≠ x)。もちろんそれに応じてW1の二行目、 b1、W2、b2 も要素の順番が入れ替わる。
丸め6桁のケースは、丸めなしのケースと異なるアトラクターに引きつけられてしまったかのように見える。
しかし丸め7桁のケース、丸め5桁のケース…だって、丸めなしと同じアトラクターを目指しているという保証はどこにもないのだ。
比較のため「その4」すなわち初期値重み 50 の W1、b1、W2、b2 ダンプ表を小数点以下1桁表示すると、当然ながら丸めなし~丸め2桁の結果は区別つかなくなる。
| 丸めなし | 6桁 | 4桁 | 2桁 | |
| W1[0][0] | 3.1 | 3.1 | 3.1 | 3.1 |
| W1[0][1] | -6.9 | -6.9 | -6.9 | -6.9 |
| W1[0][2] | -8.0 | -8.0 | -8.0 | -8.0 |
| W1[1][0] | -3.7 | -3.7 | -3.7 | -3.7 |
| W1[1][1] | -2.4 | -2.4 | -2.4 | -2.4 |
| W1[1][2] | 7.2 | 7.2 | 7.2 | 7.2 |
| b1[0] | -2.8 | -2.8 | -2.8 | -2.8 |
| b1[1] | 1.3 | 1.3 | 1.3 | 1.3 |
| b1[2] | -4.3 | -4.3 | -4.3 | -4.3 |
| W2[0][0] | -6.5 | -6.5 | -6.5 | -6.5 |
| W2[0][1] | 7.9 | 7.9 | 7.9 | 7.9 |
| W2[1][0] | 6.6 | 6.6 | 6.6 | 6.6 |
| W2[1][1] | -2.8 | -2.8 | -2.8 | -2.8 |
| W2[2][0] | 1.6 | 1.6 | 1.6 | 1.6 |
| W2[2][1] | 12.7 | 12.7 | 12.7 | 12.7 |
| b2[0] | 1.8 | 1.8 | 1.8 | 1.8 |
| b2[1] | -1.8 | -1.8 | -1.8 | -1.8 |
この数値に基づく検算結果が、わけわからんのだ。
まずは入力 x と1層目重み W1 の積。

1層目バイアス b1との和をとる。xW1 + b1 である。
例によってブロードキャストができないから、1行目を2~4行目にコピペしている。

今回は先の2つの検算と異なり、1 or 0 の近似では巧くいかなかった。
そこで上掲スクショの出力を Python のシグモイド関数に入力し、その結果を小数点以下1桁で丸めたものを Z1 とした。
そこまでやるなら検算も Python でやったほうが早かったと思ったが、やってみなければわからないことは、しばしばある。
Z1 と 2層目の重み W2 の積 Z1・W2 の計算である。

さらに2層目のバイアス b2 を加算している。Z1・W2 + b2 である。

なんなんだこれは?
1行目:1列目 >2列目、2行目:1列目 < 2列目、3行目:1列目 < 2列目、4行目:1列目 >2列目だから、出力でソフトマックス関数を噛ませれば確かにこれでも 1列目:EORの否定、2列目:EOR になるけど、先ほどの初期値重み 0.1 のときの鮮やかな対称性とは似ても似つかないではないか!?
だがこの値こそが、初期値の差が小数点以下の丸めの桁数程度ではびくともしない強力なアトラクターであるはずなのだが、なぜAIがこのアトラクターを選択したのか、人間には見当つかない。少なくとも私には見当つかない。
まことAIの考えることはわからん。
スポンサーリンク



