Функция активации Anano HiddenLayer
Можно ли использовать Rectified Linear Unit (ReLU) в качестве функции активации скрытого слоя вместо tanh()
или sigmoid()
в Theano? Реализация скрытого слоя выглядит следующим образом, и, насколько я искал в Интернете, ReLU не реализовано внутри Theano.
class HiddenLayer(object):
def __init__(self, rng, input, n_in, n_out, W=None, b=None, activation=T.tanh):
pass
Ответы
Ответ 1
relu легко сделать в Theano:
switch(x<0, 0, x)
Чтобы использовать его в вашем случае, создайте функцию python, которая будет выполнять relu и передать ее активации:
def relu(x):
return theano.tensor.switch(x<0, 0, x)
HiddenLayer(..., activation=relu)
Некоторые используют эту реализацию: x * (x > 0)
UPDATE: у более новой версии Theano есть доступный файл theano.tensor.nnet.relu(x).
Ответ 2
ОБНОВЛЕНИЕ: Последняя версия theano имеет встроенную поддержку ReLU:
T.nnet.relu, который должен быть предпочтительнее, чем пользовательские решения.
Я решил сравнить скорость решений, так как это очень важно для NN. Сравнивая скорость самой функции и ее градиент, в первом случае switch
является предпочтительным, градиент быстрее для x * (x > 0).
Все вычисленные градиенты верны.
def relu1(x):
return T.switch(x<0, 0, x)
def relu2(x):
return T.maximum(x, 0)
def relu3(x):
return x * (x > 0)
z = numpy.random.normal(size=[1000, 1000])
for f in [relu1, relu2, relu3]:
x = theano.tensor.matrix()
fun = theano.function([x], f(x))
%timeit fun(z)
assert numpy.all(fun(z) == numpy.where(z > 0, z, 0))
Output: (time to compute ReLU function)
>100 loops, best of 3: 3.09 ms per loop
>100 loops, best of 3: 8.47 ms per loop
>100 loops, best of 3: 7.87 ms per loop
for f in [relu1, relu2, relu3]:
x = theano.tensor.matrix()
fun = theano.function([x], theano.grad(T.sum(f(x)), x))
%timeit fun(z)
assert numpy.all(fun(z) == (z > 0)
Output: time to compute gradient
>100 loops, best of 3: 8.3 ms per loop
>100 loops, best of 3: 7.46 ms per loop
>100 loops, best of 3: 5.74 ms per loop
Наконец, сравните с тем, как градиент должен быть вычислен (самый быстрый способ)
x = theano.tensor.matrix()
fun = theano.function([x], x > 0)
%timeit fun(z)
Output:
>100 loops, best of 3: 2.77 ms per loop
Таким образом, anano генерирует неоптимальный код для градиента. IMHO, версия переключения сегодня должна быть предпочтительной.
Ответ 3
Я думаю, что более точно написать его таким образом:
x * (x > 0.) + 0. * (x < 0.)
Ответ 4
Я написал это вот так:
lambda x: T.maximum(0,x)
или
lambda x: x * (x > 0)
Ответ 5
В Python функция очень проста:
def relu(input):
output = max(input, 0)
return(output)