在计算机里面数据都是以二进制的形式存储的,如果数据超过了计算机所能存储的最大范围,就会发生溢出。
softmax公式:
softmax公式里面因为存在指数函数,所以有可能会出现上溢或下溢的问题。如下面的例子所示:
import math
import numpy as np
def softmax(inp):
length = len(inp)
exps = []
res = 0
ind = 0
for item in inp:
exp = math.exp(item)
res = res + exp
exps.append(exp)
ind+=1
exps = np.array(exps)
return exps/res
inp = [1000,500,500]
inp1 = [-1000,-1000,-1000]
print("上溢:",softmax(inp))
print("下溢:",softmax(inp1))
当指数函数里面传入的值很大时,就会出现上溢,爆出OverflowError.
当指数函数里面传入的值是很小的负数时,就会出现下溢,输出结果就是0, 这样就有可能导致分母的值为0。比如,inp=[-1000,-1000,-1000]。
解决这个问题的方法就是利用softmax的冗余性。我们可以看到对于任意一个数a, x-a和x在softmax中的结果都是一样的。
所以,对于一组输入,我们可以让a=max(x). 这样就可以保证x-a的最大值等于0,也就不会产生上溢的问题。同时,因为一定有x-a=0,, 所以分母的值就不可能为0,也就解决了下溢的问题。大家可以去改改上面的代码看看。
在用梯度下降法最小化交叉熵损失函数的时候,对参数求导需要计算log(softmax)。用这个方法同样可以保证不会出现log(0)的情况,因为softmax的分母至少有一项为1,就不会等于0了。