🍉しいたげられたしいたけ

NO WAR! 戊争反察Ceasefire Now! 䞀刻も早い停戊を

排他的論理和EORを機械孊習で実珟しようずしたらバタフラむ効果が発生したその

わけのわからない぀か未調査のこずは他にもたくさんあっお、䞀䟋だが䜿甚するパ゜コンによっおも蚈算結果が違うのだ。同じパ゜コンを䜿っおいる限り再珟性は揺るぎもしないのだが、珟圚保有しおいるDELL17むンチノヌパ゜ずLenovo15むンチノヌパ゜で結果に差が出たりする。いずれも 64bit Windows10 Home なのだが、内郚衚珟が違うのか Anaconda のバヌゞョンが違うのか これは調査すればわかるこずだず思いたい。

重みの初期倀もいろいろ倉えお詊しおいる。マッピングするべきだろうが、倉数が倚いし範囲ず刻みをどうするか等の方針がただ決たっおいない。

ガりス分垃乱数でいく぀か詊しお、ずりわけヘンな結果が出た数倀䟋を、今回は貌っおいく。

「その」の「#コヌド4-0」の1局重み W1 ず2局重み W2 を、次のように倉曎した。numpy のガりス分垃乱数メ゜ッド random.randn() で生成した盎埌にダンプした倀を、そのたたコヌドに眮き換えたのだ。

W1 = np.array([
[-0.00420782, -0.04331233, 0.12136818],
[-0.00953556, 0.01987206, 0.02593997]])
W2 = np.array([
[ 0.08212653, -0.04860534],
[-0.17150817, -0.30326033],
[-0.003902 , -0.0539731 ]])

この初期倀を䜿甚するず、正答率が100%にならない。損倱関数の倀もれロ近くに収束しない。぀たり排他的論理和EORを実珟するのに倱敗したずいうこずだ。ずきどきそういうこずがある。

「その」「#コヌド4-2」で䜜成した正解率accず損倱関数の倀lossのグラフは、こんな感じになる。

f:id:watto:20210323010447p:plain

 

以䞋、い぀ものように「その」に茉せたコヌドで䜜成したグラフを貌っおいく。

巊「#コヌド4-3」によるW1の3D折れ線グラフ。

右「#コヌド4-4」によるW1の3面2D展開図颚グラフ。

f:id:watto:20210323010521p:plain
f:id:watto:20210323010510p:plain

 

巊「#コヌド4-5」によるb1の3D折れ線グラフ。

右「#コヌド4-6」によるb1の3面2D展開図颚グラフ。 

f:id:watto:20210323010459p:plain
f:id:watto:20210323010452p:plain

 

巊「#コヌド4-7」によるW2の3D折れ線グラフ。

右「#コヌド4-8」によるW2の3面2D展開図颚グラフ。 

f:id:watto:20210323010441p:plain
f:id:watto:20210323010516p:plain

 

巊「#コヌド4-9」によるバむアスb2の2D折れ線グラフ。

右「#コヌド4-2」による正解率ず損倱関数の倀のグラフを再掲グラフの倧きさを合わせるため。

f:id:watto:20210323010505p:plain
f:id:watto:20210323010447p:plain

 

前回蚘事「その」でよくわかっおいないのに「アトラクタヌ」ずいう甚語を䜿いたくなったのは、䞊掲グラフずりわけW1の3D折れ線グラフが呚回軌道に䌌た動きを瀺しおいたこずも䞀因である。ただし正解率100%にならないグラフが必ずしもこのような呚回軌道もどきの動きをするわけではなく、むしろ単調な動きを瀺すこずも倚い。実䟋は埌日瀺すかも。

 

グラフ描画埌すなわち孊習を100回繰り返した埌でダンプしたW1、b1、W2、b2の倀は、次の通りだった。

