Функция активации 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)