为什么 Tensorflow 将 int32/int32 转换为 float64 以及如何停止它?
Why does Tensorflow cast int32/int32 to float64 and how to stop it?
我用一个int32类型的张量除以一个int32类型的张量,结果是float64。我找不到关于为什么会发生这种情况的答案,或者 Tensorflow 如何执行此操作背后是否存在隐含规则。我没有为任何张量明确定义 dtype,但我检查了所有张量,并且 none 其中 none 在除法之前具有 64 位类型。
我试过使用不同的除法公式,例如 tf.divide,都给出了相同的结果。
我的代码如下:
a_cdf = a / tf.size(a)
具有 tf.int32 类型的存在。
我想要得到的结果是 float32,所以我可以在没有显式转换的情况下编写我的函数。
这是设计使然。 "True" TensorFlow中的除法(也就是实数除法)使用了一个_TRUEDIV_TABLE
来指定每个类型的转换规则,目前是这样写的:
# Conversion table for __truediv__. None entries mean no conversion required.
_TRUEDIV_TABLE = {
dtypes.uint8: dtypes.float32,
dtypes.int8: dtypes.float32,
dtypes.uint16: dtypes.float32,
dtypes.int16: dtypes.float32,
dtypes.int32: dtypes.float64,
dtypes.int64: dtypes.float64,
dtypes.bfloat16: None,
dtypes.float16: None,
dtypes.float32: None,
dtypes.float64: None,
dtypes.complex64: None,
dtypes.complex128: None,
}
意味着 int32
张量将被转换为 float64
。如果您想获得 float32
作为输出,请使用较小的 int 类型或将您的输入转换为 float32
.
这样做的理由是另一回事。如果我不得不猜测,一方面我会说如果您使用 8 位或 16 位整数,您可能会担心内存,因此较小的结果类型是有意义的。但是,您也可以给出以下参数:
import numpy as np
# Compute smallest positive divisions with 16 and 32 bits
smallest_16bit_fraction = 1 / ((1 << 16) - 1)
smallest_32bit_fraction = 1 / (-(1 << 31)) # 31 bits because int32 is signed
# Compute one plus the smallest fractions with 32 and 64 bit floats
print(np.float32(1) + np.float32(smallest_16bit_fraction))
# 1.0000153
print(np.float64(1) + np.float64(smallest_16bit_fraction))
# 1.0000152590218967
print(np.float32(1) + np.float32(smallest_32bit_fraction))
# 1.0
print(np.float64(1) + np.float64(smallest_32bit_fraction))
# 0.9999999995343387
因此您可能会认为,作为两个整数值的除法,您可能希望将结果与整数混合,但正如您所见,对于 32 位整数,在某些情况下,32 位浮点数会下溢。
但同样,这只是猜测,更多的是一种思维练习。
我用一个int32类型的张量除以一个int32类型的张量,结果是float64。我找不到关于为什么会发生这种情况的答案,或者 Tensorflow 如何执行此操作背后是否存在隐含规则。我没有为任何张量明确定义 dtype,但我检查了所有张量,并且 none 其中 none 在除法之前具有 64 位类型。
我试过使用不同的除法公式,例如 tf.divide,都给出了相同的结果。
我的代码如下:
a_cdf = a / tf.size(a)
具有 tf.int32 类型的存在。
我想要得到的结果是 float32,所以我可以在没有显式转换的情况下编写我的函数。
这是设计使然。 "True" TensorFlow中的除法(也就是实数除法)使用了一个_TRUEDIV_TABLE
来指定每个类型的转换规则,目前是这样写的:
# Conversion table for __truediv__. None entries mean no conversion required.
_TRUEDIV_TABLE = {
dtypes.uint8: dtypes.float32,
dtypes.int8: dtypes.float32,
dtypes.uint16: dtypes.float32,
dtypes.int16: dtypes.float32,
dtypes.int32: dtypes.float64,
dtypes.int64: dtypes.float64,
dtypes.bfloat16: None,
dtypes.float16: None,
dtypes.float32: None,
dtypes.float64: None,
dtypes.complex64: None,
dtypes.complex128: None,
}
意味着 int32
张量将被转换为 float64
。如果您想获得 float32
作为输出,请使用较小的 int 类型或将您的输入转换为 float32
.
这样做的理由是另一回事。如果我不得不猜测,一方面我会说如果您使用 8 位或 16 位整数,您可能会担心内存,因此较小的结果类型是有意义的。但是,您也可以给出以下参数:
import numpy as np
# Compute smallest positive divisions with 16 and 32 bits
smallest_16bit_fraction = 1 / ((1 << 16) - 1)
smallest_32bit_fraction = 1 / (-(1 << 31)) # 31 bits because int32 is signed
# Compute one plus the smallest fractions with 32 and 64 bit floats
print(np.float32(1) + np.float32(smallest_16bit_fraction))
# 1.0000153
print(np.float64(1) + np.float64(smallest_16bit_fraction))
# 1.0000152590218967
print(np.float32(1) + np.float32(smallest_32bit_fraction))
# 1.0
print(np.float64(1) + np.float64(smallest_32bit_fraction))
# 0.9999999995343387
因此您可能会认为,作为两个整数值的除法,您可能希望将结果与整数混合,但正如您所见,对于 32 位整数,在某些情况下,32 位浮点数会下溢。
但同样,这只是猜测,更多的是一种思维练习。