ä»åćÆćå¦ēæć®ę§č½åäøć試ćć¾ćć
ę¹åę”
ååćÆćéćæććć¤ć¢ć¹ć®ć²ćØć¤ć„ć¤ć«ć¤ćć¦ćå
„åććåŗåć¾ć§čØē®ćć¦ćć¾ćććMNISTć§ć®čØē®åę°ćÆć仄äøć§ććć
1é層ē®ļ¼768 $ \times $ 50
2é層ē®ļ¼50 $ \times $ 100
3é層ē®ļ¼100 $ \times $ 10
ć”ćć£ćØå¤§ććŖå¤ćØć”ćć£ćØå°ććå¤ć®2åčØē®ćć¦ććć®ć§2åć«ćŖćć¾ćć
ćććčØē®ćććØ88,800åć«ćŖćć¾ćć
ć¾ććå
Øćć¼ćæ60,000ååå®č”ćććØć5,328,000,000åå®č”ć«ćŖćć¾ććé
ćććć§ćć
ććäøåŗ¦ćććććÆć¼ćÆå³ćč¦ć¦ćæć¾ćććć赤ē·ć®éØåćå ØéØčØē®ćć¦ćć¾ćć
åŗå層ć®éØåć®$ w_{11}^{(2)} $ć«ę³Øē®ćć¦ćæć¾ćććć$ w_{11}^{(2)} $ć®å¤ę“ćå½±éæćåć¼ććć¼ćæćÆć$ u_1^{(2)} $ć$ y_1 $ć$ E $ć®ćæć«ćŖćć¾ććäøå³ć®čµ¤ē·éØåć®ćæčØē®ćē“ćć°ććććØć«ćŖćć¾ćć
åę§ć«ćäøé層ć®$ w_{11}^{(1)} $ć«ę³Øē®ćć¦ćæć¾ćććć$ w_{11}^{(2)} $ć®å¤ę“ćå½±éæćåć¼ććć¼ćæćÆć$ u_1^{(1)} $ć$ z_1^{(1)} $ććć³ä»„éćÆćć¹ć¦ć«ćŖćć¾ćć
赤ē·ć®ćæčØē®ććć°ćććŖćčØē®éćęøććØęććć¾ćć
誤差éä¼ęę³
éćæććć¤ć¢ć¹ć«åƾććå¾é ćć²ćØć¤ć²ćØć¤čØē®ćć¦ćć¾ććććå¾ć§čæ°ć¹ćļ¼ć¤ć®ę³åćå©ēØććć°ćć£ćØē°”åć«å¾é ć®čØē®ćć§ćć¾ććę³åć®č©³ē“°ćē°”åć«čŖ¬ęć§ććŖćććØčććć®ć§ććé£ććć®ć§ććććŖćć®ć ćØčØćēč§£ć§ä½æć£ć¦ćæć¾ćććććććē°”åć«čŖ¬ęććę¹ę³ćčććććć°ććć®éćÆę“ę°ćć¾ćć
ćę³åļ¼ļ¼å¾é ćÆćććććÆć¼ćÆć®åē·ć®å¾é ć®ē©ćØćŖćć
äøå³ć§ć$ w_{11}^{(2)} $ć«ć¤ćć¦čćć¦ćæć¾ćć仄äøć§å¾é ćčØē®ć§ćć¾ćć便å®äøćå¾ćć®ē¢å°ććęøćć¾ćć
$ y_1 $ć®$ E() $ć«åƾććå¾é $ \times $ $ u_1^{(2)} $ć®$ f^{(2)}() $ć«åƾććå¾é $ \times $ $ w_{11}^{(2)} $ć®å¾é
$ y_1 $ć®å¤ćć”ćć£ćØå¤åććå “åć®$ E $ć®å¤åć$ u_1^{(2)} $ć®å¤ćć”ćć£ćØå¤åććå “åć®$ y_1 $ć®å¤åć$ w_{11}^{(2)} $ć®å¤ćć”ćć£ćØå¤åććå “åć®$ u_1^{(2)} $ć®å¤åć®ē©ć«ćŖćć¾ćć
å ·ä½ēć«č¦ć¦ććć¾ććććć¾ććÆåŗå層ć®éØåć§ćć
åŗå層ć®ę“»ę§åé¢ę°ć«ćÆćsoftmaxé¢ę°ćå©ēØćć¦ćć¾ććå®ćÆć$ u_1^{(2)} $ćå¤åććććØć$ y_2 $ćå¤åćć¾ćććććÆććŖć¬ć³ćøć®ē¢å°ć®éØåćć¾ćØćć¦åƾåæććććØć«ćć¾ćććććŖć¬ć³ćøć®ē¢å°ć®éØåć®å¾é ć $ E^{'}(u_1^{(2)}) $ ć§č”Øćć¾ćć
E^{'}(u_1^{(2)}) = \frac{E(u_1^{(2)}+h) - E(u_1^{(2)}-h)}{2h}
ꬔć«ć$ w_{11}^{(2)} $ć«ć¤ćć¦ćæć¦ćæć¾ćććć
$ u_1^{(2)} = w_{11}^{(2)}z_1^{(1)}+w_{12}^{(2)}z_2^{(1)}+w_{13}^{(2)}z_3^{(1)}+b_1^{(2)} $ ć§ćććå¾é
ćčØē®ćć¦ćæć¾ćć
\frac{((w_{11}^{(2)}+h)z_1^{(1)}+w_{12}^{(2)}z_2^{(1)}+w_{13}^{(2)}z_3^{(1)}+b_1^{(2)}) - ((w_{11}^{(2)}-h)z_1^{(1)}+w_{12}^{(2)}z_2^{(1)}+w_{13}^{(2)}z_3^{(1)}+b_1^{(2)})}{2h} = z_1^{(1)}
ē·ć®ē¢å°éØåćÆć$ z_1^{(1)} $ć«ćŖćć¾ććć
ćć£ć¦ć$ w_{11}^{(2)} $ć«åƾććå¾é
ćÆć仄äøć®čØē®å¼ć«ćŖćć¾ćć
z_1^{(1)} \times E^{'}(u_1^{(2)})
ćć¤ć¢ć¹($ b_1^{(2)} $)ć«ć¤ćć¦ćč¦ć¦ćæć¾ććććéćæåę§ć«čØē®ćć¦ćæć¾ćć
\frac{(w_{11}^{(2)}z_1^{(1)}+w_{12}^{(2)}z_2^{(1)}+w_{13}^{(2)}z_3^{(1)}+(b_1^{(2)}+h)) - (w_{11}^{(2)}z_1^{(1)}+w_{12}^{(2)}z_2^{(1)}+w_{13}^{(2)}z_3^{(1)}+(b_1^{(2)}-h))}{2h} = 1
1ć«ćŖćć¾ćććå³ć§ćć¤ć¢ć¹ć®ē¢å°ć®å
ćÆć1ć§ććććć
ćć£ć¦ć$ b_1^{(2)} $ć«åƾććå¾é
ćÆć仄äøć®čØē®å¼ć«ćŖćć¾ććåć«ććŖć¬ć³ćøć®ē¢å°ć®å¾é
ć«ćŖćć¾ććć
E^{'}(u_1^{(2)})
ꬔć«ćäøé層ćč¦ć¦ćæć¾ćććć$ z_1^{(1)} $ć®éØåć§åå²ćć¦ćć¾ćć
ććć§ę³åļ¼ć使ćć¾ćć
ćę³åļ¼ļ¼åå²ć®å “åćÆćććććć®å¾é ć®åćØćŖćć
$ z_1^{(1)} $ć®$ w_{11}^{(2)} $ę¹åć®å¾é ćčØē®ćć¦ćæć¾ćć
\frac{(w_{11}^{(2)}(z_1^{(1)}+h)+w_{12}^{(2)}z_2^{(1)}+w_{13}^{(2)}z_3^{(1)}+b_1^{(2)}) - (w_{11}^{(2)}(z_1^{(1)}-h)+w_{12}^{(2)}z_2^{(1)}+w_{13}^{(2)}z_3^{(1)}+b_1^{(2)})}{2h} = w_{11}^{(2)}
åę§ć«ć$ w_{21}^{(2)} $ę¹åćÆć$ w_{21}^{(2)} $ć«ćŖćć¾ćć
ćć£ć¦ćććććć®éē¢å°ććŖć¬ć³ćøē¢å°ć®å¾é
ćęććå¤ćå ććć°ććććØć«ćŖćć¾ćć
w_{11}^{(2)} \times E^{'}(u_1^{(2)}) + w_{21}^{(2)} \times E^{'}(u_2^{(2)})
é»č²ć®ē¢å°ćÆć$ f'^{(1)}(u_1^{(1)}) $ćØćŖćć¾ćć
f'^{(1)}(u_1^{(1)}) = \frac{f^{(1)}(u_1^{(1)}+h)-f^{(1)}(u_1^{(1)}-h)}{2h}
ē·č²ć®ē¢å°ćÆćåŗå層ć®éć«čØē®ććććć«ć$ z_1^{(0)} $ć«ćŖćć¾ćć
ćć£ć¦ć$ w_{11}^{(1)} $ć«åƾććå¾é
ćÆć仄äøć®čØē®å¼ć«ćŖćć¾ćć
z_1^{(0)} \times f'^{(1)}(u_1^{(1)}) \times (w_{11}^{(2)} \times E^{'}(u_1^{(2)}) + w_{21}^{(2)} \times E^{'}(u_2^{(2)}))
ććć§ę³Øē®ćć¦ę¬²ććć®ćÆćå¾ćć®å¾é ććé ć«åć®å¾é ćčØē®ć§ććććØć§ććē¢å°ć®å¾é ćļ¼åę±ććć ććŖć®ć§ćå¤§å¹ ćŖę§č½ę¹åćč¦č¾¼ć¾ćć¾ćć
å®č£
ććć§ćÆćå®č£ ćć¦ćæć¾ćććć
ć¾ććÆćåŗå層ć®$ E'(u) $ć®éØåć§ććļ¼ćŖć¬ć³ćøē¢å°ć®éØåļ¼
ę失é¢ę°ćerror_funcćåŗå層ć®ę“»ę§åé¢ę°ćoutput_funcćØćć¾ćć
é¢ę°åćÆćoutput_error_backćØćć¾ćććxć®å¤ć®ććć大ććŖå¤ćØå°ććŖå¤ć®åŗå層ć®ę“»ę§åé¢ę°ć®å¤ćčØē®ćććć®å¤ćę失é¢ę°ć«ęø”ćć¾ććććć¦ćć®å·®ćčØē®ćć¦å¾é
ćę±ćć¾ćć
def output_error_back(x, t):
h = 1e-4
dx = np.zeros(x.shape)
for idx,i in np.ndenumerate(x):
work = x[idx] # ē¾åØć®å¤ćäøęééæ
x[idx] = work + h # ććć大ććŖå¤
y = output_func(x)
xph = error_func(y, t)
x[idx] = work - h # ćććå°ććŖå¤
y = output_func(x)
xmh = error_func(y, t)
dx[idx] = (xph - xmh) / (2*h) # å¾é
čØē®
x[idx] = work # å¤ćććØć«ę»ć
return dx
ꬔćÆćéē¢å°ć®éØåć§ććéćæććć¤ć¢ć¹ć®å¾é
ćØćØćć«ćäøä½ć«čæå“ććå¾é
ćę±ŗćć¾ććéćæćÆćéē¢å°ć®éØåļ¼zć®å¤ļ¼ćØćććć¾ć§ć®å¾é
ćęććć°ę±ćććć¾ććććć¤ć¢ć¹ćåę§ć«éē¢å°ć®éØåćÆć1ćŖć®ć§ēµå±ćććć¾ć§ć®å¾é
ć«ćŖćć¾ćććć¼ćæć«ć®å¾é
ćÆćććć¾ć§ć®å¾é
ćØéćæćęććć°ććć®ć§ćććå
ē©ćå©ēØćć¦čØē®ćć¦ćć¾ćć
ćć¤ć¢ć¹ć®éØåćÆćććć§ćÆč¤ę°ćć¼ćæå¦ēć§ććććć«åƾåæćć¦ćć¾ćć1ćęććć°ććć®ć§ććććć¼ćæä»¶ę°åć®1ć®é
åćēØęććäøåŗ¦ć«čØē®ć§ććććć«ćć¦ćć¾ćć
def affine_back(dx, z, W, b):
dz = np.dot(dx, W.T) # zć®å¾é
ćÆćä»ć¾ć§ć®å¾é
ćØéćæćęććå¤
dW = np.dot(z.T, dx) # éćæć®å¾é
ćÆćzć«ä»ć¾ć§ć®å¾é
ćęććå¤
size = 1
if z.ndim == 2:
size = z.shape[0]
db = np.dot(np.ones(size).T, dx) # ćć¤ć¢ć¹ć®å¾é
ćÆćä»ć¾ć§ć®å¾é
ć®å¤
return dz, dW, db
ꬔć«ćé»č²ć®ē¢å°ć§ććę“»ę§åé¢ę°ćmiddle_funcćØćć¦å¾é ćčØē®ćć¾ććććć大ććŖå¤ćØå°ććŖå¤ććé»č²ē¢å°éØåć®å¾é ćę±ćć¦ććć¾ć¾ć§ć®å¾é ć®å¤ćęćć¾ćć
def middle_back(dz, x):
h = 1e-4
work = x # ē¾åØć®å¤ćäøęééæ
x = work + h # ććć大ććŖå¤
xph = middle_func(x)
x = work - h # ćććå°ććŖå¤
xmh = middle_func(x)
du = (xph - xmh) / (2*h) # å¾é
čØē®
x = work # å¤ćććØć«ę»ć
return dz * du
ććć§ćå¾é ć®čØē®ć«åæ č¦ćŖé¢ę°ććć¹ć¦ēØęć§ćć¾ććć
仄äøćÆćååć®å¾é ć®čØē®ć§ćć
dW1 = calc_gradient(z0[i:i+batch_size], t[i:i+batch_size], W1)
db1 = calc_gradient(z0[i:i+batch_size], t[i:i+batch_size], b1)
dW2 = calc_gradient(z0[i:i+batch_size], t[i:i+batch_size], W2)
db2 = calc_gradient(z0[i:i+batch_size], t[i:i+batch_size], b2)
dW3 = calc_gradient(z0[i:i+batch_size], t[i:i+batch_size], W3)
db3 = calc_gradient(z0[i:i+batch_size], t[i:i+batch_size], b3)
ä»åćÆć仄äøć®ććć«ćŖćć¾ćć
du3 = output_error_back(u3[i:i+batch_size], t[i:i+batch_size])
dz2, dW3, db3 = affine_back(du3, z2[i:i+batch_size], W3, b3)
du2 = middle_back(dz2, u2[i:i+batch_size])
dz1, dW2, db2 = affine_back(du2, z1[i:i+batch_size], W2, b2)
du1 = middle_back(dz1, u1[i:i+batch_size])
dz0, dW1, db1 = affine_back(du1, z0[i:i+batch_size], W1, b1)
ć”ćć£ćØćććć«ććććććć¾ććććå¾ćå“ććé ć«å¾é ćę±ćć¦čØē®ćć¦ćć¾ććę±ććå¾é ćé ć«åć«ęø”ćć¦čØē®ćć¦ććć¾ćć
ꬔć«ćä»ć¾ć§ć®é¢ę°ć®č¦ē“ććč”ćć¾ććpropagationé¢ę°ćÆćéäøć®u,zć®å¤ćå©ēØćć¾ćć®ć§čæå“ććććć«ćć¾ććć¾ććę“»ę§åé¢ę°ćē“ę„čØčæ°ćććå®ē¾©ćå¤ę“ććć°ććććć«ćć¾ććć
å¾ćÆćåé¢ę°ć®å®ē¾©ć§ććę£č¦åć®é¢ę°ćinit_funcćØćć¦å®ē¾©ććććć«ćć¾ććć
def propagation(x):
# äøé層(1)
u1 = affine(x, W1, b1)
z1 = middle_func(u1)
# äøé層(2)
u2 = affine(z1, W2, b2)
z2 = middle_func(u2)
# åŗå層
u3 = affine(z2, W3, b3)
y = output_func(u3)
return u1, z1, u2, z2, u3, y
def init_func(x):
return min_max(x)
def middle_func(x):
return relu(x)
def output_func(x):
return softmax(x)
def error_func(y, t):
return cross_entropy_error(y, t)
誤差éä¼ęę³ć«åƾåæććććć°ć©ć ć§ćć
ä»ć¾ć§ć«ä½ęććé¢ę°ē¾¤ćå
ć«čŖćæč¾¼ć¾ćć¦ććåæ
č¦ćććć¾ććäøēŖäøć®(åč)ć«ć®ćć¦ćć¾ćć
import numpy as np
# ćć¼ćę°
d0 = 784
d1 = 50
d2 = 100
d3 = 10
# éćæććć¤ć¢ć¹ć®åęåćå¦ēæēćććććµć¤ćŗć®čØå®
W1 = he_normal(d0,d1)
b1 = np.zeros(d1)
W2 = he_normal(d1,d2)
b2 = np.zeros(d2)
W3 = he_normal(d2,d3)
b3 = np.zeros(d3)
eta = 0.01
batch_size = 100
# MNISTćć¼ćæčŖćæč¾¼ćæ
x_train, t_train, x_test, t_test = load_mnist('c:\\mnist\\')
# å
„åćć¼ćæć®ę£č¦å
z0_train = init_func(x_train)
z0_test = init_func(x_test)
# ćć¼ćæć®ć·ć£ććć«(ę£č§£ćć¼ćæćåęćć¦ć·ć£ćć«ććåæ
č¦ćććććäøåŗ¦ćēµåćåé¢)
z0_t = np.concatenate([z0_train, t_train], axis=1)
np.random.shuffle(z0_t)
z0, t = np.split(z0_t, [z0_train.shape[1]], axis=1)
# å®č”(å¦ēæćć¼ćæ)
u1_train, z1_train, u2_train, z2_train, u3_train, y_train = propagation(z0_train)
# å®č”(ćć¹ććć¼ćæ)
u1_test, z1_test, u2_test, z2_test, u3_test, y_test = propagation(z0_test)
# ę£č§£ē蔨示
print(" å¦ēæćć¼ćæę£č§£ē = " + str(accuracy_rate(y_train, t_train)) + " ćć¹ććć¼ćæę£č§£ē = " + str(accuracy_rate(y_test, t_test)))
for i in range(0,z0.shape[0],batch_size):
# å®č”
u1, z1, u2, z2, u3, y = propagation(z0[i:i+batch_size])
# å¾é
ćčØē®
du3 = output_error_back(u3, t[i:i+batch_size])
dz2, dW3, db3 = affine_back(du3, z2, W3, b3)
du2 = middle_back(dz2, u2)
dz1, dW2, db2 = affine_back(du2, z1, W2, b2)
du1 = middle_back(dz1, u1)
dz0, dW1, db1 = affine_back(du1, z0[i:i+batch_size], W1, b1)
# éćæććć¤ć¢ć¹ć®čŖæę“
W1 = W1 - eta*dW1
b1 = b1 - eta*db1
W2 = W2 - eta*dW2
b2 = b2 - eta*db2
W3 = W3 - eta*dW3
b3 = b3 - eta*db3
# čŖæę“å¾ć®å®č”(å¦ēæćć¼ćæ)
u1_train, z1_train, u2_train, z2_train, u3_train, y_train = propagation(z0_train)
# čŖæę“å¾ć®å®č”(ćć¹ććć¼ćæ)
u1_test, z1_test, u2_test, z2_test, u3_test, y_test = propagation(z0_test)
print(str(i+1) + " ļ½ " + str(i+batch_size) + " å¦ēæćć¼ćæę£č§£ē = " + str(accuracy_rate(y_train, t_train)) + " ćć¹ććć¼ćæę£č§£ē = " + str(accuracy_rate(y_test, t_test)))
ä»åćÆćę©ćčØē®ć§ćć¾ććć
å¦ēæćć¼ćæę£č§£ē = 0.0955833333333 ćć¹ććć¼ćæę£č§£ē = 0.0952
1 ļ½ 100 å¦ēæćć¼ćæę£č§£ē = 0.09895 ćć¹ććć¼ćæę£č§£ē = 0.099
101 ļ½ 200 å¦ēæćć¼ćæę£č§£ē = 0.0994666666667 ćć¹ććć¼ćæę£č§£ē = 0.0995
201 ļ½ 300 å¦ēæćć¼ćæę£č§£ē = 0.104983333333 ćć¹ććć¼ćæę£č§£ē = 0.1053
301 ļ½ 400 å¦ēæćć¼ćæę£č§£ē = 0.10805 ćć¹ććć¼ćæę£č§£ē = 0.1079
401 ļ½ 500 å¦ēæćć¼ćæę£č§£ē = 0.117133333333 ćć¹ććć¼ćæę£č§£ē = 0.118
501 ļ½ 600 å¦ēæćć¼ćæę£č§£ē = 0.120283333333 ćć¹ććć¼ćæę£č§£ē = 0.1201
601 ļ½ 700 å¦ēæćć¼ćæę£č§£ē = 0.124183333333 ćć¹ććć¼ćæę£č§£ē = 0.1229
701 ļ½ 800 å¦ēæćć¼ćæę£č§£ē = 0.12895 ćć¹ććć¼ćæę£č§£ē = 0.1272
801 ļ½ 900 å¦ēæćć¼ćæę£č§£ē = 0.133833333333 ćć¹ććć¼ćæę£č§£ē = 0.1329
901 ļ½ 1000 å¦ēæćć¼ćæę£č§£ē = 0.14095 ćć¹ććć¼ćæę£č§£ē = 0.1374
å Øćć¼ćæć60,000ä»¶ć¾ć§å®č”ććć°ć©ćć§ććę£č§£ēćē“87%ć¾ć§éćć¾ććć
ćØćććÆ
å
ć»ć©ć®ć°ć©ććććć¾ć ć¾ć ę£č§£ēćåäøćććć§ććéåøøć®å¦ēæćÆćļ¼åć ćć§ćŖććåććć¼ćæć§ē¹°ćčæćå¦ēæććććć§ćććć¹ć¦ć®å¦ēæćć¼ćæćļ¼åå¦ēæććććØććØćććÆćØčØćć¾ććMNISTć§ććć°ć60,000ćć¼ćæć®å¦ēæć§1ćØćććÆćåććć¼ćæć§ååŗ¦å¦ēæćć2ćØćććÆć«ćŖćć¾ćć
č¤ę°ćØćććÆć«åƾåæććććć°ć©ć ć«äæ®ę£ćć¾ććęå®ćććØćććÆę°ć«ć¼ćććććć«ćć¾ćććę£č§£ēćÆććØćććÆććØć«ę±ćć¾ćć
import numpy as np
# ćć¼ćę°
d0 = 784
d1 = 50
d2 = 100
d3 = 10
# éćæććć¤ć¢ć¹ć®åęåćå¦ēæēćććććµć¤ćŗććØćććÆć®čØå®
W1 = he_normal(d0,d1)
b1 = np.zeros(d1)
W2 = he_normal(d1,d2)
b2 = np.zeros(d2)
W3 = he_normal(d2,d3)
b3 = np.zeros(d3)
eta = 0.01
batch_size = 100
epoch = 10
# MNISTćć¼ćæčŖćæč¾¼ćæ
x_train, t_train, x_test, t_test = load_mnist('c:\\mnist\\')
# å
„åćć¼ćæć®ę£č¦å
z0_train = init_func(x_train)
z0_test = init_func(x_test)
# ćć¼ćæć®ć·ć£ććć«(ę£č§£ćć¼ćæćåęćć¦ć·ć£ćć«ććåæ
č¦ćććććäøåŗ¦ćēµåćåé¢)
z0_t = np.concatenate([z0_train, t_train], axis=1)
np.random.shuffle(z0_t)
z0, t = np.split(z0_t, [z0_train.shape[1]], axis=1)
# å®č”(å¦ēæćć¼ćæ)
u1_train, z1_train, u2_train, z2_train, u3_train, y_train = propagation(z0_train)
# å®č”(ćć¹ććć¼ćæ)
u1_test, z1_test, u2_test, z2_test, u3_test, y_test = propagation(z0_test)
# ę£č§£ē蔨示
print(" å¦ēæćć¼ćæę£č§£ē = " + str(accuracy_rate(y_train, t_train)) + " ćć¹ććć¼ćæę£č§£ē = " + str(accuracy_rate(y_test, t_test)))
for j in range(epoch):
for i in range(0,z0.shape[0],batch_size):
# å®č”
u1, z1, u2, z2, u3, y = propagation(z0[i:i+batch_size])
# å¾é
ćčØē®
du3 = output_error_back(u3, t[i:i+batch_size])
dz2, dW3, db3 = affine_back(du3, z2, W3, b3)
du2 = middle_back(dz2, u2)
dz1, dW2, db2 = affine_back(du2, z1, W2, b2)
du1 = middle_back(dz1, u1)
dz0, dW1, db1 = affine_back(du1, z0[i:i+batch_size], W1, b1)
# éćæććć¤ć¢ć¹ć®čŖæę“
W1 = W1 - eta*dW1
b1 = b1 - eta*db1
W2 = W2 - eta*dW2
b2 = b2 - eta*db2
W3 = W3 - eta*dW3
b3 = b3 - eta*db3
# čŖæę“å¾ć®å®č”(å¦ēæćć¼ćæ)
u1_train, z1_train, u2_train, z2_train, u3_train, y_train = propagation(z0_train)
# čŖæę“å¾ć®å®č”(ćć¹ććć¼ćæ)
u1_test, z1_test, u2_test, z2_test, u3_test, y_test = propagation(z0_test)
print(str(j+1) + " å¦ēæćć¼ćæę£č§£ē = " + str(accuracy_rate(y_train, t_train)) + " ćć¹ććć¼ćæę£č§£ē = " + str(accuracy_rate(y_test, t_test)))
å®č”ēµęć§ćć10ćØćććÆć§94%ć¾ć§åäøćć¾ććć
å¦ēæćć¼ćæę£č§£ē = 0.0955833333333 ćć¹ććć¼ćæę£č§£ē = 0.0952
1 å¦ēæćć¼ćæę£č§£ē = 0.87225 ćć¹ććć¼ćæę£č§£ē = 0.875
2 å¦ēæćć¼ćæę£č§£ē = 0.897233333333 ćć¹ććć¼ćæę£č§£ē = 0.9015
3 å¦ēæćć¼ćæę£č§£ē = 0.909983333333 ćć¹ććć¼ćæę£č§£ē = 0.9107
4 å¦ēæćć¼ćæę£č§£ē = 0.91795 ćć¹ććć¼ćæę£č§£ē = 0.9182
5 å¦ēæćć¼ćæę£č§£ē = 0.924583333333 ćć¹ććć¼ćæę£č§£ē = 0.9228
6 å¦ēæćć¼ćæę£č§£ē = 0.928983333333 ćć¹ććć¼ćæę£č§£ē = 0.9281
7 å¦ēæćć¼ćæę£č§£ē = 0.932733333333 ćć¹ććć¼ćæę£č§£ē = 0.9318
8 å¦ēæćć¼ćæę£č§£ē = 0.935916666667 ćć¹ććć¼ćæę£č§£ē = 0.9357
9 å¦ēæćć¼ćæę£č§£ē = 0.938916666667 ćć¹ććć¼ćæę£č§£ē = 0.9383
10 å¦ēæćć¼ćæę£č§£ē = 0.94125 ćć¹ććć¼ćæę£č§£ē = 0.9409
ēµęćč¦ć¦ćæć¾ććććęåć®10ä»¶ć®ēµęćØćć®ē»åć§ćć(MNISTć®ęåć®10ä»¶ć§ćÆćŖććć·ć£ććć«å¾ć®ęåć®10ä»¶ć§ćć)åę°åć®åŗåēµę$ y_i $ć%ć§č”Øē¤ŗćć¦ćć¾ććę£č§£ćÆć太åć§ćć
2ēŖē®ä»„å¤ćÆćę£č§£ć§ććć2ēŖē®ćÆć1ćē“50%ć§ćććę£č§£ćÆć5ć§ććć2ēŖē®ć®ē»åć5ć«č¦ćć¾ććļ¼
| ę°å | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 0.00 | 0.00 | 0.01 | 0.01 | 0.00 | 0.00 | 0.00 | 99.97 | 0.00 | 0.01 |
| 2 | 1.76 | 50.06 | 10.49 | 3.33 | 0.07 | 22.13 | 0.44 | 1.08 | 10.56 | 0.07 |
| 3 | 0.00 | 0.00 | 0.00 | 0.01 | 0.00 | 0.00 | 0.00 | 99.88 | 0.00 | 0.11 |
| 4 | 0.09 | 0.00 | 0.73 | 0.02 | 0.01 | 0.30 | 98.84 | 0.00 | 0.00 | 0.00 |
| 5 | 0.01 | 0.00 | 0.01 | 0.33 | 0.00 | 0.57 | 0.00 | 0.00 | 98.85 | 0.22 |
| 6 | 0.37 | 0.01 | 98.85 | 0.27 | 0.00 | 0.01 | 0.49 | 0.00 | 0.00 | 0.00 |
| 7 | 0.02 | 0.45 | 0.54 | 1.31 | 0.12 | 7.25 | 84.60 | 0.00 | 5.66 | 0.06 |
| 8 | 0.00 | 0.01 | 2.80 | 0.01 | 0.79 | 0.76 | 95.59 | 0.00 | 0.05 | 0.00 |
| 9 | 0.00 | 0.34 | 98.31 | 0.38 | 0.00 | 0.00 | 0.97 | 0.00 | 0.00 | 0.00 |
| 10 | 0.02 | 0.80 | 0.47 | 1.19 | 0.10 | 18.47 | 0.01 | 0.33 | 78.56 | 0.03 |
11ä»¶ē®ä»„éć§ćäøę£č§£ć ć£ć10ä»¶ć§ććę£č§£ć®ę°åć太åćę£č§£ćØå¤ęććę°åćć¤ćæćŖććÆć§ē¤ŗćć¾ćć
ē¹ć«43ēŖē®,67ēŖē®ćÆć90%仄éć®ē¢ŗēć§ę£č§£ćØćć¦ćć¾ćććäøę£č§£ć§ććć43ēŖē®ćÆćę£č§£ćÆ2ć§ććć0ćØå¤ęćć¾ććć67ēŖē®ćÆćę£č§£ćÆ5ć§ććć8ćØå¤ęćć¾ććććććć®ę°åćÆćäŗŗć®ē®ć§ććééćäŗŗćå¤ćć®ć§ćÆļ¼
| ę°å | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|---|---|
| 16 | 1.30 | 0.01 | 0.91 | 60.95 | 0.42 | 19.72 | 0.10 | 0.05 | 15.90 | 0.64 |
| 43 | 95.79 | 0.00 | 0.60 | 2.00 | 0.00 | 1.31 | 0.00 | 0.00 | 0.29 | 0.00 |
| 67 | 2.10 | 0.00 | 0.00 | 0.06 | 0.00 | 1.87 | 0.03 | 0.00 | 95.61 | 0.33 |
| 74 | 0.01 | 0.01 | 4.67 | 26.31 | 0.00 | 0.32 | 0.00 | 67.92 | 0.01 | 0.74 |
| 93 | 51.63 | 0.01 | 26.58 | 13.92 | 0.00 | 7.72 | 0.02 | 0.02 | 0.09 | 0.00 |
| 108 | 0.03 | 0.01 | 0.63 | 0.20 | 9.68 | 0.00 | 0.04 | 1.37 | 0.05 | 87.97 |
| 111 | 0.20 | 21.41 | 0.70 | 3.23 | 0.19 | 33.32 | 0.27 | 0.24 | 40.31 | 0.13 |
| 138 | 69.89 | 0.00 | 29.59 | 0.48 | 0.00 | 0.04 | 0.00 | 0.00 | 0.00 | 0.00 |
| 141 | 0.35 | 0.10 | 68.16 | 15.53 | 0.01 | 12.05 | 0.22 | 0.03 | 3.54 | 0.02 |
| 151 | 0.04 | 0.00 | 0.01 | 0.19 | 0.00 | 13.27 | 0.01 | 0.00 | 86.46 | 0.01 |
éćæććć¤ć¢ć¹ć®å¤å
å ć»ć©ć®å®č”å¾ć®éćæććć¤ć¢ć¹ć®ęå°å¤ćę大å¤ćå¹³åå¤ćč¦ć¦ćæć¾ćććć
print('W1 ęå°å¤ = ' + str(np.min(W1)) + ' ([' + str(np.int(np.argmin(W1)/W1.shape[1])) + '][' + str(np.mod(np.argmin(W1),W1.shape[1])) + '])')
print('W1 å¹³åå¤ = ' + str(np.mean(W1)))
print('W1 ęå¤§å¤ = ' + str(np.max(W1)) + ' ([' + str(np.int(np.argmax(W1)/W1.shape[1])) + '][' + str(np.mod(np.argmax(W1),W1.shape[1])) + '])')
print('W1 ęØęŗåå·® = ' + str(np.std(W1)))
print('b1 ęå°å¤ = ' + str(np.min(b1)) + ' ([' + str(np.argmin(b1)) + '])')
print('b1 å¹³åå¤ = ' + str(np.mean(b1)))
print('b1 ęå¤§å¤ = ' + str(np.max(b1)) + ' ([' + str(np.argmax(b1)) + '])')
print('b1 ęØęŗåå·® = ' + str(np.std(b1)))
print('W2 ęå°å¤ = ' + str(np.min(W2)) + ' ([' + str(np.int(np.argmin(W2)/W2.shape[1])) + '][' + str(np.mod(np.argmin(W2),W2.shape[1])) + '])')
print('W2 å¹³åå¤ = ' + str(np.mean(W2)))
print('W2 ęå¤§å¤ = ' + str(np.max(W2)) + ' ([' + str(np.int(np.argmax(W2)/W2.shape[1])) + '][' + str(np.mod(np.argmax(W2),W2.shape[1])) + '])')
print('W2 ęØęŗåå·® = ' + str(np.std(W2)))
print('b2 ęå°å¤ = ' + str(np.min(b2)) + ' ([' + str(np.argmin(b2)) + '])')
print('b2 å¹³åå¤ = ' + str(np.mean(b2)))
print('b2 ęå¤§å¤ = ' + str(np.max(b2)) + ' ([' + str(np.argmax(b2)) + '])')
print('b2 ęØęŗåå·® = ' + str(np.std(b2)))
print('W3 ęå°å¤ = ' + str(np.min(W3)) + ' ([' + str(np.int(np.argmin(W3)/W3.shape[1])) + '][' + str(np.mod(np.argmin(W3),W3.shape[1])) + '])')
print('W3 å¹³åå¤ = ' + str(np.mean(W3)))
print('W3 ęå¤§å¤ = ' + str(np.max(W3)) + ' ([' + str(np.int(np.argmax(W3)/W3.shape[1])) + '][' + str(np.mod(np.argmax(W3),W3.shape[1])) + '])')
print('W3 ęØęŗåå·® = ' + str(np.std(W3)))
print('b3 ęå°å¤ = ' + str(np.min(b3)) + ' ([' + str(np.argmin(b3)) + '])')
print('b3 å¹³åå¤ = ' + str(np.mean(b3)))
print('b3 ęå¤§å¤ = ' + str(np.max(b3)) + ' ([' + str(np.argmax(b3)) + '])')
print('b3 ęØęŗåå·® = ' + str(np.std(b3)))
ēµęć§ććę¬å¼§å
ćÆćč¦ē“ ēŖå·ć蔨ćć¾ćć
ēµę§ćå°ććå¤ć«ćŖć£ć¦ćć¾ććå¹³åćÆć0ć«čæćć§ććć
W1 ęå°å¤ = -0.215683681507 ([487][20])
W1 å¹³åå¤ = 0.00289181066786
W1 ęå¤§å¤ = 0.226295371151 ([434][44])
W1 ęØęŗåå·® = 0.0537721940886
b1 ęå°å¤ = -0.080514889263 ([11])
b1 å¹³åå¤ = 0.0250239727252
b1 ęå¤§å¤ = 0.141728276556 ([4])
b1 ęØęŗåå·® = 0.0499303977195
W2 ęå°å¤ = -0.834521381206 ([24][86])
W2 å¹³åå¤ = 0.00318932553046
W2 ęå¤§å¤ = 0.828200612032 ([46][9])
W2 ęØęŗåå·® = 0.210507854251
b2 ęå°å¤ = -0.0903755259307 ([47])
b2 å¹³åå¤ = 0.0136107723887
b2 ęå¤§å¤ = 0.121659228401 ([58])
b2 ęØęŗåå·® = 0.0323200998782
W3 ęå°å¤ = -0.67279333296 ([81][7])
W3 å¹³åå¤ = 0.00255267426697
W3 ęå¤§å¤ = 0.584028052995 ([48][7])
W3 ęØęŗåå·® = 0.183865649512
b3 ęå°å¤ = -0.172679974526 ([8])
b3 å¹³åå¤ = -6.52443168936e-10
b3 ęå¤§å¤ = 0.156593237942 ([5])
b3 ęØęŗåå·® = 0.080831611452
ꬔć«ćéćæććć¤ć¢ć¹ććć©ć®ććć«å¤åććććć°ć©ćć«ęćć¦ćæć¾ććć
仄å¤ćØå¤åćå°ćŖćć§ćććć°ć©ććęćć¦ćæć¾ćććććć®ēµęćć©ććØććććććććē¾ęē¹ć§ćÆćććć¾ććć
ććććå®č³Ŗę°åć¹ćććć®ććć°ć©ć ć§ćććć¾ć§ć§ććććØć«ć³ć£ććć§ććććććę°åć§ćŖćć¦ćć"ā","ā³"ć"Ć"ć§ććć¢ć«ćć”ćććć§ćććøććÆćå¤ę“ććć«åƾåæć§ćć¦ćć¾ćć¾ćć
ꬔåććććććććć©ć”ć¼ćæćå¤ę“ćć¦ć試ćć¦ćæć¾ćć
(åč)
ä»ć¾ć§ć«ä½ęććé¢ę°ć§ćć
import gzip
import numpy as np
def load_mnist( mnist_path ) :
return _load_image(mnist_path + 'train-images-idx3-ubyte.gz'), \
_load_label(mnist_path + 'train-labels-idx1-ubyte.gz'), \
_load_image(mnist_path + 't10k-images-idx3-ubyte.gz'), \
_load_label(mnist_path + 't10k-labels-idx1-ubyte.gz')
def _load_image( image_path ) :
# ē»åćć¼ćæć®čŖćæč¾¼ćæ
with gzip.open(image_path, 'rb') as f:
buffer = f.read()
size = np.frombuffer(buffer, np.dtype('>i4'), 1, offset=4)
rows = np.frombuffer(buffer, np.dtype('>i4'), 1, offset=8)
columns = np.frombuffer(buffer, np.dtype('>i4'), 1, offset=12)
data = np.frombuffer(buffer, np.uint8, offset=16)
image = np.reshape(data, (size[0], rows[0]*columns[0]))
image = image.astype(np.float32)
return image
def _load_label( label_path ) :
# ę£č§£ćć¼ćæčŖćæč¾¼ćæ
with gzip.open(label_path, 'rb') as f:
buffer = f.read()
size = np.frombuffer(buffer, np.dtype('>i4'), 1, offset=4)
data = np.frombuffer(buffer, np.uint8, offset=8)
label = np.zeros((size[0], 10))
for i in range(size[0]):
label[i, data[i]] = 1
return label
def min_max(x, axis=None):
x_min = np.min(x, axis=axis, keepdims=True) # ęå°å¤ćę±ćć
x_max = np.max(x, axis=axis, keepdims=True) # ę大å¤ćę±ćć
return (x-x_min)/np.maximum((x_max-x_min),1e-7)
def z_score(x, axis = None):
x_mean = np.mean(x, axis=axis, keepdims=True) # å¹³åå¤ćę±ćć
x_std = np.std(x, axis=axis, keepdims=True) # ęØęŗåå·®ćę±ćć
return (x-x_mean)/np.maximum(x_std,1e-7)
def affine(z, W, b):
return np.dot(z, W) + b
def sigmoid(x):
return 1/(1 + np.exp(-x))
def tanh(x):
return np.tanh(x)
def relu(x):
return np.maximum(0, x)
def identity(x):
return x
def softmax(x):
x = x.T
max_x = np.max(x, axis=0)
exp_x = np.exp(x - max_x)
sum_exp_x = np.sum(exp_x, axis=0)
y = exp_x/sum_exp_x
return y.T
def lecun_normal(d_1, d):
std = 1/np.sqrt(d_1)
return np.random.normal(0, std, (d_1, d))
def lecun_uniform(d_1, d):
min = -np.sqrt(3/d_1)
max = np.sqrt(3/d_1)
return np.random.uniform(min, max, (d_1, d))
def glorot_normal(d_1, d):
std = np.sqrt(2/(d_1+d))
return np.random.normal(0, std, (d_1, d))
def glorot_uniform(d_1, d):
min = -np.sqrt(6/(d_1+d))
max = np.sqrt(6/(d_1+d))
return np.random.uniform(min, max, (d_1, d))
def he_normal(d_1, d):
std = np.sqrt(2/d_1)
return np.random.normal(0, std, (d_1, d))
def he_uniform(d_1, d):
min = -np.sqrt(6/d_1)
max = np.sqrt(6/d_1)
return np.random.uniform(min, max, (d_1, d))
def mean_squared_error(y, t):
size = 1
if y.ndim == 2:
size = y.shape[0]
return 0.5 * np.sum((y-t)**2)/size
def cross_entropy_error(y, t):
size = 1
if y.ndim == 2:
size = y.shape[0]
return -np.sum(t * np.log(y))/size
def calc_gradient(x, t, w):
h = 1e-4
gradient = np.zeros(w.shape)
for idx,i in np.ndenumerate(w): # ćć¹ć¦ć®ćć¼ćæć«åƾćć¦å®č”
work = w[idx] # ē¾åØć®å¤ćäøęééæ
w[idx] = work + h # ććć大ććŖå¤
yph = propagation(x)
eph = error_func(yph, t)
w[idx] = work - h # ćććå°ććŖå¤
ymh = propagation(x)
emh = error_func(ymh, t)
gradient[idx] = (eph - emh) / (2*h) # å¾é
čØē®
w[idx] = work # å¤ćććØć«ę»ć
return gradient
def accuracy_rate(y, t):
max_y = np.argmax(y, axis=1)
max_t = np.argmax(t, axis=1)
return np.sum(max_y == max_t)/y.shape[0]
def affine_back(dx, z, W, b):
dz = np.dot(dx, W.T) # zć®å¾é
ćÆćä»ć¾ć§ć®å¾é
ćØéćæćęććå¤
dW = np.dot(z.T, dx) # éćæć®å¾é
ćÆćzć«ä»ć¾ć§ć®å¾é
ćęććå¤
size = 1
if z.ndim == 2:
size = z.shape[0]
db = np.dot(np.ones(size).T, dx) # ćć¤ć¢ć¹ć®å¾é
ćÆćä»ć¾ć§ć®å¾é
ć®å¤
return dz, dW, db
def middle_back(dz, x):
h = 1e-4
work = x # ē¾åØć®å¤ćäøęééæ
x = work + h # ććć大ććŖå¤
xph = middle_func(x)
x = work - h # ćććå°ććŖå¤
xmh = middle_func(x)
du = (xph - xmh) / (2*h) # å¾é
čØē®
x = work # å¤ćććØć«ę»ć
return dz * du
def output_error_back(x, t):
h = 1e-4
dx = np.zeros(x.shape)
for idx,i in np.ndenumerate(x):
work = x[idx] # ē¾åØć®å¤ćäøęééæ
x[idx] = work + h # ććć大ććŖå¤
y = output_func(x)
xph = error_func(y, t)
x[idx] = work - h # ćććå°ććŖå¤
y = output_func(x)
xmh = error_func(y, t)
dx[idx] = (xph - xmh) / (2*h) # å¾é
čØē®
x[idx] = work # å¤ćććØć«ę»ć
return dx










