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

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

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

すみたせん、察象は斎藀康毅『れロから䜜るDeep Learning ―Pythonで孊ぶディヌプラヌニングの理論ず実装』(O'REILLY) 読者限定の蚘事に぀き、新着お目汚しを避けるため日付をさかのがっお公開したす。匊ブログでは、ずきどきそういうこずをやりたす。

 

2幎半、攟眮しおいるシリヌズがある。

www.watto.nagoya

方針は、排他的論理和EORを実珟する重み行列 W0 、定数ベクトル b0、重みベクトル W1、定数 b1 を、機械孊習によっお求めるこずだった。

今気づいたけど、䞭断しおいる゚ントリヌでは排他的論理和をEORではなくXORず曞いおしたっおいるな。䞍統䞀すみたせん。

念のため真理倀衚を瀺す。入力デヌタ0ず入力デヌタ1に察する教垫デヌタ0が排他的論理和、教垫デヌタ1は排他的論理和の吊定である。

入力0 入力1 教垫0 教垫1
0 0 0 1
1 0 1 0
0 1 1 0
1 1 0 1

ずころがこれが、なかなか思った通りにいかなかった。各係数がい぀たでたっおも収束しなかったのだ。

そこぞ実生掻でやっかいなトラブルに芋舞われ、䞭途半端に攟眮せざるを埗なかった。

トラブルはなんずか片付けるのに玄2幎かかった。経緯はブログに曞こうかどうしようか迷っおいる。

半幎ほど前から、機械孊習の勉匷をが぀が぀ず再開した。2幎も間が開くず、现かいずころを忘れおしたっおいた。ようやく䞭断したずころたで远い぀いたのが、今幎の幎明けくらいだった。 

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

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

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

Excel ぞの移怍はしばらく諊め、Python で蚘述するこずにする。

次に瀺す Python スクリプトは、排他的論理和EORを実珟する䞀䟋である。䞊掲曞『れロから䜜るDeep Learning』の察応ペヌゞをコメントに瀺した。

以䞋、䟿宜的に「コヌド1」「コヌド2」 などず名称を぀ける。

#コヌド1
import sys, os
import numpy as np
sys.path.append(os.pardir) #P73 䞊䜍フォルダをパス指定
from common.functions import *

x = np.array([[0, 0], [1, 0], [0, 1], [1, 1]]) # 入力

W1 = np.array([[-0.5, 0.5], [-0.5, 0.5]]) #第1å±€ P61改倉
b1 = np.array([0.7, -0.3]) #係数はP26をそのたた䜿甚

A1 = np.dot(x,W1) + b1
Z1 = step_function(A1) #ステップ関数 P47

W2 = np.array([[0.5, -0.5], [0.5, -0.5]]) #第2å±€ P61改倉
b2 = np.array([-0.7, 0.7]) #係数はP27をそのたた䜿甚

A2 = np.dot(Z1,W2) + b2
y = step_function(A2) #ステップ関数 P47

print(y)

 

『れロから䜜るDeep Learning』たえがきvii、xiにあるサンプルスクリプトをダりンロヌドしたディレクトリに移動しお Anagonda プロンプトの察話モヌド画面に䞊掲コヌドを貌り付けるず、実行結果が

[[0 1]
[1 0]
[1 0]
[0 1]] 

のように衚瀺されるはずであるWindows 10 Home、python version3.8.3にお確認。

なお察話型モヌドのいいずころは、プロンプトに倉数を入力するだけで蚈算過皋が衚瀺・確認できるこずである。

>>> A1
array([[ 0.7, -0.3],
[ 0.2, 0.2],
[ 0.2, 0.2],
[-0.3, 0.7]])
>>> Z1
array([[1, 0],
[1, 1],
[1, 1],
[0, 1]])
>>> A2
array([[-0.2, 0.2],
[ 0.3, -0.3],
[ 0.3, -0.3],
[-0.2, 0.2]])

「A1 = np.dot(x,W1) + b1」「A2 = np.dot(Z1,W2) + b2」の "np.dot" は内積 P55、"+" はブロヌドキャスト挔算 P14 である。

぀たり第1局ではORずNANDを䜜り、第2局では䞡者のANDをずっおいるのである。

この係数W1、W2、b1、b2を、人間が䞎えるのではなく機械孊習で求めたい。

 

詊行錯誀の過皋は省略し結論を急ぐ。 続いお『れロから䜜るDeep Learning』P114の2局ニュヌラルネットワヌクを改造しお、次のようなコヌドを䜜成した。

#コヌド2
import sys, os
sys.path.append(os.pardir)
import numpy as np
from common.functions import *
from common.gradient import numerical_gradient

x_e = np.array([[0, 0], [1, 0], [0, 1], [1, 1]]) #入力デヌタ
t_e = np.array([[1, 0], [0, 1], [0, 1], [1, 0]]) #教垫デヌタ

weight_init_std=0.1
W1 = weight_init_std * np.random.randn(2, 2) #ガりス分垃
W2 = weight_init_std * np.random.randn(2, 2) #乱数で初期化
b1, b2 = np.zeros(2), np.zeros(2) #れロで初期化

def predict(x):
    A1 = np.dot(x,W1) + b1
    Z1 = sigmoid(A1) #シグモむド関数P48
    A2 = np.dot(Z1,W2) + b2
    y = softmax(A2) #゜フトマックス関数P66
    return y

 

倪字、フォント色倉曎をしおいるが Anaconda プロンプトには貌り぀くはずである。

重みW1、W2の圢状は2×2、バむアスb1、b2の芁玠数は2である。

W1、W2をガりス分垃により生成された乱数で、b1、b2をれロで初期化しおいるこず、シグモむド関数ず゜フトマックス関数を導入しおいるこずなど、少し説明したい箇所があるが、ざっくり省略する。

だがこれでは、思ったように動䜜しおくれなかった。W1、W2、b1、b2を求めるこずができなかった。

远蚘

weight_init_std の倀を倉曎するず解が埗られるこずがあった。だが安定的に埗られるわけではない。なんでだろう

远蚘おわり

远蚘の远蚘

「#コヌド2」の䞭の教垫デヌタ t_e を真理倀にするず

入力0 入力1 教垫0 教垫1
0 0 1 0
1 0 0 1
0 1 0 1
1 1 1 0

ず1列目「教垫0」がEORの吊定、2列目がEORずなる。これはタネ本『れロから䜜るDeep Learning』で、出力結果にもう䞀段 numpy の argmax() メ゜ッド最倧倀を持぀列を取り出す関数。P80参照を噛たせおいるのを、そのたた螏襲したため。

远蚘の远蚘おわり

そこで、W1の圢状を2×3、W2の圢状を3×2、バむアスb1の芁玠数を3、b2の芁玠数を2に倉曎するか 

#コヌド3
import sys, os
sys.path.append(os.pardir)
import numpy as np
from common.functions import *
from common.gradient import numerical_gradient

x_e = np.array([[0, 0], [1, 0], [0, 1], [1, 1]]) #入力デヌタ
t_e = np.array([[1, 0], [0, 1], [0, 1], [1, 0]]) #教垫デヌタ

weight_init_std=0.1
W1 = weight_init_std * np.random.randn(2, 3) #ガりス分垃
W2 = weight_init_std * np.random.randn(3, 2) #乱数で初期化
b1, b2 = np.zeros(3), np.zeros(2) #れロで初期化

def predict(x):
    A1 = np.dot(x,W1) + b1
    Z1 = sigmoid(A1) #シグモむド関数P48
    A2 = np.dot(Z1,W2) + b2
    y = softmax(A2) #゜フトマックス関数P66
    return y

 

たたはW1の圢状を2×4、W2の圢状を4×2、バむアスb1の芁玠数を4、b2の芁玠数を2に倉曎にしたずころ 

#コヌド4
import sys, os
sys.path.append(os.pardir)
import numpy as np
from common.functions import *
from common.gradient import numerical_gradient

x_e = np.array([[0, 0], [1, 0], [0, 1], [1, 1]]) #入力デヌタ
t_e = np.array([[1, 0], [0, 1], [0, 1], [1, 0]]) #教垫デヌタ

weight_init_std=0.1
W1 = weight_init_std * np.random.randn(2, 4) #ガりス分垃
W2 = weight_init_std * np.random.randn(4, 2) #乱数で初期化
b1, b2 = np.zeros(4), np.zeros(2) #れロで初期化

def predict(x):
    A1 = np.dot(x,W1) + b1
    Z1 = sigmoid(A1) #シグモむド関数P48
    A2 = np.dot(Z1,W2) + b2
    y = softmax(A2) #゜フトマックス関数P66
    return y

 

機械孊習によりW1、W2、b1、b2を求めるこずができた なんでだ

 

すなわち䞊掲「コヌド3」たたは「コヌド4」ず、次に瀺す「コヌド5」をAnacondaプロンプトに貌り付けお、正解率accず損倱関数の倀lossのグラフを衚瀺させたのである。

損倱関数のグラフは『れロから䜜るDeep Learning』P119図4-11、正解率のグラフはP121図4-12を

#コヌド5 ch04\two_layer_net 改造
def loss(x, t): #損倱関数
    y = predict(x)
    return cross_entropy_error(y, t)


def accuracy(x, t): #正答率
    y = predict(x)
    y = np.argmax(y, axis=1)
    t = np.argmax(t, axis=1)
    accuracy = np.sum(y == t) / float(x.shape[0])
    return accuracy


import matplotlib.pyplot as plt #グラフ描画準備
loss_W = lambda W: loss(x_e, t_e)
loss_list = [ ]
acc_list = [ ]
learning_rate = 5.0 #孊習率
step_num = 200 #繰り返し回数

for i in range(step_num): #繰り返し孊習
    W1 -= learning_rate*numerical_gradient(loss_W, W1)
    b1 -= learning_rate*numerical_gradient(loss_W, b1)
    W2 -= learning_rate*numerical_gradient(loss_W, W2)
    b2 -= learning_rate*numerical_gradient(loss_W, b2)
    loss_list.append(loss(x_e,t_e))
    acc_list.append(accuracy(x_e, t_e))


x = np.arange(len(loss_list))
plt.plot(x, loss_list, label='loss')
plt.plot(x, acc_list, label='acc', linestyle='--')
plt.xlabel("iteration") #x軞ラベル
plt.legend() #凡䟋
plt.show()

 

 これはたった今、コヌド3ずコヌド5を貌り付けお実行した結果 

https://cdn-ak.f.st-hatena.com/images/fotolife/w/watto/20210313/20210313235645.png

 

これはコヌド4ずコヌド5を貌り付けお実行した結果、埗られたグラフである。

https://cdn-ak.f.st-hatena.com/images/fotolife/w/watto/20210313/20210313235656.png

 

iterationは繰り返し回数である。損倱関数の倀lossは0に近いほどよく、正解率accは1になっおほしい。

今回はたたたた、コヌド3+コヌド5もコヌド4+コヌド5も期埅通りの結果が埗られた。

ずころが、実行するたびにグラフの圢状が激しく違ったのだ

正解率が1にならない、すなわち孊習結果が正しく埗られないこずも、少なくなかった

いったい䜕が起きおいるのだろう

ずいうこずで、もう少し深く掘っおみるこずにした。

明快な結論が出せたわけではないが、それでも少しわかったこずがあるので、だらだら続けようず思う。

スポンサヌリンク

Â