在Udacity's deep learning class中,y_i的软最大值只是指数除以整个y向量的指数之和:
其中,S(y_i)
是y_i
的softmax函数,e
是指数函数,j
是输入向量Y中的列数
我试过以下方法:
import numpy as np
def softmax(x):
"""Compute softmax values for each sets of scores in x."""
e_x = np.exp(x - np.max(x))
return e_x / e_x.sum()
scores = [3.0, 1.0, 0.2]
print(softmax(scores))
返回:
[ 0.8360188 0.11314284 0.05083836]
但建议的解决方案是:
def softmax(x):
"""Compute softmax values for each sets of scores in x."""
return np.exp(x) / np.sum(np.exp(x), axis=0)
它产生与第一个实现相同的输出,即使第一个实现显式地接受每列和max的差,然后除以和。
有人能从数学上说明原因吗?一个对一个错吗?
实现在代码和时间复杂性方面是否相似?哪个更有效?
(嗯。。。这里有很多困惑,无论是问题还是答案……)
首先,这两个解(即您的解和建议的解)是而不是等价的;它们发生仅在一维分数数组的特殊情况下是等价的。如果您也尝试过Udacity测试提供的示例中的二维分数数组,您就会发现它。
从结果上看,这两种解决方案之间唯一的实际区别是
axis=0
参数。为了证明这是真的,让我们试试您的解决方案(your_softmax
),其中唯一的区别是axis
参数:正如我所说,对于一维分数数组,结果确实是相同的:
然而,以下是作为测试示例的Udacity测验中给出的二维分数数组的结果:
结果是不同的-第二个结果确实与Udacity测验中预期的结果相同,其中所有列的总和确实为1,而第一个(错误的)结果则不是这样。
所以,所有的麻烦实际上都是为了实现细节-参数
axis
。根据numpy.sum documentation:在这里我们要按行求和,因此
axis=0
。对于一维数组,(仅)行的和和和所有元素的和碰巧是相同的,因此在这种情况下得到相同的结果。。。撇开
axis
问题不谈,您的实现(即您选择先减去最大值)实际上比建议的解决方案要好!事实上,这是实现softmax函数的推荐方法-请参见here以获得理由(数字稳定性,也由上面的一些答案指出)。它们都是正确的,但从数值稳定性的角度来看,最好是你的。
你从
通过使用a^(b-c)=(a^b)/(a^c)这个事实,我们得到了
另一个答案是。您可以用任何变量替换max(x),它将被取消。
所以,这确实是对沙漠人的回答的评论,但由于我的名声,我现在还不能评论。正如他所指出的,只有当您的输入包含一个样本时,您的版本才是正确的。如果您的输入包含多个示例,则它是错误的。然而,desternaut的解决方案也是错误的。问题是,一旦他接受一维输入,然后他接受二维输入。让我给你看看这个。
以逃兵为例:
这是输出:
您可以看到desenauts版本在这种情况下会失败。(如果输入像np.array([1,2,3,6])一样是一维的,那就不会了。
现在让我们使用3个样本,因为这就是我们使用二维输入的原因。下面的x2与desenauts示例中的x2不同。
此输入由一个包含3个样本的批组成。但样本一和样本三基本上是一样的。我们现在期望3行softmax激活,其中第一行应与第三行相同,也应与我们激活的x1相同!
我希望你能明白这只是我的解决方案。
此外,以下是TensorFlows softmax实现的结果:
结果是:
相关问题 更多 >
编程相关推荐