Проблема нейронной сети с вычислением обратного распространения - PullRequest
2 голосов
/ 24 июня 2019

В настоящее время я работаю над созданием простой нейронной сети для идентификации записанных чисел с использованием базы данных номеров MNIST. Когда я запускаю первый тест, я получаю случайный ассортимент вероятностей в моих выходных массивах, что и ожидается. Однако, когда я запускаю его более одного раза, мои выходные массивы почти все сбрасываются в нули во всех позициях индекса. Кажется, что мои расчеты для моих корректировок веса, которые распространяются в обратном направлении, вызывают проблему, но я не могу понять, почему.

def sigmoid(x):
    a = 1 / (1 + np.exp(-x))
    return a

def sigmoid_derivative(x):
    return x * (1 - x)

def train(n, inputs):
    input_layer = inputs
    weights1 = 2 * np.random.random ((784 , 16)) - 1
    weights2 = 2 * np.random.random ((16 , 10)) - 1

    for i in range(n):
        trained_hidden = sigmoid(np.dot(input_layer, weights1))
        trained_outputs = sigmoid(np.dot(trained_hidden, weights2))

        o_error = (outputs - trained_outputs)
        o_adjustments = o_error * sigmoid_derivative(trained_outputs)

        h_error = np.dot(o_adjustments, weights2.T)
        h_adjustments = h_error * sigmoid_derivative(trained_hidden)

        w1 = np.dot(input_layer.T, h_adjustments)
        w2 = np.dot(trained_hidden.T, o_adjustments)

        weights1 += w1
        weights2 += w2

    return trained_outputs

Я использую массивы Numpy, и входные данные представляют собой массив (10000 x 784) со значением 0 - 1 в оттенках серого и выводят его в массив (10000 x 10) с 1 в позиции индекса действительной цифры.

x_train, t_train, x_test, t_test = mnist.load()

inputs = x_test/256

outputs = np.zeros((10000,10), dtype=int)

for i in range(10000):
    x = t_test[int(i)]
    outputs[i][x] = 1

set = train(10, inputs)

Я использовал ряд ресурсов для построения этого, в том числе теорию, основанную на 3 синих 1 коричневых сериях нейронных сетей, и код, за которым следует пример, приведенный здесь (https://enlight.nyc/projects/neural-network/)

Редактировать: Согласно предложению @ 9000, здесь приведена распечатка каждого шага в одном примере. Глядя на результаты, похоже, что w1 (расчет поправки на вес) является проблемой, но, глядя на это снова и снова, я не могу понять, почему это неверно, любая помощь приветствуется.

Редактировать 2: Я включил вторую распечатку того же примера во второй тренировочный заезд.

Первый запуск

trained_hidden [0.87880514 0.4789476  0.38500953 0.00142838 0.01373613 0.37572408 0.53673194 0.11774215 0.99989426 0.0547656  0.20645864 0.85484692 0.99903171 0.88929566 0.00673453 0.03816501]

trained_output [0.33244312 0.26289407 0.79917376 0.95143406 0.90780616 0.2100068 0.66253735 0.57961972 0.28231436 0.15963378]

o_error [ 0.66755688 -0.26289407 -0.79917376 -0.95143406 -0.90780616 -0.2100068 -0.66253735 -0.57961972 -0.28231436 -0.15963378]

o-adjustment [ 0.14814735 -0.05094382 -0.12826344 -0.04396319 -0.07597805 -0.03484096 -0.14813117 -0.14123055 -0.05720055 -0.02141501]

h_error [-0.00359599  0.18884347  0.15954247 -0.14839811  0.2081496  -0.01152563 0.03262859 -0.46315722 -0.06974061 -0.46774417 -0.00690463 -0.44303219 -0.16267084 -0.02505235 -0.12866526  0.22212537]

h_adjustment [-3.82997246e-04  4.71271721e-02  3.77760172e-02 -2.11665993e04 2.81989626e-03 -2.70339996e-03  8.11312465e-03 -4.81122794e02 -7.37327102e-06 -2.42134002e-02 -1.13120886e-03 -5.49730579e-02 -1.57359939e-04 -2.46637616e-03 -8.60664795e-04  8.15387570e-03]

w1 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]

w2 [-111.70644608 -164.50671691 -254.60942018 -205.06537232 -330.43317768 -94.6976 -346.78221607 -272.22044431 -249.54889015  -75.99543441]

weights1 [-0.09535479 -0.09824519 -0.11582134 -0.65075843 -0.65593035  0.77593957 -0.0406199 0.12669151  0.79979191 -0.52502487 -0.2433578 0.16617536 -0.25711996  0.92995152 -0.40922601 -0.63029133]

weights2 [-112.24597022 -164.86741004 -254.21715269 -205.27326963 -331.18579697 -95.07615178 -347.04311247 -271.82206581 -250.04075852  -76.69273265]

Второй запуск

trained_hidden [0.00000000e+000 1.00000000e+000 1.00000000e+000 3.77659154e-181 1.00000000e+000 0.00000000e+000 0.00000000e+000 0.00000000e+000 1.00000000e+000 0.00000000e+000 1.00000000e+000 0.00000000e+000 2.71000625e-055 0.00000000e+000 0.00000000e+000 1.00000000e+000]

trained_output [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]

o_error [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]

o-adjustment [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]

h_error [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]

h_adjustment [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]

w1 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]

w2 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]

weights1 [-0.09535479 -0.09824519 -0.11582134 -0.65075843 -0.65593035  0.77593957 -0.0406199   0.12669151  0.79979191 -0.52502487 -0.2433578   0.16617536 -0.25711996  0.92995152 -0.40922601 -0.63029133]

weights2 [-112.24597022 -164.86741004 -254.21715269 -205.27326963 -331.18579697 -95.07615178 -347.04311247 -271.82206581 -250.04075852  -76.69273265]

1 Ответ

1 голос
/ 25 июня 2019

Прежде всего, вы уверены, что ваши распечатки весов1 и весов2 верны?Они одинаковы между двумя прогонами с очень разными выходами, что мне кажется очень подозрительным.

Я немного проверил ваши производные и из того небольшого, что я изучил, они выглядят правильно.Однако я вижу две ошибки.При обновлении весов вы действительно хотите подтакт производную от ваших весов.Поскольку градиент всегда указывает в гору, и вы хотите минимизировать потери, следовательно, вы хотите идти в направлении спуска.Вторая возможная ошибка заключается в том, что вы используете полную производную в качестве обновления, в основном всегда, в нейронных сетях, используется скорость обучения (например, 0,001), которая используется в качестве множителя для производной обновления, если вы не уменьшаете своюградиент перед обновлением, возможно, что он будет очень сильно перегружен и, например, установит все ваши веса на очень большие значения, что приведет к очень нестабильной оптимизации.

Поэтому я предлагаю заменить:

weights1 += w1
weights2 += w2

with:

learning_rate = 0.001
weights1 -= w1 * learning_rate
weights2 -= w2 * learning_rate

Кроме того, общее правило при отладке нейронных сетей состоит в том, чтобы использовать минимальный пример, который должна соответствовать вашей сети, поэтому выберите один образец из набора данных и просматривайте обновления в каждой итерации,это скажет вам многое (например, используйте отладчик).Если вы не можете соответствовать одному примеру, вы не можете соответствовать 10000.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...