через долгое время я все еще не могу запустить свой nn без каких-либо ошибок. Точность этой игрушки составляет удивительные 1-2% (60 нейронов в скрытом слое, 100 эпох, скорость обучения 0,3, активация tanh, набор данных MNIST, загруженный через TF) - так что в основном это не обучение вообще. После всего этого времени, просматривая видео / пост о обратном распространении, я все еще не могу это исправить. Так что моя ошибка должна быть между частью, отмеченной двумя линиями #####. Я думаю, что мое понимание деривативов в целом хорошее, но я просто не могу связать это знание с обратным распространением. Если база обратного распространения верна, то ошибка должна быть на axis = 0/1
, потому что я также не могу понять, как определить, по какой оси я буду работать.
Кроме того, у меня есть сильное чувство, что dZ2 = A2 - Y
может быть не так, это должно быть dZ2 = Y - A2
, но после этого исправления nn начинает угадывать только одно число.
(и да, самого обратного распространения я не написал, я нашел его на inte rnet)
#importing data and normalizing it
#"x_test" will be my X
#"y_test" will be my Y
import tensorflow as tf
(traindataX, traindataY), (testdataX, testdataY) = tf.keras.datasets.mnist.load_data()
x_test = testdataX.reshape(testdataX.shape[0], testdataX.shape[1]**2).astype('float32')
x_test = x_test / 255
y_test = testdataY
y_test = np.eye(10)[y_test]
#Activation functions:
def tanh(z):
a = (np.exp(z)-np.exp(-z))/(np.exp(z)+np.exp(-z))
return a
###############################################################################START
def softmax(z):
smExp = np.exp(z - np.max(z, axis=0))
out = smExp / np.sum(smExp, axis=0)
return out
###############################################################################STOP
def neural_network(num_hid, epochs,
learning_rate, X, Y):
#num_hid - number of neurons in the hidden layer
#X - dataX - shape (10000, 784)
#Y - labels - shape (10000, 10)
#inicialization
W1 = np.random.randn(784, num_hid) * 0.01
W2 = np.random.randn(num_hid, 10) * 0.01
b1 = np.zeros((1, num_hid))
b2 = np.zeros((1, 10))
correct = 0
for x in range(1, epochs+1):
#feedforward
Z1 = np.dot(X, W1) + b1
A1 = tanh(Z1)
Z2 = np.dot(A1, W2) + b2
A2 = softmax(Z2)
###############################################################################START
m = X.shape[1] #-> 784
loss = - np.sum((Y * np.log(A2)), axis=0, keepdims=True)
cost = np.sum(loss, axis=1) / m
#backpropagation
dZ2 = A2 - Y
dW2 = (1/m)*np.dot(A1.T, dZ2)
db2 = (1/m)*np.sum(dZ2, axis = 1, keepdims = True)
dZ1 = np.multiply(np.dot(dZ2, W2.T), 1 - np.power(A1, 2))
dW1 = (1/m)*np.dot(X.T, dZ1)
db1 = (1/m)*np.sum(dZ1, axis = 1, keepdims = True)
###############################################################################STOP
#parameters update - gradient descent
W1 = W1 - dW1*learning_rate
b1 = b1 - db1*learning_rate
W2 = W2 - dW2*learning_rate
b2 = b2 - db2*learning_rate
for i in range(np.shape(Y)[1]):
guess = np.argmax(A2[i, :])
ans = np.argmax(Y[i, :])
print(str(x) + " " + str(i) + ". " +"guess: ", guess, "| ans: ", ans)
if guess == ans:
correct = correct + 1;
accuracy = (correct/np.shape(Y)[0]) * 100