Я хочу сделать простую нейронную сеть и хочу использовать функцию ReLU. Может кто-нибудь дать мне подсказку о том, как я могу реализовать функцию, используя numpy. Спасибо за ваше время!
Как реализовать функцию ReLU в Numpy
Ответ 1
Есть несколько способов.
>>> x = np.random.random((3, 2)) - 0.5
>>> x
array([[-0.00590765, 0.18932873],
[-0.32396051, 0.25586596],
[ 0.22358098, 0.02217555]])
>>> np.maximum(x, 0)
array([[ 0. , 0.18932873],
[ 0. , 0.25586596],
[ 0.22358098, 0.02217555]])
>>> x * (x > 0)
array([[-0. , 0.18932873],
[-0. , 0.25586596],
[ 0.22358098, 0.02217555]])
>>> (abs(x) + x) / 2
array([[ 0. , 0.18932873],
[ 0. , 0.25586596],
[ 0.22358098, 0.02217555]])
Если синхронизировать результаты со следующим кодом:
import numpy as np
x = np.random.random((5000, 5000)) - 0.5
print("max method:")
%timeit -n10 np.maximum(x, 0)
print("multiplication method:")
%timeit -n10 x * (x > 0)
print("abs method:")
%timeit -n10 (abs(x) + x) / 2
Получаем:
max method:
10 loops, best of 3: 239 ms per loop
multiplication method:
10 loops, best of 3: 145 ms per loop
abs method:
10 loops, best of 3: 288 ms per loop
Таким образом, умножение кажется самым быстрым.
Ответ 2
Если вы не возражаете против изменения x
, используйте np.maximum(x, 0, x)
. На это указал Даниэль С. Это намного быстрее, и потому что люди могут пропустить это, я перепишу это как ответ. Вот сравнение:
max method:
10 loops, best of 3: 238 ms per loop
multiplication method:
10 loops, best of 3: 128 ms per loop
abs method:
10 loops, best of 3: 311 ms per loop
in-place max method:
10 loops, best of 3: 38.4 ms per loop
Ответ 3
Я нашел более быстрый метод для ReLU с numpy. Вы также можете использовать функцию "причудливого индекса" numpy.
Фантастический индекс:
20,3 мс ± 272 мкс на петлю (среднее ± стандартное отклонение 7 прогонов, 10 циклов)
>>> x = np.random.random((5,5)) - 0.5
>>> x
array([[-0.21444316, -0.05676216, 0.43956365, -0.30788116, -0.19952038],
[-0.43062223, 0.12144647, -0.05698369, -0.32187085, 0.24901568],
[ 0.06785385, -0.43476031, -0.0735933 , 0.3736868 , 0.24832288],
[ 0.47085262, -0.06379623, 0.46904916, -0.29421609, -0.15091168],
[ 0.08381359, -0.25068492, -0.25733763, -0.1852205 , -0.42816953]])
>>> x[x<0]=0
>>> x
array([[ 0. , 0. , 0.43956365, 0. , 0. ],
[ 0. , 0.12144647, 0. , 0. , 0.24901568],
[ 0.06785385, 0. , 0. , 0.3736868 , 0.24832288],
[ 0.47085262, 0. , 0.46904916, 0. , 0. ],
[ 0.08381359, 0. , 0. , 0. , 0. ]])
Вот мой ориентир:
import numpy as np
x = np.random.random((5000, 5000)) - 0.5
print("max method:")
%timeit -n10 np.maximum(x, 0)
print("max inplace method:")
%timeit -n10 np.maximum(x, 0,x)
print("multiplication method:")
%timeit -n10 x * (x > 0)
print("abs method:")
%timeit -n10 (abs(x) + x) / 2
print("fancy index:")
%timeit -n10 x[x<0] =0
max method:
241 ms ± 3.53 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
max inplace method:
38.5 ms ± 4 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
multiplication method:
162 ms ± 3.1 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
abs method:
181 ms ± 4.18 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
fancy index:
20.3 ms ± 272 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
Ответ 4
Вы можете сделать это намного проще и без numpy:
def ReLU(x):
return x * (x > 0)
def dReLU(x):
return 1. * (x > 0)
Ответ 5
Сравнение Ричарда Мона несправедливо.
Как прокомментировал Андреа Ди Бьяджо, метод на месте np.maximum(x, 0, x)
изменит x в первом цикле.
Итак, вот мой тест:
import numpy as np
def baseline():
x = np.random.random((5000, 5000)) - 0.5
return x
def relu_mul():
x = np.random.random((5000, 5000)) - 0.5
out = x * (x > 0)
return out
def relu_max():
x = np.random.random((5000, 5000)) - 0.5
out = np.maximum(x, 0)
return out
def relu_max_inplace():
x = np.random.random((5000, 5000)) - 0.5
np.maximum(x, 0, x)
return x
Сроки это:
print("baseline:")
%timeit -n10 baseline()
print("multiplication method:")
%timeit -n10 relu_mul()
print("max method:")
%timeit -n10 relu_max()
print("max inplace method:")
%timeit -n10 relu_max_inplace()
Получите результаты:
baseline:
10 loops, best of 3: 425 ms per loop
multiplication method:
10 loops, best of 3: 596 ms per loop
max method:
10 loops, best of 3: 682 ms per loop
max inplace method:
10 loops, best of 3: 602 ms per loop
Метод максимума на месте только немного быстрее, чем метод максимума, и это может произойти, потому что он пропускает присвоение переменной для "out". И это все еще медленнее, чем метод умножения.
И так как вы реализуете функцию ReLU. Возможно, вам придется сохранить 'x' для backprop через relu. Например:
def relu_backward(dout, cache):
x = cache
dx = np.where(x > 0, dout, 0)
return dx
Поэтому я рекомендую вам использовать метод умножения.
Ответ 6
Это более точная реализация:
def ReLU(x):
return abs(x) * (x > 0)
Ответ 7
Если у нас есть 3 параметра (t0, a0, a1)
для Relu, то есть мы хотим реализовать
if x > t0:
x = x * a1
else:
x = x * a0
Мы можем использовать следующий код:
X = X * (X > t0) * a1 + X * (X < t0) * a0
X
есть матрица.
Ответ 8
У numpy не было функции relu, но вы сами определяете ее следующим образом:
def relu(x):
return np.maximum(0, x)
например:
arr = np.array([[-1,2,3],[1,2,3]])
ret = relu(arr)
print(ret) # print [[0 2 3] [1 2 3]]