Рекомендации по использованию ReLU в качестве функции активации

Я внедряю нейронную сеть и хотел использовать ReLU в качестве функции активации нейронов. Кроме того, я тренирую сеть с SDG и обратным распространением. Я тестирую нейронную сеть с парадигматической проблемой XOR, и до сих пор она правильно классифицирует новые выборки, если я использую логистическую функцию или гиперболический тангенс в качестве функций активации.

Я читал о преимуществах использования Leaky ReLU в качестве функции активации и реализовал его в Python следующим образом:

def relu(data, epsilon=0.1):
    return np.maximum(epsilon * data, data)

где np это имя для NumPy. Соответствующая производная реализована так:

def relu_prime(data, epsilon=0.1):
    if 1. * np.all(epsilon < data):
        return 1
    return epsilon

Используя эту функцию в качестве активации, я получаю неверные результаты. Например:

  • Вход = [0, 0] -> Выход = [0.43951457]

  • Вход = [0, 1] -> Выход = [0.46252925]

  • Вход = [1, 0] -> Выход = [0.34939594]

  • Вход = [1, 1] -> Выход = [0.37241062]

Видно, что выходы сильно отличаются от ожидаемых значений XOR. Таким образом, вопрос заключается в том, есть ли особые соображения по использованию ReLU в качестве функции активации?

Пожалуйста, не стесняйтесь спрашивать меня больше контекста или кода. Заранее спасибо.

РЕДАКТИРОВАТЬ: есть ошибка в производной, так как он возвращает только одно значение с плавающей запятой, а не массив NumPy. Правильный код должен быть:

def relu_prime(data, epsilon=0.1):
    gradients = 1. * (data > epsilon)
    gradients[gradients == 0] = epsilon
    return gradients

2 ответа

Решение

Ваш relu_prime функция должна быть:

def relu_prime(data, epsilon=0.1):
    gradients = 1. * (data > 0)
    gradients[gradients == 0] = epsilon
    return gradients

Обратите внимание на сравнение каждого значения в матрице данных с 0 вместо epsilon, Это следует из стандартного определения протекающих ReLU, которое создает кусочный градиент 1 когда x > 0 а также epsilon иначе.

Я не могу комментировать, являются ли утечки ReLU лучшим выбором для проблемы XOR, но это должно решить вашу проблему с градиентом.

Короткий ответ

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

Длинный ответ

Не могу сказать, если что-то не так с кодом Python, потому что я пишу на Java. Но по логике я считаю, что использование ReLU в этом случае - плохое решение. Поскольку мы прогнозируем XOR, диапазон значений вашего NN ограничен [0,1]. Это также диапазон функции активации сигмоида. С ReLU вы работаете со значениями [0, бесконечность], что означает, что существует огромное количество значений, которые вы никогда не собираетесь использовать, поскольку это XOR. Но ReLU все равно примет это значение во внимание, и ошибка, которую вы получите, увеличится. Вот почему вы получаете правильные ответы примерно в 50% случаев. На самом деле это значение может быть как 0%, так и 99%. Мораль истории - при принятии решения, какую функцию активации использовать, попытайтесь сопоставить диапазон входных значений в вашем NN с диапазоном значений функции активации.

Другие вопросы по тегам