我有一个 Tensorflow 多类分类器,它正在生成nan
或inf
同时使用tf.nn.softmax
. 请参阅以下代码片段(logits
形状为batch_size x 6
,因为我有 6 个类并且输出是单热编码的)。batch_size
是 1024。
logits = tf.debugging.check_numerics(logits, message='bad logits', name=None)
probabilities = tf.nn.softmax(logits=logits, name='Softmax')
probabilities = tf.debugging.check_numerics(probabilities, message='bad probabilities', name=None)
分类器在最后一条语句上失败,因为它找到nan
或inf
。是干净的,否则第一个语句将失败。probabilities
logits
从我读到的内容来看tf.nn.softmax
,它可以处理 logits 中非常大和非常小的值。我已经在交互模式下验证了这一点。
>>> with tf.Session() as s:
... a = tf.constant([[1000, 10], [-100, -200], [3, 4.0]])
... sm = tf.nn.softmax(logits=a, name='Softmax')
... print(a.eval())
... print(sm.eval())
...
[[1000. 10.]
[-100. -200.]
[ 3. 4.]]
[[1. 0. ]
[1. 0. ]
[0.26894143 0.7310586 ]]
然后我尝试将这些值剪掉,logits
现在整个事情都可以工作了。请参阅下面的修改片段。
logits = tf.debugging.check_numerics(logits, message='logits', name=None)
safe_logits = tf.clip_by_value(logits, -15.0, 15.0)
probabilities = tf.nn.softmax(logits=safe_logits, name='Softmax')
probabilities = tf.debugging.check_numerics(probabilities, message='bad probabilities', name=None)
在第二个语句中,我将值裁剪logits
为 -15 和 15,这以某种方式阻止了nan
/inf
在 softmax 计算中。所以,我能够解决手头的问题。
但是,我仍然不明白为什么这个剪辑有效?(我应该提到 -20 和 20 之间的裁剪不起作用,并且模型在nan
或inf
中失败probabilities
)。
有人可以帮我理解为什么会这样吗?
我正在使用 tensorflow 1.15.0,在 64 位实例上运行。