#python #numpy #neural-network #gradient-descent
#python #numpy #нейронная сеть #градиентный спуск
Вопрос:
Когда я тренирую свою нейронную сеть только на одном обучающем примере, мой код работает просто отлично, но когда я тренируюсь дальше, он вообще не работает. Кто-нибудь имеет представление о том, почему? Я почти уверен, что что-то не так с функцией update_mini_batch, но я понятия не имею. Кстати, это моя первая нейронная сеть, и я делаю ее с нуля, поэтому я действительно не знаю, что я делаю. Кроме того, я использую алгоритм обучения стохастическому градиентному спуску и программирую на python. Кстати, большое спасибо за помощь.
import numpy as np
import random as Ran
class Neural_Network:
def __init__(self, layersizes):
weight_shapes = [(a,b) for a,b in zip(layersizes[1:],
layersizes[:-1])]
self.weights = [np.random.standard_normal(s)/s[1]**.5 for s in
weight_shapes]
self.biases = [np.zeros((s,1)) for s in layersizes[1:]]
self.layersizes = layersizes
def feedforward(self, I):
for w,b in zip(self.weights, self.biases):
I = self.activation(np.matmul(w, I) b)
return I
def backprop(self, input, output):
gradient_b = [np.zeros(b.shape) for b in self.biases]
gradient_w = [np.zeros(w.shape) for w in self.weights]
Activation = input
Activations = [input]
Z_value = 0.0
Z_values = []
for b, w in zip(self.biases, self.weights):
Z_value = np.matmul(w, Activation) b
Activation = self.activation(Z_value)
Activations.append(Activation)
Z_values.append(Z_value)
Activation_derivative = self.activation_prime(Z_values[-1])
Cost_output_delta = (Activations[-1] - output)
delta = Cost_output_delta * Activation_derivative
transpose_value = np.transpose(self.weights[-2])
gradient_b[-1] = delta
gradient_w[-1] = np.matmul(delta, np.transpose(Activations[-2]))
for i in range(2, len(self.layersizes) - 1):
Z_value = Z_values[-i]
Activation_derivative = self.activation_prime(Z_value)
transpose_value = np.transpose(self.weights[-i 1])
delta = [
(a * b) for a,b in zip(np.dot(transpose_value, delta), Activation_derivative)
]
gradient_b[i] = delta
gradient_w[i] = np.matmul(np.transpose(Activations[-i-1]), delta)
return (gradient_b, gradient_w)
def stochastic_gradient_descent(self, Training_data, Epochs, mini_batch_size, eta):
for i in range(Epochs):
Ran.shuffle(Training_data)
mini_batches = [
Training_data[k:k mini_batch_size]
for k in range(0, len(Training_data))
]
for mini_batch in mini_batches:
self.Update_mini_batch(mini_batch, eta)
print("Epoch {0} complete".format(i))
def Update_mini_batch(self, mini_batch, eta):
gradient_b = [np.zeros(b.shape) for b in self.biases]
gradient_w = [np.zeros(w.shape) for w in self.weights]
for input, output in mini_batch:
delta_gradient_pair = self.backprop(input, output)
delta_gradient_b = delta_gradient_pair[0]
delta_gradient_w = delta_gradient_pair[1]
Bias_zip = zip(gradient_b, delta_gradient_b)
Weight_zip = zip(gradient_w, delta_gradient_w)
gradient_b = [g_b d_b for g_b, d_b in Bias_zip]
gradient_w = [g_w d_w for g_w, d_w in Weight_zip]
Bias_zip = zip(self.biases, gradient_b)
Weight_zip = zip(self.weights, gradient_w)
self.biases = [b - (eta / len(mini_batch) * g_b) for b, g_b in Bias_zip]
self.weights = [w - (eta / len(mini_batch) * g_w) for w, g_w in Weight_zip]
def activation(self, value):
return 1 / (1 np.exp(-value))
def activation_prime(self, value):
return np.exp(-value) / ((1 np.exp(-value))**2)
#Test_Program:
with np.load('mnist.npz') as data:
training_images = data['training_images']
training_labels = data['training_labels']
data =[(a, b) for a,b in zip(training_images, training_labels)]
layersizes = (784, 32, 10)
nn = Neural_Network(layersizes)
nn.stochastic_gradient_descent(data, 30, 10, 3)
Комментарии:
1. Можете ли вы описать, как это не работает? Вы получаете сообщение об ошибке или неправильные градиенты или что?
2. Когда вы говорите об одной обучающей выборке, вы имеете в виду одно изображение?
3. Когда я тренирую нейронную сеть на одном изображении, она отлично справляется с предсказанием того, какой цифрой является изображение, но если я тренирую ее на двух изображениях, они оба сильно ошибаются.
Ответ №1:
итак, я нашел проблему, но я не знаю, как ее исправить. по-видимому, моя нейронная сеть может в конечном итоге сделать это правильно, но для этого требуется пара тысяч эпох обучения. это связано с тем, что градиент обратного распространения возврата всегда имеет нули в первом слое смещения и веса. Я считаю, что это ошибка в индексации, но я действительно не уверен. Я до сих пор не знаю, как решить эту проблему, хотя это отстой. если у вас есть какие-либо идеи о том, как я мог бы отредактировать свою нейронную сеть, чтобы она действительно функционировала, это было бы здорово.
ОБНОВЛЕНИЕ: итак, я наконец понял это, БОЖЕ, это так приятно, оказывается, это была целая смесь проблем. прежде всего, я начал индексировать градиенты спереди, а не сзади, что также приводило к тому, что я не попадал во все слои, И я умножал транспонирование активации на дельту назад, что вызывало еще больше проблем. слава богу, я наконец понял это.