softmax函数的实现对于大量输入返回nan

时间:2019-02-26 07:28:29

标签: python softmax

enter image description here

我正在尝试在cnn的末尾实现softmax,我得到的输出是nan和0。我给10-20k左右的softmax提供高输入值,给我T-SQL

的数组

我的功能是

X=[2345,3456,6543,-6789,-9234]

我遇到了def softmax (X): B=np.exp(X) C=np.sum(np.exp(X)) return B/C

错误
true divide and run time error

3 个答案:

答案 0 :(得分:1)

如果大量应用softmax,则可以尝试使用 max规范化

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.])

答案 1 :(得分:0)

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

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,这样,您将有输入作为浮点数输入,而不是输入[-20000,20000] [-20,20]。

答案 2 :(得分:0)

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

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

为避免这种情况,请首先将数组中的最大值移到。然后计算softmax。例如,要计算[1, 3, 5]的softmax,请使用[1-5, 3-5, 5-5]的{​​{1}}。您也可以选择矢量化的实现方式(如您打算做的那样):

[-4, -2, 0]

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