до sklearn.dataset.load_digit()
, который представляет собой набор данных изображения 8x8. Я тренировался с 0,2-сплит-тестом и использовал как сигмовидную, так и танх активацию. Похоже, что выходные данные всегда заполняют матрицы либо 1, либо близко к 1, например
Iter: 100 Error: 3.6666666751528374
[[0.99999999 0.99999999 0.99999999 ... 0.99999999 0.99999999 0.99999999]
[0.99999999 0.99999999 0.99999999 ... 0.99999999 0.99999999 0.99999999]
[0.99999999 0.99999999 0.99999999 ... 0.99999999 0.99999999 0.99999999]
...
[0.99999999 0.99999999 0.99999999 ... 0.99999999 0.99999999 0.99999999]
[0.99999999 0.99999999 0.99999999 ... 0.99999999 0.99999999 0.99999999]
[0.99999999 0.99999999 0.99999999 ... 0.99999999 0.99999999 0.99999999]]
Iter: 200 Error: 3.666666674023404
[[0.99999999 0.99999999 0.99999999 ... 0.99999999 0.99999999 0.99999999]
[0.99999999 0.99999999 0.99999999 ... 0.99999999 0.99999999 0.99999999]
[0.99999999 0.99999999 0.99999999 ... 0.99999999 0.99999999 0.99999999]
, хотя структура правильная, похоже, что функция активации всегда портит ответ. Вот тренировка
for i in range(1, 1000+1):
# Feed forward through layers 0, 1, and 2
l0 = x_train
l1 = sigmoid(np.dot(l0,syn0))
l2 = sigmoid(np.dot(l1,syn1))
l2_error = y_train - l2
l2_delta = l2_error * sigmoid(l2,True)
l1_error = l2_delta.dot(syn1.T)
l1_delta = l1_error * sigmoid(l1,True)
syn1 += l1.T.dot(l2_delta) * rate
syn0 += l0.T.dot(l1_delta) * rate
b0 += np.sum(l2_delta)
b1 += np.sum(l1_delta)
if (i % 100) == 0:
print("Iter: {} Error: {}".format(i, str(np.mean(np.abs(l2_error)))))
print(l2, end=' ')
print()
Активация
# activation
def sigmoid(x, d=False):
if d:
return x * (1 - x)
return 1 / (1 + np.exp(-x))
def tanh(x, d=False):
if d: return 1.0 - np.tanh(x)**2
return np.tanh(x)
и слои
# init layer
in_l, hid_l, out_l = 64, 32, 9
# init weight
syn0 = np.random.random((in_l,hid_l))
syn1 = np.random.random((hid_l,out_l))
b0 = np.random.random(hid_l)
b1 = np.random.random(out_l)
rate = 1