Numpy Ошибка нейронной сети взрывается при использовании Softmax - PullRequest
0 голосов
/ 25 февраля 2020

Я создаю нейронную сеть с нуля, используя Numpy, Python и набор данных sklearn di git.

Моя нейронная сеть имеет 3 слоя, 1 вход (64 нейрона), 1 скрытый (10 нейронов) и 1 выход (10 нейронов).

Мне нужно использовать Softmax в выходном слое для классификации, но когда я делаю, ошибка просто увеличивается.

Когда я использую Sigmoid как функция активации в выходном слое, ошибка уменьшается, как и ожидалось.

Кто-нибудь есть какие-либо идеи относительно того, что я могу делать неправильно?

Единственное, что я изменил, это активация функция в выходном слое.

sigmoid error

softmax

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()
...