Моя проблема в том, что мой NN не тренируется, и я не могу понять, почему.Кто-нибудь может помочь?Вот мой код, я могу описать больше, если вы чего-то не понимаете.Спасибо !
Итак, прежде всего, я импортирую базу данных распознавания цифр и разделяю ее для обучения и тестирования.
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
digits = load_digits()
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(digits.data, digits.target, test_size=0.25, random_state=0)
Я хочу, чтобы мои метки были векторами размера 10, здесь мойметки - это просто цифра, которую представляет изображение.Поэтому я должен выполнить преобразование, чтобы моя матрица меток имела «1» в каждом столбце в координате, соответствующей объекту.Если элемент X_1 равен «3», то во 2-й координате столбца 1 матрицы будет «1», а все остальные координаты будут «0».
y_train1 = np.zeros((10,y_train.shape[0]))
for i in range(0,y_train.shape[0]):
y_train1[ y_train[i] , i ] = 1
x_train1 = np.transpose(x_train)
Затем я создаю активациюфункции:
def sigmoid(Z):
A = 1/(1+np.exp(-Z))
cache = Z
return A, cache
def relu(Z):
A = np.maximum(0,Z)
assert(A.shape == Z.shape)
cache = Z
return A, cache
Функция, которая инициализирует параметры с хорошими размерами:
def init (n_x, n_h, n_y):
##Initialisation aléatoire des poids et biais pour un réseau à 1 couche cachée##
W1 = np.random.randn(n_h,n_x)*0.01
b1 = np.zeros((n_h,1))
W2 = np.random.randn(n_y,n_h)*0.01
b2 = np.zeros((n_y,1))
assert(W1.shape == (n_h, n_x))
assert(b1.shape == (n_h, 1))
assert(W2.shape == (n_y, n_h))
assert(b2.shape == (n_y, 1))
parameters = {"W1": W1,
"b1": b1,
"W2": W2,
"b2": b2}
return parameters
функции для линейной активации вперед:
def propa_avant(A,W,b):
Z = np.dot(W,A) + b
assert(Z.shape == (W.shape[0], A.shape[1]))
cache = (A,W,b)
return Z, cache
def propa_avant_activ(A_prev, W, b, activation):
if activation =="sigmoid" :
Z, linear_cache = propa_avant(A_prev,W,b)
A, activation_cache = sigmoid(Z)
if activation =="relu":
Z, linear_cache = propa_avant(A_prev,W,b)
A, activation_cache = relu(Z)
assert (A.shape == (W.shape[0], A_prev.shape[1]))
cache = (linear_cache, activation_cache)
return A, cache
Стоимость перекрестной энтропиифункция:
def fonction_cout(AL,Y):
m = Y.shape[1]
cost = (-1/m)*np.sum(Y*np.log(AL)+(1-Y)*np.log(1-AL))
cost = np.squeeze(cost)
assert(cost.shape == ())
return cost
Производные функций активации:
def relu_backward(dA, cache):
Z = cache
dZ = np.array(dA, copy=True)
dZ[Z <= 0] = 0
assert (dZ.shape == Z.shape)
return dZ
def sigmoid_backward(dA, cache):
Z = cache
s = 1/(1+np.exp(-Z))
dZ = dA * s * (1-s)
assert (dZ.shape == Z.shape)
return dZ
Функции для линейной обратной активации:
def propa_arriere(dZ, cache):
A_prev, W, b = cache
m = A_prev.shape[1]
dW = (1/2)*np.dot(dZ,A_prev.T)
db = (1/2)*np.sum(dZ, axis=1, keepdims=True)
dA_prev = np.dot(W.T,dZ)
assert (dA_prev.shape == A_prev.shape)
assert (dW.shape == W.shape)
assert (db.shape == b.shape)
return dA_prev, dW, db
def propa_arriere_activ(dA, cache, activation):
linear_cache, activation_cache = cache
if activation == "relu":
dZ = relu_backward(dA, activation_cache)
dA_prev, dW, db = propa_arriere(dZ, linear_cache)
elif activation == "sigmoid":
dZ = sigmoid_backward(dA, activation_cache)
dA_prev, dW, db = propa_arriere(dZ, linear_cache)
return dA_prev, dW, db
Функция для обновления параметров:
def update_parameters(parameters, grads, learning_rate):
L = len(parameters) // 2
for i in reversed(range(1, L-1)):
parameters["W"+str(i)]=parameters["W"+str(i)] - learning_rate*grads["W"+str(i)]
parameters["b"+str(i)]=parameters["b"+str(i)] - learning_rate*grads["b"+str(i)]
parameters["A"+str(i)]=parameters["A"+str(i)] - learning_rate*grads["A"+str(i)]
return parameters
Функция нейронной сети:
def two_layer_model(X, Y, layers_dims, learning_rate = 0.05, num_iterations = 2000, print_cost=False):
grads = {}
costs = [] # to keep track of the cost
m = X.shape[1] # number of examples
(n_x, n_h, n_y) = layers_dims
parameters = init(n_x, n_h, n_y)
W1 = parameters["W1"]
b1 = parameters["b1"]
W2 = parameters["W2"]
b2 = parameters["b2"]
for i in range(0, num_iterations):
A1, cache1 = propa_avant_activ(X, W1, b1, activation = "relu")
A2, cache2 = propa_avant_activ(A1, W2, b2, activation = "sigmoid")
cost = fonction_cout(A2, Y)
dA2 = (1/m)* (- (np.divide(Y, A2) - np.divide(1 - Y, 1 - A2)))
dA1, dW2, db2 = propa_arriere_activ(dA2, cache2, activation="sigmoid")
dA0, dW1, db1 = propa_arriere_activ(dA1, cache1, activation="relu")
grads['dW1'] = dW1
grads['db1'] = db1
grads['dW2'] = dW2
grads['db2'] = db2
parameters = update_parameters(parameters, grads, learning_rate)
W1 = parameters["W1"]
b1 = parameters["b1"]
W2 = parameters["W2"]
b2 = parameters["b2"]
if print_cost and i % 100 == 0:
print("Cost after iteration {}: {}".format(i, np.squeeze(cost)))
if print_cost and i % 100 == 0:
costs.append(cost)
plt.plot(np.squeeze(costs))
plt.ylabel('cost')
plt.xlabel('iterations (per tens)')
plt.title("Learning rate =" + str(learning_rate))
plt.show()
return parameters
Затем я вычисляю эту строку кода для запуска нейронной сети с входной формой 64, скрытым слоем формы 20 и выходомформа 10:
parameters = two_layer_model(x_train1, y_train1, layers_dims = (x_train1.shape[0], 20, 10), num_iterations = 2000, print_cost=True)
И я получаю это:
Cost after iteration 0: 6.962808001140989
Cost after iteration 100: 6.962808001140989
Cost after iteration 200: 6.962808001140989
Cost after iteration 300: 6.962808001140989
Cost after iteration 400: 6.962808001140989
Cost after iteration 500: 6.962808001140989
Cost after iteration 600: 6.962808001140989
Cost after iteration 700: 6.962808001140989
Cost after iteration 800: 6.962808001140989
Cost after iteration 900: 6.962808001140989
Cost after iteration 1000: 6.962808001140989
Cost after iteration 1100: 6.962808001140989
Cost after iteration 1200: 6.962808001140989
Cost after iteration 1300: 6.962808001140989
Cost after iteration 1400: 6.962808001140989
Cost after iteration 1500: 6.962808001140989
Cost after iteration 1600: 6.962808001140989
Cost after iteration 1700: 6.962808001140989
Cost after iteration 1800: 6.962808001140989
Cost after iteration 1900: 6.962808001140989
И этот график: