Производная 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?


person Egbert    schedule 01.05.2018    source источник


Ответы (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.

person cs95    schedule 01.05.2018
comment
Ого, большое спасибо ... честно говоря, я не понимаю, что вы имели в виду под inplace, что именно d_relu делает с y, потому что, насколько я понимаю, я передал копию y, поэтому все, что d_relu делает с копией, не должно влиять на y теперь должно? - person Egbert; 01.05.2018
comment
@user6116844 user6116844 И вот здесь вы ошибаетесь, потому что вы передали один и тот же объект ... вы нигде не делаете копий, и python неявно не делает копии для вас. - person cs95; 01.05.2018
comment
Ух ты!! Вы, сэр, очень помогли мне.. большое спасибо.. я так счастлив прямо сейчас - person Egbert; 01.05.2018