softmax函数的实现returns nan for high inputs
Implementation of softmax function returns nan for high inputs
我试图在 cnn 的末尾实现 softmax,我得到的输出是 nan 和 zeros。我为 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
我收到 true divide and run time error
的错误
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,这样,而不是在 [-20000,20000] 中输入,您将得到一个输入浮动在 [-20, 20].
如果对大数应用 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.])
根据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]
,即 [-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 课程页面。 实际问题:数值稳定性。 标题正是我要解释的内容。
我试图在 cnn 的末尾实现 softmax,我得到的输出是 nan 和 zeros。我为 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
我收到 true divide and run time error
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,这样,而不是在 [-20000,20000] 中输入,您将得到一个输入浮动在 [-20, 20].
如果对大数应用 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.])
根据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]
,即 [-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 课程页面。 实际问题:数值稳定性。 标题正是我要解释的内容。