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?
Ваша первая ошибка заключается в предположении, что 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.
@ user6116844 И здесь вы ошибаетесь, потому что вы передали один и тот же объект ... вы нигде не копируете, а python не делает копии за вас неявно.
Ух ты!! Вы, сэр, очень помогли мне ... большое спасибо ... я так счастлив прямо сейчас
Ну и дела, спасибо ... честно говоря, я не понимаю, что вы имели в виду под inplace, что именно d_relu делает с y, потому что, насколько я понимаю, я передал копию y, поэтому все, что d_relu делает с копией, не должно влиять на y теперь должно это?