softmax函数的运算涉及到了指数函数的计算,故对于计算机而言就存在了一个 “溢出问题”。因为指数函数的增长容易变得非常大,这些超大值之间进行除法,结果会出现 nan(not a number)计算机在进行数值运算时,数值的大小必须在4字节或者8字节的有效数据带宽内。
故需要对softmax函数进行改进:
从上述公式推导来看,在分子分母同乘以C常数,结果不变。故在softmax函数的指数运算中,加上或者减去某个常数并不会改变运算的结果(实际上是乘法)。
所以一般情况下,在指数上减去输入信号中的最大值(即ai的最大值),进行溢出抑制。
代码实现如下:
import numpy
import tensorflow as tf
def softmax(x, axis=-1):
x = x - np.max(x, axis=axis, keepdims=True) # 溢出对策
return np.exp(x) / np.sum(np.exp(x), axis=axis,keepdims=True)
a = np.array([[0.3, 2.9, 4.0],[0.5,0.6,1.2]])
y = softmax(a, axis=-1)
print("softmax",y) # softmax函数的形式决定
# tensorflow2.0直接就可以这样使用了,比tensorflow1.x好用多了
print("tf.math.sofmax",tf.math.softmax(a,axis=-1))