>>> W1
array([[1.71176211, 1.40439772, 5.15937839],
[1.71143204, 1.40486592, 5.15880418]])
>>> b1
array([5.35940066, 5.61089252, 1.85192825])
>>> W2
array([[-17.59943793, 17.63295912],
[-18.21478118, 17.74001268],
[-20.42315653, 20.36528143]])
>>> b2
array([ 55.77585749, -55.77585749])

ナマの数字だけでは意味がずりづらいので、前回「その」ず同様の怜算を詊みる。ただし Microsoft Mathematics はビゞュアルがよくおも操䜜が面倒なので、Python 察話モヌドに数匏を入力しお蚈算させるこずにした。

 

ニュヌラルネットワヌク1局目の挔算結果。ニュヌラルネットワヌクに関しおは、い぀ものタネ本 斎藀康毅『れロから䜜るDeep Learning』(O'REILLY) 3章、4章参照。

>>> np.dot(x_e,W1) + b1
array([[ 5.35940066, 5.61089252, 1.85192825],
[ 7.07116277, 7.01529024, 7.01130664],
[ 7.0708327 , 7.01575844, 7.01073243],
[ 8.78259481, 8.42015616, 12.17011081]])

これでもわかりにくいので、シグモむド関数を噛たせお小数点以䞋1桁たで䞞めおみた。シグモむド関数は『れロから䜜るDeep Learning』P45参照。

>>> Z1 = sigmoid(np.dot(x_e,W1) + b1)
>>> Z1
array([[0.9953183 , 0.99635553, 0.86435334],
[0.99915148, 0.99910276, 0.99909918],
[0.9991512 , 0.99910318, 0.99909867],
[0.99984664, 0.99977967, 0.99999482]])
>>> np.round(Z1,decimals=1)
array([[1. , 1. , 0.9],
[1. , 1. , 1. ],
[1. , 1. , 1. ],
[1. , 1. , 1. ]])

この1局出力を、どう捏ね回しおもEORは実珟できそうにない。

 

グラフを描画したプログラムでは、Z1をニュヌラルネットワヌク2局目に入力しおさらに゜フトマックス関数を噛たせおいる。゜フトマックス関数は『れロから䜜るDeep Learning』P66参照。

これらの挔算結果も瀺す。

>>> np.dot(Z1,W2) + b2
array([[ 2.45759337, -2.94729187],
[-0.41184405, -0.08682869],
[-0.41183621, -0.08683671],
[-0.45470003, -0.04432262]])
>>> softmax(np.dot(Z1,W2) + b2)
array([[0.99552554, 0.00447446],
[0.41945396, 0.58054604],
[0.41945782, 0.58054218],
[0.39882163, 0.60117837]])

䞀床くらい argmax() を噛たせた結果を衚瀺しおみよう。ちょっずはわかりやすくならないだろうか

>>> y = softmax(np.dot(Z1,W2) + b2)
>>> np.argmax(y, axis=1)
array([0, 1, 1, 1], dtype=int64)

正しくは [0, 1, 1, 0] ず衚瀺されなければならない。

今回は収束しなかったから結果もワケわかんないが、次からはわからないでもない結果が出おくるので、長々ず曞いたのは比范甚である。 

れロから䜜るDeep Learning ―Pythonで孊ぶディヌプラヌニングの理論ず実装

れロから䜜るDeep Learning ―Pythonで孊ぶディヌプラヌニングの理論ず実装

  • 䜜者:æ–Žè—€ 康毅
  • 発売日: 2016/09/24
  • メディア: 単行本゜フトカバヌ
 

 ç¶šã„お、この初期倀を小数点以䞋7桁に䞞めおみる。

>>> W1 = np.round(W1, decimals=7)
>>> W2 = np.round(W2, decimals=7)
>>>
>>> W1
array([[-0.0042078, -0.0433123, 0.1213682],
[-0.0095356, 0.0198721, 0.02594 ]])
>>> W2
array([[ 0.0821265, -0.0486053],
[-0.1715082, -0.3032603],
[-0.003902 , -0.0539731]])

そうするず、なんず正解率100%、評䟡関数の倀れロ付近に収束しおしたうのだ

 

巊「#コヌド4-3」によるW1の3D折れ線グラフ。

右「#コヌド4-4」によるW1の3面2D展開図颚グラフ。

f:id:watto:20210323104751p:plain
f:id:watto:20210323104741p:plain

 

巊「#コヌド4-5」によるb1の3D折れ線グラフ。

右「#コヌド4-6」によるb1の3面2D展開図颚グラフ。

f:id:watto:20210323104730p:plain
f:id:watto:20210323104725p:plain

 

巊「#コヌド4-7」によるW2の3D折れ線グラフ。

右「#コヌド4-8」によるW2の3面2D展開図颚グラフ。

f:id:watto:20210323104721p:plain
f:id:watto:20210323104746p:plain

 

巊「#コヌド4-9」によるバむアスb2の2D折れ線グラフ。

右「#コヌド4-2」による正解率ず損倱関数の倀のグラフ。

f:id:watto:20210323104735p:plain
f:id:watto:20210323104712p:plain

ご芧の通り初期倀の小数点以䞋8桁目を䞞めただけで、正解率100%損倱関数の倀れロ付近に収束するずいう劇的な倉化を芋せた。䞞めなかった堎合ずの差は䞀千䞇分の䞀以䞋である

グラフ描画埌のW1、b1、W2、b2のダンプ。

>>> W1
array([[ 0.15566959, -3.62609222, 4.41335946],
[ 0.15508861, -3.62582171, 4.41213812]])
>>> b1
array([ 4.61571949, 6.2275166 , -0.49241919])
>>> W2
array([[ -8.68490772, 8.71842892],
[ -9.37837986, 8.90361136],
[-10.95008053, 10.89220543]])
>>> b2
array([ 25.00004968, -25.00004968])

 

䞊掲倀を甚いた1局出力 Z1 = sigmoid(np.dot(x_e,W1) + b1) の怜算。

>>> np.dot(x_e,W1) + b1
array([[ 4.61571949, 6.2275166 , -0.49241919],
[ 4.77138908, 2.60142438, 3.92094027],
[ 4.77080811, 2.60169489, 3.91971893],
[ 4.92647769, -1.02439733, 8.33307838]])
>>> Z1 = sigmoid(np.dot(x_e,W1) + b1)
>>> Z1
array([[0.99020189, 0.99802954, 0.37932383],
[0.99160251, 0.93095319, 0.98056284],
[0.99159767, 0.93097058, 0.98053955],
[0.99280021, 0.26417174, 0.99975963]])

 

Z1 を小数点以䞋1桁衚瀺しおみる。

>>> np.round(Z1,decimals=1)
array([[1. , 1. , 0.4],
[1. , 0.9, 1. ],
[1. , 0.9, 1. ],
[1. , 0.3, 1. ]])

1列目が䜙剰次元で、2列目ず3列目で EOR を実珟しようずしおいるこずが掚察される。「䜙剰次元」ずいう蚀葉は「次局ぞの圱響が小さそうな列」ずいうほどの意味で䜿っおいたす。

 

念のため2局出力および出力に argmax() を噛たせた結果を。

>>> np.dot(Z1,W2) + b2
array([[ 2.88671093, -3.34930457],
[-3.0800014 , 2.61450368],
[-3.07986738, 2.61436259],
[ 2.95272011, -3.10272186]])
>>> softmax(np.dot(Z1,W2) + b2)
array([[0.99804618, 0.00195382],
[0.00335312, 0.99664688],
[0.00335404, 0.99664596],
[0.99766042, 0.00233958]])
>>> y = softmax(np.dot(Z1,W2) + b2)
>>> np.argmax(y, axis=1)
array([0, 1, 1, 0], dtype=int64) 

[0, 1, 1, 0]、正解しおいる。

れロから䜜るDeep Learning ❷ ―自然蚀語凊理線

れロから䜜るDeep Learning ❷ ―自然蚀語凊理線

  • 䜜者:æ–Žè—€ 康毅
  • 発売日: 2018/07/21
  • メディア: 単行本゜フトカバヌ
 

初期倀6桁䞞めず5桁䞞めのデヌタも採ったが、7桁のケヌスず䌌通っおいたので省略する。結果が激しく倉化したのが4桁䞞めず3桁䞞めのケヌスだった。差が倧きいから倉化しお圓然ずいう芋方もできようが、それでも4桁で1䞇分の1、3桁で千分の1以䞋の差である。

4桁で䞞めたケヌス。

>>> W1 = np.round(W1, decimals=4)
>>> W2 = np.round(W2, decimals=4)

>>> W1
array([[-0.0042, -0.0433, 0.1214],
[-0.0095, 0.0199, 0.0259]])
>>> W2
array([[ 0.0821, -0.0486],
[-0.1715, -0.3033],
[-0.0039, -0.054 ]])

 

巊「#コヌド4-3」によるW1の3D折れ線グラフ。

右「#コヌド4-4」によるW1の3面2D展開図颚グラフ。

f:id:watto:20210323121826p:plain
f:id:watto:20210323121814p:plain

 

巊「#コヌド4-5」によるb1の3D折れ線グラフ。

右「#コヌド4-6」によるb1の3面2D展開図颚グラフ。

f:id:watto:20210323121804p:plain
f:id:watto:20210323121758p:plain

 

巊「#コヌド4-7」によるW2の3D折れ線グラフ。

右「#コヌド4-8」によるW2の3面2D展開図颚グラフ。

f:id:watto:20210323121753p:plain
f:id:watto:20210323121820p:plain

 

巊「#コヌド4-9」によるバむアスb2の2D折れ線グラフ。

右「#コヌド4-2」による正解率ず損倱関数の倀のグラフ。

f:id:watto:20210323121809p:plain
f:id:watto:20210323121738p:plain

前々回「その」あたりでは地味だったb1やW2のグラフの動きが激しい。今回はどれもそうか。

グラフ描画埌のW1、b1、W2、b2のダンプ。

>>> W1
array([[-0.5733437 , -3.00341978, 3.54293311],
[ 0.58475128, 2.82789074, -3.73600438]])
>>> b1
array([3.18836141, 2.22843679, 2.34602933])
>>> W2
array([[ 5.54385952, -5.51035952],
[ 5.69392689, -6.16872689],
[ 5.15003454, -5.20793454]])
>>> b2
array([-13.74932189, 13.74932189])

 

1局出力 Z1 = sigmoid(np.dot(x_e,W1) + b1) の小数点以䞋1桁衚瀺。

>>> Z1 = sigmoid(np.dot(x_e,W1) + b1)
>>> np.round(Z1,decimals=1)
array([[1. , 0.9, 0.9],
[0.9, 0.3, 1. ],
[1. , 1. , 0.2],
[1. , 0.9, 0.9]])

1行目が䜙剰次元のようなのはいいずしお、2行目ず3行目でEORを実珟しようずする方法が、7桁䞞めのずきず異なっおいる。

すなわち7桁䞞めのずきは2列目ず3列目をAND挔算しおいるかのようだが、この4桁䞞めではNAND挔算しおいるように芋える。

4桁䞞めず7桁䞞めでは異なるアトラクタヌに匕き寄せられおいるず衚珟しおいいのではないだろうか。アトラクタヌも䞍正確な蚀い方なので「目暙ずする収束倀」などず蚀い換えた方が倚少はマシかもだが。

 

2局目出力ず argmax()。結果は同じである。

>>> np.dot(Z1,W2) + b2
array([[ 1.41531244, -1.86461704],
[-1.65174635, 1.47546936],
[-1.64513101, 1.19453733],
[ 1.23769924, -1.67817407]])
>>> softmax(np.dot(Z1,W2) + b2)
array([[0.96373382, 0.03626618],
[0.04199849, 0.95800151],
[0.05521784, 0.94478216],
[0.94862556, 0.05137444]])
>>> y = softmax(np.dot(Z1,W2) + b2)
>>> np.argmax(y, axis=1)
array([0, 1, 1, 0], dtype=int64)

れロから䜜るDeep Learning ❞ ―フレヌムワヌク線

れロから䜜るDeep Learning ❞ ―フレヌムワヌク線

  • 䜜者:æ–Žè—€ 康毅
  • 発売日: 2020/04/20
  • メディア: 単行本゜フトカバヌ
 

 3桁で䞞めたケヌス。

>>> W1 = np.round(W1, decimals=3)
>>> W2 = np.round(W2, decimals=3)

>>> W1
array([[-0.004, -0.043, 0.121],
[-0.01 , 0.02 , 0.026]])
>>> W2
array([[ 0.082, -0.049],
[-0.172, -0.303],
[-0.004, -0.054]])

  

巊「#コヌド4-3」によるW1の3D折れ線グラフ。

右「#コヌド4-4」によるW1の3面2D展開図颚グラフ。

f:id:watto:20210323125341p:plain
f:id:watto:20210323125331p:plain

 

巊「#コヌド4-5」によるb1の3D折れ線グラフ。

右「#コヌド4-6」によるb1の3面2D展開図颚グラフ。

f:id:watto:20210323125320p:plain
f:id:watto:20210323125315p:plain

 

巊「#コヌド4-7」によるW2の3D折れ線グラフ。

右「#コヌド4-8」によるW2の3面2D展開図颚グラフ。

f:id:watto:20210323125309p:plain
f:id:watto:20210323125336p:plain

 

巊「#コヌド4-9」によるバむアスb2の2D折れ線グラフ。

右「#コヌド4-2」による正解率ず損倱関数の倀のグラフ。

f:id:watto:20210323125326p:plain
f:id:watto:20210323125257p:plain

 

グラフ描画埌のW1、b1、W2、b2のダンプ。

>>> W1
array([[ 3.76666159, -2.17278522, -4.22211443],
[-2.11128289, 3.81356837, -4.28411122]])
>>> b1
array([2.13895947, 2.19372889, 1.55502881])
>>> W2
array([[ 13.5655765 , -13.5325765 ],
[ 13.31123554, -13.78623554],
[ 4.06164038, -4.11964038]])
>>> b2
array([-23.99379003, 23.99379003])

 

1局出力 Z1 の小数点以䞋1桁衚瀺。

>>> np.round(Z1,decimals=1)
array([[0.9, 0.9, 0.8],
[1. , 0.5, 0.1],
[0.5, 1. , 0.1],
[1. , 1. , 0. ]])

これは䜕をしおいるんだろう 1列目ず2列目のNANDを䜿っお3列目は䜙剰次元 それにしおはフリヌダム。

むしろ䜙剰次元は2局目の行列挔算で無芖できればいいのだから、もずもず 0 たたは 1 に揃える必芁性はなさそうに思われる。

 

2局出力ず argmax()。結果は合っおいるのだが。

>>> np.dot(Z1,W2) + b2
array([[ 3.47178286, -3.91749739],
[-3.47597717, 3.26513381],
[-3.58969204, 3.12903216],
[ 2.30683187, -2.73956496]])
>>> softmax(np.dot(Z1,W2) + b2)
array([[9.99382541e-01, 6.17458987e-04],
[1.17994009e-03, 9.98820060e-01],
[1.20662080e-03, 9.98793379e-01],
[9.93608643e-01, 6.39135684e-03]])
>>> y = softmax(np.dot(Z1,W2) + b2)
>>> np.argmax(y, axis=1)
array([0, 1, 1, 0], dtype=int64)

スポンサヌリンク