Python 针对高输入,softmax函数返回nan的实现

Python 针对高输入,softmax函数返回nan的实现,python,softmax,Python,Softmax,我试图在cnn的末尾实现softmax,我得到的输出是nan和零。我给softmax提供了大约10-20k的高输入值,我给了一个X=[23453456543,-6789,-9234] 我的职能是 def softmax (X): B=np.exp(X) C=np.sum(np.exp(X)) return B/C 我得到的错误是true除法和运行时错误 C:\Anaconda\envs\deep_learning\lib\site-packages\ipykernel_

我试图在cnn的末尾实现softmax,我得到的输出是nan和零。我给softmax提供了大约10-20k的高输入值,我给了一个
X=[23453456543,-6789,-9234]

我的职能是

def softmax (X):
    B=np.exp(X)
    C=np.sum(np.exp(X))
    return B/C
我得到的错误是
true除法和运行时错误

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.

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

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,这样,您就可以在[-2000020000]中输入数据,而不是在[-20,20]中以浮点形式输入数据。

如果对大量数字应用
softmax
,您可以尝试使用max规范化:

如您所见,这不会影响
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.])
根据,您需要迭代数组中的所有元素,并计算每个元素的指数,然后将其除以所有元素的指数之和:

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
但是,如果数字太大,指数可能会爆炸(计算机无法处理如此大的数字):

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

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

可能重复的
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
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.])