ReLU производная с NumPy - PullRequest
0 голосов
/ 01 мая 2018
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 Ответ

0 голосов
/ 01 мая 2018

Ваша первая ошибка в предположении, что 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.

...