ReLU производная с NumPy
import numpy as np
def relu(z):
return np.maximum(0,z)
def d_relu(z):
z[z>0]=1
z[z<=0]=0
return z
x=np.array([5,1,-4,0])
y=relu(x)
z=d_relu(y)
print("y = {}".format(y))
print("z = {}".format(z))
Код выше распечатывает:
y = [1 1 0 0]
z = [1 1 0 0]
вместо
y = [5 1 0 0]
z = [1 1 0 0]
Из того, что я понимаю, вызовы функций, которые я использовал, должны были только передавать по значению, передавая копию переменной.
Почему моя функция d_relu влияет на переменную y?
1 ответ
Ваша первая ошибка в предположении, что python передает объекты по значению... это не так - это передача по присваиванию (аналогично передаче по ссылке, если вы знакомы с этой концепцией). Однако только изменяемые объекты, как следует из названия, могут быть изменены на месте. Это включает в себя, среди прочего, NumPy массивов.
Вы не должны иметь d_relu
модифицировать z
на месте, потому что это то, что он делает сейчас, через z[...] = ...
синтаксис. Вместо этого попробуйте создать маску с использованием переданного сравнения и вернуть ее.
def d_relu(z):
return (z > 0).astype(int)
Это возвращает новый массив вместо изменения z
на месте, и ваш код печатается
y = [5 1 0 0]
z = [1 1 0 0]
Если вы строите многоуровневую архитектуру, вы можете использовать вычисленную маску на этапе прямого прохода:
class relu:
def __init__(self):
self.mask = None
def forward(self, x):
self.mask = x > 0
return x * self.mask
def backward(self, x):
return self.mask
Где производная просто 1, если вход во время прямой связи, если> 0, иначе 0.