Рекомендации по использованию 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 с диапазоном значений функции активации.