当前位置: 首页 > 知识库问答 >
问题:

软最大函数的实现为高输入返回 nan

贲永思
2023-03-14

我试图在CNN的末尾实现softmax,我得到的输出是nan和零。我正在为softmax提供大约10-20k的高输入值,我给出一个X=[2345,3456,6543,-6789,-9234]数组。

我的职能是

def softmax (X):
    B=np.exp(X)
    C=np.sum(np.exp(X))
    return B/C

我得到真除法和运行时错误

C:\Anaconda\envs\deep_learning\lib\site-packages\ipykernel_launcher.py:4: RuntimeWarning: invalid value encountered in true_divide
  after removing the cwd from sys.path.

共有3个答案

长孙文栋
2023-03-14

当我运行相同的代码时,我得到:

RuntimeWarning: overflow encountered in exp
RuntimeWarning: overflow encountered in exp
RuntimeWarning: invalid value encountered in true_divide

这并不奇怪,因为 e^(6543) 约为 0.39 * 10^2842,这可能会导致以下操作中的溢出。

要做的事情:在将数据提供给softmax之前对其进行规范化:在将数据提供给softmax之前,您能否将其除以1000,这样,您就可以在[-20,20]中输入浮点数,而不是在[-20000,20000]中输入浮点数。

萧阳波
2023-03-14

如果对大量数字应用softmax,可以尝试使用最大规格化:

import numpy as np

def softmax (x):
    B=np.exp(x)
    C=np.sum(np.exp(x))
    return B/C

arr = np.array([1,2,3,4,5])

softmax(arr)
# array([0.01165623, 0.03168492, 0.08612854, 0.23412166, 0.63640865])

softmax(arr - max(arr))
# array([0.01165623, 0.03168492, 0.08612854, 0.23412166, 0.63640865])

如您所见,这不会影响softmax的结果。将此应用于您的softmax

def softmax(x):
    B = np.exp(x - max(x))
    C = np.sum(B)
    return B/C
op_arr = np.array([2345,3456,6543,-6789,-9234])
softmax(op_arr)
# array([0., 0., 1., 0., 0.])
督飞羽
2023-03-14

根据softmax函数,您需要迭代数组中的所有元素并计算每个单独元素的指数,然后将其除以所有元素的指数之和:

import numpy as np

a = [1,3,5]
for i in a:
    print np.exp(i)/np.sum(np.exp(a))

0.015876239976466765
0.11731042782619837
0.8668133321973349

然而,如果数字太大,指数可能会爆炸(计算机无法处理如此大的数字):

a = [2345,3456,6543]
for i in a:
    print np.exp(i)/np.sum(np.exp(a))

__main__:2: RuntimeWarning: invalid value encountered in double_scalars
nan
nan
nan

为避免这种情况,请首先将数组中的最大值平移到零。然后计算软最大值。例如,要计算 [1, 3, 5] 的软最大值,请使用 [1-5, 3-5, 5-5],即 [-4, -2, 0]。您也可以选择以矢量化方式实现它(正如您打算在有问题的方式中所做的那样):

def softmax(x):
    f = np.exp(x - np.max(x))  # shift values
    return f / f.sum(axis=0)

softmax([1,3,5])
# prints: array([0.01587624, 0.11731043, 0.86681333])

softmax([2345,3456,6543,-6789,-9234])
# prints: array([0., 0., 1., 0., 0.])

有关详细信息,请查看cs231n课程页面。实际问题:数值稳定性。标题正是我想解释的。

 类似资料:
  • 出于我无法控制的原因,我必须在我的C代码中实现这个函数: 调用此函数时,编译器是否忽略它,或者是否仍然进行调用?例如: 两行代码的执行时间是相同的,还是第一行需要更长的时间?

  • 问题内容: 如果我有 我有: 然后,我可以成功执行以下操作: 但是,假设我要在doSomething中添加另一个参数,例如: 如果我这样称呼,Go在编译时会抱怨: 带有: 有没有办法做到这一点,还是我应该放弃并将返回值分配给某些引用,并将msg和这些值传递给? 问题答案: 在规范中对此进行了描述。它要求内部函数返回所有参数的正确类型。没有多余的参数以及返回多个值的函数。 作为一种特殊情况,如果一个

  • 本文向大家介绍返回JavaScript中数组的最小值和最大值的函数,包括了返回JavaScript中数组的最小值和最大值的函数的使用技巧和注意事项,需要的朋友参考一下 问题 我们需要编写一个接受一个数组并返回另一个数组的JavaScript函数,该数组的第一个元素应该是输入数组的最小元素,第二个应该是输入数组的最大元素。 示例 以下是代码- 输出结果

  • 我有一个这样的方法,它通常用于返回。 在最后一行,我从Pylance那里得到了以下信息: (方法)is_file:()- 有没有一种方法可以正确地键入提示这种情况,以便Pylance知道是?或者我应该让它总是返回路径,并有另一个方法调用将输出转换为字符串,然后返回? 谢谢 编辑1 我刚刚意识到另一个更常见的场景: 在熊猫中,输入参数可以改变输出类型,Pylance也不能处理这个问题。Pylance

  • 我有一个接口,它的函数当前返回它自己。但是,我希望任何实现类都返回该类,而不是基接口。例如,在这个简化的示例中,它工作得很好: 这显然是失败的,因为重写函数不再与接口中的声明匹配。 我需要baz()返回Class而不是Interface,因为调用者可以以任意顺序调用bar和baz任意次数,但是目前所有bar()调用必须在所有baz()调用之前,除非我们重复地向下调用。 更复杂的是foo()函数,它

  • 函数getfile: 但我需要一个数组而不是这个promise的东西。怎么解决?