Comment mettre en œuvre la fonction ReLU dans Numpy
je veux faire un simple réseau neuronal et je veux utiliser la fonction ReLU. Est-ce que quelqu'un peut me donner un indice de Comment puis-je mettre en œuvre la fonction en utilisant numpy. Merci pour votre temps!
7 réponses
il y a plusieurs façons.
>>> 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]])
si chronométrage des résultats avec le code suivant:
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
, Nous obtenons:
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
donc la multiplication semble être la plus rapide.
si cela ne vous dérange pas que x
soit modifié, utilisez np.maximum(x, 0, x)
. Cela a été souligné par Daniel s . Il est beaucoup plus rapide et parce que les gens pourraient l'ignorer, je vais reposter comme une réponse. Voici la comparaison:
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
j'ai trouvé une méthode plus rapide pour ReLU avec numpy. Vous pouvez également utiliser la fonction index de fantaisie de num PY.
envie d'index:
20.3 ms ± 272 µs par boucle (moyenne ± MST. dev. sur 7 passages, 10 boucles chacune)
>>> 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. ]])
Voici mon benchmark:
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)
Vous pouvez le faire de manière beaucoup plus facile et sans numpy:
def ReLU(x):
return x * (x > 0)
def dReLU(x):
return 1. * (x > 0)
Richard Möhn de comparaison n'est pas juste.
Comme le commentaire de Andrea Di Biagio , la méthode en place np.maximum(x, 0, x)
modifiera x à la première boucle.
Alors voici mon benchmark:
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
le Calendrier:
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()
obtenir les résultats:
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
méthode du maximum en place est seulement un peu plus rapide que la méthode maximum, et il peut parce qu'il omet l'assignation de variable pour "out". Et c'est toujours plus lent que la méthode de multiplication.
Et puisque vous mettez en place le ReLU func. Vous devrez peut-être sauvegarder le 'x' pour backprop à travers relu. Par exemple:
def relu_backward(dout, cache):
x = cache
dx = np.where(x > 0, dout, 0)
return dx
Donc, je vous recommande d'utiliser la méthode de multiplication.
c'est une mise en œuvre plus précise:
def ReLU(x):
return abs(x) * (x > 0)
si nous avons 3 paramètres (t0, a0, a1)
pour Relu, c'est-à-dire que nous voulons implémenter
if x > t0:
x = x * a1
else:
x = x * a0
nous pouvons utiliser le code suivant:
X = X * (X > t0) * a1 + X * (X < t0) * a0
X
il y a une matrice.