我试图在非常窄的值范围内扫描一些参数,并使用 bfloat16 epsilong 作为步长,以避免出现诸如
a-b==a
对于非常小的 b
之类的问题,但是我偶然发现了这种情况:
import torch
test = torch.Tensor([2.8438]).to(torch.bfloat16)
delta=torch.finfo(torch.bfloat16).eps
test - delta == test
Out[1]: tensor([True])
我认为epsilon的目的就是为了避免此类问题。我究竟做错了什么?我怎样才能得到下一个最小的数字?目前我正在使用:
if test - delta == test:
test = test - delta*2
else:
test = test - delta
这是可行的,但我担心我对 epsilon 的理解不正确..?
来自 Pytorch 文档:
eps | ... | 最小的可表示数字,使得 1.0 + eps != 1.0.
如您的示例
2.8438
> 2
* 1.0
所示,它的指数大于 1.0
的指数,因此 2.8438 + eps
!= 2.8438
不成立。
更新。对于任意数字,我们可能可以将
eps
移动该数字的指数:
import torch
import math
def anyEps(n):
if n == 0:
return torch.finfo(torch.bfloat16).eps
pow2 = 2**math.floor(math.log((abs(n),2))
return torch.finfo(torch.bfloat16).eps * pow2
test = torch.Tensor([2.8438]).to(torch.bfloat16)
delta = anyEps(test)
test - delta == test
# tensor([False])