Нейронная сеть функции Relu, выводящая 0 или 1 - PullRequest
0 голосов
/ 26 сентября 2019

Я попытался реализовать простую нейронную сеть, используя функции sigmoid и relu.с сигмовидной функцией я получил несколько хороших результатов.но при использовании relu я получил либо массив 0, либо 1.(Мне нужна функция relu, потому что я хочу использовать код для некоторых выходов> 1).

def relu(x):
return np.maximum(0,x)

def reluDerivative(x):
  x[x<=0] = 0
  x[x>0] = 1
  return x
training_inputs = np.array([[9, 0 , 1],
[7, 1, 1],
[8, 0, 1],
[5, 1, 1]
])

training_outputs = np.array([[9, 7, 8, 5]]).T

np.random.seed(1)

synaptic_weights = 2 * np.random.random((3,1)) - 1


for iteration in range(100000):

   outputs = relu(np.dot(training_inputs, synaptic_weights))


   error = training_outputs - outputs
   adjustments = error * reluDerivative(outputs)
   synaptic_weights += np.dot(training_inputs.T, adjustments )

print("output after training: \n" , outputs)

1 Ответ

0 голосов
/ 26 сентября 2019

Обновление :

(Спасибо за включение методов relu и reluDerivative)

Ошибка действительно в методе reluDerivative(x).

Когдавы делаете x[x<=0] = 0, вы модифицируете данный массив numpy.Аргумент x не является клоном / глубокой копией outputs, это точно такой же массивный массив.Поэтому, когда вы модифицируете x, вы также модифицируете outputs.

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

Обновление 2

Похоже, код имеет больше проблем, чем приведенный выше, и они немного сложнее:

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

    • Что ж, вы могли бы использовать другие семена (например, seed = 10), но это не является удовлетворительным решением
    • Эта проблема была бы гораздо менее вероятной, если бы у вас был гораздо больший тренировочный набор(например, 100 вместо 4), поскольку маловероятно, что все 100 приведут к отрицательным точечным произведениям.
    • Я заметил, что первый элемент в каждой строке данных намного больше, чем остальные.Выполнение «нормализации» набора данных позволило бы избежать этой проблемы.Вы можете прочитать больше о том, как нормализовать ввод.
    • Наконец, эта проблема «нулевого градиента» с ReLU именно поэтому и была изобретена «LeakyReLU».В более крупных нейронных сетях регулярные ReLU могут быть достаточными в части четкости, но в вашем упрощенном примере LeaklyReLU наверняка избежал бы этой проблемы.
  • Как только вы решите вышеуказанные проблемы, вы все равно заметите другую проблему.Ошибки и градиенты будут взорваны в течение нескольких итераций.Это связано с тем, что вы еще не используете параметр «скорость обучения» для ограничения скорости обновления весов.Узнайте, как использовать параметр скорости обучения (или альфа).

Удачи!

...