Я создаю нейронную сеть с нуля, используя Numpy, Python и набор данных sklearn di git.
Моя нейронная сеть имеет 3 слоя, 1 вход (64 нейрона), 1 скрытый (10 нейронов) и 1 выход (10 нейронов).
Мне нужно использовать Softmax в выходном слое для классификации, но когда я делаю, ошибка просто увеличивается.
Когда я использую Sigmoid как функция активации в выходном слое, ошибка уменьшается, как и ожидалось.
Кто-нибудь есть какие-либо идеи относительно того, что я могу делать неправильно?
Единственное, что я изменил, это активация функция в выходном слое.
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from sklearn import metrics
def reLu(v):
return np.maximum(v,0)
def reLu_der(v):
v[v<=0] = 0
v[v>0] = 1
return v
def softmax(X):
exps = np.exp(X - np.max(X))
return exps / np.sum(exps)
def crossEntropy(o,y):
return (-y*(np.log(o)) - (1-y)* np.log(1-o))
def crossEntrDeriv(o,y):
return -(y/o - (1-y)/(1-o))
np.random.seed(42)
np.set_printoptions(suppress=True)
w1 = np.random.uniform(-1,1,[64, 10]) #weights of the first hidden layer
b1 = np.zeros([1,10]) #bias of the first hidden layer
w2 = np.random.uniform(-1,1,[10,10]) #weights of the output layer
b2 = np.zeros([1,10]) #bias of the output layer
l = 0.01
epochs = 500
data = load_digits()
images = data.images
target = data.target
images_reshaped = np.reshape(images, (1797, 64))
#spliting data into train/test sets
x_train, x_test, y_train, y_test = train_test_split(images_reshaped, target, test_size=0.2, random_state=0, shuffle=True)
train_E = []
# 1-hot encoding
temp_y_train = np.zeros((y_train.size, y_train.max()+1))
temp_y_train[np.arange(y_train.size),y_train] = 1
for epoch in range(epochs):
# Forward pass
in1 = x_train @ w1 + b1
out1 = reLu(in1)
in2 = out1 @ w2 + b2
out2 = sigmoid(in2) # Only part I've changed
# Calculate error
error = crossEntropy(out2 ,temp_y_train).mean()
train_E.append(error)
#backpropagation Layer 2
dE_dIn2 = -(temp_y_train - out2) # Derivative of error with respect to input2
dIn2_dW2 = out1 # Derivative of input2 with respect to weights2
dIn2_dB2 = 0 # Derivative of input2 with respect to bias2
dE_dW2 = (1/x_train.shape[0]) * out1.T @ dE_dIn2
dE_dB2 = (1/x_train.shape[0])*np.ones([1,len(x_train)])@(dE_dIn2)
#backpropagation Layer 1
dIn2_dOut1 = w2
dOut1_dIn1 = reLu_der(in1)
dIn1_dW1 = x_train
dIn1_dB1 = 0
dE_dW1 = (1/x_train.shape[0]) * x_train.T@ ((dE_dIn2 @ w2.T) * dOut1_dIn1)
dE_dB1 = (1/x_train.shape[0]) * np.ones([len(x_train)])@ ((dE_dIn2 @ dIn2_dOut1) * dIn1_dB1)
b2 -= l * dE_dB2
w2 -= l * dE_dW2
b1 -= l * dE_dB1
w1 -= l * dE_dW1
print('error', error)
z=np.arange(epochs)
f1=plt.figure(1)
plt.plot(z,train_E,label="train",color='red')
plt.legend(loc='best')
plt.title('Error')
f1.show()