Это переопределение, но переписать оптимизацию, кажется, что вы не понимаете backpropagation
. Майкл Нильсен Neural Networks and Deep Learning
подробно расскажет о backprop.
import numpy as np
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([0, 1, 1, 0])
def activation(x): # sigmoid
return 1 / (1 + np.exp(-x))
def activation_d(x): # sigmoid derivative
s = activation(x)
return s * (1 - s)
def cost(y1, y2):
return (np.linalg.norm(y1 - y2) ** 2) / 2
def cost_d(y1, y2):
""" Compute MSE loss, gradient
Args:
y1: prediction
y2: target
Returns:
grads: same shape with y1 / y2
"""
# d_sigmoid = sigmoid * (1 - sigmoid)
return np.array(y1 - y2) * (y1 * (1 - y1))
def mlp_train(X, y, n_h, learning_rate=1e-2, max_iterations=10000):
n_i = 1 if len(X.shape) == 1 else len(X[0]) # input neurons count
n_o = 1 if len(y.shape) == 1 else len(y[0]) # output neurons count
# add bias
hw = np.random.randn(n_i, n_h)
hb = np.zeros((1, n_h))
ow = np.random.randn(n_h, n_o)
ob = np.zeros((1, n_o))
for iteration in range(max_iterations):
if iteration % 2000 == 0:
print('iteration', iteration)
for x_i, y_i in zip(X, y):
# forwardprop
x_i = x_i[np.newaxis, :]
hz = np.dot(x_i, hw) + hb # (1, n_h)
ho = activation(hz)
oz = np.dot(ho, ow) + ob # (1, n_o)
oo = activation(oz)
# cost
c = cost(oo, y_i)
# backwardprop
grad_oz = cost_d(oo, y_i) # (1, n_o)
grad_ob = grad_oz
grad_ow = np.dot(ho.T, grad_oz) # (n_h, n_o)
# update
ow -= learning_rate * grad_ow
ob -= learning_rate * grad_ob
grad_h = np.dot(grad_oz, ow.T) # (1, n_h)
grad_hz = grad_h * (ho * (1 - ho))
grad_hb = grad_hz # (1, n_h)
grad_hw = np.dot(x_i.T, grad_hz) # (n_i, n_h)
# update
hw -= learning_rate * grad_hw
hb -= learning_rate * grad_hb
if iteration % 2000 == 0:
print(x_i, '->', oo, 'cost', c)
mlp_train(X, y, n_h=2, max_iterations=int(1e5))
выходы:
...
[[1 0]] -> [[0.94364581]] cost 0.0015878973434031022
[[1 1]] -> [[0.04349045]] cost 0.0009457095065652823
iteration 96000
[[0 0]] -> [[0.04870092]] cost 0.0011858898326805463
[[0 1]] -> [[0.95518092]] cost 0.0010043748998508786
[[1 0]] -> [[0.94458789]] cost 0.001535251186790804
[[1 1]] -> [[0.04277648]] cost 0.0009149137866793687
iteration 98000
[[0 0]] -> [[0.04791496]] cost 0.0011479218121198723
[[0 1]] -> [[0.95588406]] cost 0.0009731082050768009
[[1 0]] -> [[0.94548701]] cost 0.0014858330062528543
[[1 1]] -> [[0.04209458]] cost 0.0008859767334115659