提问人:Jason Gross 提问时间:11/14/2023 最后编辑:Jason Gross 更新时间:11/15/2023 访问量:76
某些(所有?)库不通过 log1p(x) = log(1 + x) 实现 log_softmax 是有原因的吗?
Is there a reason some (all?) libraries don't implement log_softmax via log1p(x) = log(1 + x)?
问:
据我了解,PyTorch 实现为 ,以增加数值稳定性。(例如,请参阅此处。但是,当最大值远大于其余值时(float32 大约大 16,float64 大约 36),则返回最大值,此时它可以给出更精确的答案。log_softmax(x)
x - x.max() - (x - x.max()).exp().sum().log()
log_softmax
0
从数字上看,我们有
>>> eps = torch.tensor(torch.finfo(torch.float32).eps)
>>> -torch.tensor([1-(2*eps).log(), 0]).log_softmax(dim=0)
tensor([1.1921e-07, 1.6249e+01])
>>> -torch.tensor([1-eps.log(), 0]).log_softmax(dim=0)
tensor([-0.0000, 16.9424])
(对于 float16,这是 7.2e-4。
据我了解,并使用某种多项式(?)级数扩展在引擎盖下实现。(参见,例如,这个答案)1.19e-7 是 float32 在 1 附近的最低精度单位,但 float32 可以表示小到通常 (, ) 或大约 1.18e-45 () 不正常的值。因此,在更高的精度方面有很大的空间,这可以通过具有诸如 which is 但精度更高的函数来实现,以及 which is 但对 的微小值具有更高的精度。然后我们可以实现为log
exp
torch.finfo(torch.float32).smallest_normal
2**-126 = 2**-(2**7 - 2)
2**-126 * 2**-23
expm1(x)
exp(x) - 1
log1p(x)
log(1 + x)
x
log_softmax(x)
maxi = x.argmax()
xoffset = x - x[maxi]
xoffsetexp = xoffset.exp()
# xoffsetexp[maxi] is currently about 1
xoffsetexp[maxi] = 0
xoffsetexp_sum_m1 = xoffsetexp.sum()
return xoffset - xoffsetexp_sum_m1.log1p()
例如,在某些情况下,这可能使模型训练不会像以前那样早地被浮点误差所支配。
是否有任何库以这种方式实现log_softmax
?是否有理由避免以这种方式实施log_softmax
?
答: 暂无答案
评论
log_softmax
log_softmax