英文:
What does drelu[z <= 0] = 0 mean?
问题
他基本上是将drelu中所有z对应元素小于或等于0的值替换为零。第二行代码的作用是将z中小于等于0的元素对应位置的drelu值置为0。这样做是为了在ReLU函数的反向传播中处理负数输入。
英文:
I am currently reading the nnfs book by Harrison Kinsley, and in describing the derivative of the ReLU function in back propagation, he uses this code
drelu = dvalues.copy()
drelu[z <= 0] = 0
Where he is essentially replacing all the values of drelu with zero where the corresponding element in z is less than or equal to 0. What does the second line mean/do, what is the particular thing happening (just asking so that I can understand what is going on and to use it for future projects).
Python btw
I got an np array that was equivalent to the z array but every value that was <=0 was 0 (expected output)
答案1
得分: 5
z <= 0
创建一个与 z
大小完全相同的布尔数组,在那些 z <= 0
的位置为True,其他位置为False。
drelu[a_boolean_array] = 0
将 drelu
设置为0,仅在布尔数组为True的位置。如果两个数组大小不同,会进行广播操作,但在这里不是问题。
将这两者结合起来,你可以看到 drelu[z <= 0] = 0
将 drelu
在 z
小于或等于0的位置设置为0。
英文:
z <= 0
creates a boolean array of the exact same size as z
that is True in those locations were z <= 0
and False elsewhere.
drelu[a_boolean_array] = 0
sets drelu
to 0 only at those locations where the boolean array is True. If the two arrays are different sizes, various broadcasting happens, but that's not an issue here.
Combining these two, you can see that drelu[z <= 0] = 0
sets drelu
to 0 at the locations where z
is less than or equal to 0;
答案2
得分: 0
我对 numpy
的设置不是特别熟悉,所以我尝试创建具有相同行为的自定义数据类型。我认为这可能是一个说明性的例子,以帮助理解库可能如何设置以支持这种语法:
class Thing:
def __init__(self, inner):
self.inner = inner
def __le__(self, val):
return Thing(list(map(lambda x: x <= val, self.inner)))
def __setitem__(self, key, value):
if isinstance(key, Thing):
for i, v in enumerate(key.inner):
if v:
self.inner[i] = value
else:
self.inner[key] = value
def __repr__(self):
return str(self.inner)
z = Thing([1,2,3,4,5])
print(z <= 3)
d = Thing([1,1,1,1,1])
d[z <= 3] = 0
print(d)
运行这个小脚本,我们可以看到 print(z <= 3)
将调用我们自定义的 __le__
方法来将基本的 Thing
转换为包含布尔值的 Thing
。当我们将其传递给索引语法时,现在调用了自定义的 __setitem__
方法。
最终,看起来该库充分利用了 Python 的数据模型,为一些常见操作提供了更方便的简写。不足之处在于,未经了解的人可能会觉得这种行为出乎意料,难以阅读和理解。
要完全了解 numpy
允许的各种选项,您必须查阅它们的文档:https://numpy.org/doc/stable/reference/arrays.ndarray.html#indexing-arrays
英文:
I was not super familiar with how numpy
(presumably) was set up so I went about trying to make my own data type with the same behavior. I think it might be illustrative as an example to help understand how a library might be set up to support this syntax:
class Thing:
def __init__(self, inner):
self.inner = inner
def __le__(self, val):
return Thing(list(map(lambda x: x <= val, self.inner)))
def __setitem__(self, key, value):
if isinstance(key, Thing):
for i, v in enumerate(key.inner):
if v:
self.inner[i] = value
else:
self.inner[key] = value
def __repr__(self):
return str(self.inner)
z = Thing([1,2,3,4,5])
print(z <= 3)
d = Thing([1,1,1,1,1])
d[z <= 3] = 0
print(d)
Running this small script we can see that print(z <= 3)
will convert the base Thing
into an Thing
containing boolean values by calling our custom __le__
method on Thing
. When we pass that to the index syntax and the custom __setitem__
method is now called.
At the end of the day, it seems the library is taking extreme advantage of pythons data model to provide more convenient short hands for some common operations. The downside is that the uninitiated may find this behavior unexpected and difficult to read / reason about.
To fully understand the range of options numpy
allows, you have to turn to their docs: https://numpy.org/doc/stable/reference/arrays.ndarray.html#indexing-arrays
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论