Нейронная сеть не работает для нескольких выборок данных

#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:

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

ОБНОВЛЕНИЕ: итак, я наконец понял это, БОЖЕ, это так приятно, оказывается, это была целая смесь проблем. прежде всего, я начал индексировать градиенты спереди, а не сзади, что также приводило к тому, что я не попадал во все слои, И я умножал транспонирование активации на дельту назад, что вызывало еще больше проблем. слава богу, я наконец понял это.