我声明了ReLU函数如下:
def relu(x):
return (x if x > 0 else 0)并且发生了一个ValueError,它的回溯消息是
ValueError:包含多个元素的数组的真值是不明确的。使用a.any()或a.all()
但是,如果我用numpy更改ReLU函数,它可以工作:
def relu_np(x):
return np.maximum(0, x)为什么这个函数(relu(x))不能工作?我无法理解..。
================================
使用的代码:
>>> x = np.arange(-5.0, 5.0, 0.1)
>>> y = relu(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "filename", line, in relu
return (x if x > 0 else 0)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()发布于 2022-01-26 09:12:17
请记住,如果您愿意的话,x > 0是一个布尔值数组,是一个掩码:
array([False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True])所以做if x>0是没有意义的,因为x包含几个元素,它们可以是True或False。这是您错误的根源。
numpy的第二个实现是很好的!另一个实现(也许更清楚?)可能是:
def relu(x):
return x * (x > 0)在这个实现中,我们对x进行元素乘法,x是沿x轴的一系列值,如果x的元素低于0,则乘以0,如果元素在上面,则为1。
发布于 2022-01-26 09:22:57
TLDR;您的第一个函数没有使用向量化的方法,这意味着它需要一个浮动/int值作为输入,而第二个函数则利用Numpy的矢量化。
NumPy中的矢量化
第二个函数使用numpy函数,该函数被向量化,并在数组的每个单独元素上运行。
import numpy as np
arr = np.arange(-5.0, 5.0, 0.5)
def relu_np(x):
return np.maximum(0, x)
relu_np(arr)
# array([0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.5, 1. ,
# 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5])但是,第二个函数使用三元操作符(x if x > 0 else 0),它期望输入单个值并输出单个值。这就是为什么当您传递单个元素时,它会工作,但是在传递数组时,它无法独立地运行每个元素上的函数。
def relu(x):
return (x if x > 0 else 0)
relu(-8)
## 0
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
注意:造成此错误的原因是由于您使用的是(x if x > 0 else 0)的三元操作符。条件x>0只能接受给定整数/浮点数的值True或False。但是,在传递数组时,在应用if,all()子句之前,需要使用类似于all()或all()的方法将布尔值列表聚合到单个值。
解决办法-
有几种方法可以让这件事-
1.使用np.vectorize (不推荐,性能低于纯numpy方法)
import numpy as np
arr = np.arange(-5.0, 5.0, 0.5)
def relu(x):
return (x if x > 0.0 else 0.0)
relu_vec = np.vectorize(relu)
relu_vec(arr)
# array([0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.5, 1. ,
# 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5])2.具有列表理解的数组的迭代
import numpy as np
arr = np.arange(-5.0, 5.0, 0.5)
def relu(x):
return (x if x > 0 else 0)
arr = np.array(arr)
np.array([relu(i) for i in arr])
# array([0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.5, 1. ,
# 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5])发布于 2022-01-26 09:12:28
免责声明:如果我错了,请有人纠正我,我不能百分之百地确定numpy是怎么做的。
您的函数relu需要一个数字值,并将其与0进行比较,并返回任何较大的值。x if x > 0 else 0将等于max(x, 0),其中max是内置的Python函数。
另一方面,relu_np使用numpy函数maximum,它接受2个数字,或数组,或迭代。这意味着您可以传递您的numpy数组x,它将最大的函数自动应用于每一项。我相信这就是所谓的“矢量化”。
要使relu函数按其工作方式工作,需要对其进行不同的调用。您必须手动将您的函数应用于每个元素。你可以做一些像y = np.array(list(map(relu, x)))这样的事情。
https://stackoverflow.com/questions/70860771
复制相似问题