我知道如何通过添加元素 -max _i x_i 来使 softmax 稳定。这避免了上溢和下溢。现在,记录这个可能会导致下溢。log softmax(x) 可以计算为零,导致 -infinity。
我不知道如何解决它。我知道这是一个常见的问题。我看了几个答案,我不明白。但我仍然对如何解决这个问题感到困惑。
PS:如果你提供一个简单的例子,那就太棒了。
我知道如何通过添加元素 -max _i x_i 来使 softmax 稳定。这避免了上溢和下溢。现在,记录这个可能会导致下溢。log softmax(x) 可以计算为零,导致 -infinity。
我不知道如何解决它。我知道这是一个常见的问题。我看了几个答案,我不明白。但我仍然对如何解决这个问题感到困惑。
PS:如果你提供一个简单的例子,那就太棒了。
为了稳定, Tensorflow和ThenaoLogsoftmax
等大多数实现都使用了取出最大组件的技巧。这个技巧常用于稳定计算。对于,我们从:max(x_i)
softmax
logsoftmax
在提取exp(b)
并使用 的事实之后log(exp(x)) = x
,我们有:
如果我们设置,这个新方程同时具有上溢和下溢稳定条件。
在代码方面, ifx
是一个向量:
def log_softmax(x):
x_off = x - np.max(x)
return x_off - np.log(np.sum(np.exp(x_off)))
另见:https ://timvieira.github.io/blog/post/2014/02/11/exp-normalize-trick/
logsoftmax = logits - log(reduce_sum(exp(logits), dim))
参考:https ://www.tensorflow.org/api_docs/python/tf/nn/log_softmax
只需使用它,因为它会照顾 Nan
tf.nn.softmax_cross_entropy_with_logits(
labels, logits, axis=-1, name=None
)
logits = tf.constant([[4, 5, 1000]], dtype = tf.float32)
labels = tf.constant([[1,0,1]], dtype = tf.float32)
# Case-1
output = tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=logits)
print(output)
>>> tf.Tensor([996.], shape=(1,), dtype=float32)
#Case-2
a = tf.nn.softmax(logits)
output = tf.reduce_sum(-(labels * tf.math.log(a)))
print(output)
>>> tf.Tensor(nan, shape=(), dtype=float32)
# this happens because value of softmax truncates to zero
print(a)
>>> <tf.Tensor: shape=(1, 3), dtype=float32, numpy=array([[0., 0., 1.]], dtype=float32)>
数学技巧不能帮助您创建log 0
除 -inf 之外的东西。如果你认为它是低谷的,唯一的方法是你规范化数据,这样你就不会在那里结束。