Logsoftmax 稳定性

8
我知道如何通过将-max _i x_i 添加到元素中来使softmax稳定。这可以避免溢出和下溢。现在,对此取对数可能会导致下溢。log softmax(x) 可能会评估为零,导致 - 无穷大。
我不确定如何解决它。我知道这是一个常见的问题。我读了几篇关于它的答案,但我还是不理解。但我仍然困惑如何解决这个问题。
附注:如果您提供一个简单的例子,那就太好了。
4个回答

13
为了稳定 Logsoftmax,大多数实现(如TensorflowThenao)使用一个技巧,取出最大的组件max(x_i)。这个技巧经常用于稳定计算softmax。对于logsoftmax,我们从以下内容开始:

formula

提取出exp(b)并使用log(exp(x)) = x这个事实,我们得到:

{{exp(b)}},然后使用{{log(exp(x)) = x}},我们得到:

formula

如果我们设定{{b = max(x_i)}},这个新方程具有溢出和下溢稳定条件。

在代码方面,如果x是一个向量:

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/


1

0

只需要使用这个,它就会处理 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)>

-1

数学技巧无法帮助您将log 0变成除了负无穷以外的其他值。 如果您仔细思考,唯一的方法是规范化数据,以避免出现这种情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接