Использование правильной производной ReLU предотвращает обучение

Я пытаюсь реализовать обратное распространение с помощью ReLU в качестве функции активации. Если я не ошибаюсь, производная этой функции равна 1 при x > 0 и 0 при x ‹ 0. Используя эту производную, сеть вообще не обучается. При поиске других примеров я обнаружил, что большинство из них игнорируют часть 1 вместо X > 0 и просто оставляют значение x, что приводит к гораздо лучшим результатам. Интересно, почему это так?

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

import random

x = random.uniform(0, 1)
y = random.uniform(0, 1)
w = random.uniform(0, 1)
lr = 0.1

for i in range(500):
    z = x * w
    yP = z
    if yP < 0:
        yP = 0
    loss = (yP - y)**2
    print(i, loss)

    grad_y=2.0*(yP - y)
    grad_z = grad_y
    if z < 0:
        grad_z = 0
    else :
        grad_z = grad_y
    grad_w = grad_z * x
    w -= lr * grad_w

Обратите внимание: вряд ли это связано с размером сети, которую я также тестировал в сети с 1000 входными нейронами, 1 скрытым слоем со 100 нейронами и 10 выходными нейронами. Я использовал размер партии 64 и 500 эпох. Была такая же проблема.


person Ymi_Yugy    schedule 03.08.2018    source источник
comment
Прежде всего, попробуйте выполнить обратное распространение со смещением. Во-вторых, потери следует использовать как 1/2 (yP-y)^2 для простоты обратного распространения (у grad_y нет 2). Наконец, почему вы инициализируете x и y здесь как случайные числа? Поскольку это случайные числа, я не думаю, что есть какая-то функция, которую можно использовать для их соединения.   -  person Minh-Tuan Nguyen    schedule 04.08.2018
comment
Я создаю свои входы и выходы случайным образом, потому что это всего лишь тестовая сеть, и у меня нет под рукой реальных данных. Сеть просто изучает эту партию снова и снова. Это не должно быть проблемой, поскольку NN является аппроксиматором произвольной функции. Я могу изменить функцию ошибки, чтобы использовать 1/2, но это не решает проблему. Странно то, что он учится правильно, как только я использую x = x для положительной части производной, противоположной x = 1, которая была бы правильной производной.   -  person Ymi_Yugy    schedule 04.08.2018


Ответы (1)


Я только что понял, какую глупую ошибку я совершил. В соответствии с цепным правилом grad_y следует умножать на производную ReLU в точке h, которая равна 0 или 1. Это, конечно, эквивалентно простой установке ее на 0, если производная равна 0.

person Ymi_Yugy    schedule 12.08.2018