Почему Tensorflow приводит int32 / int32 к float64 и как его остановить? - PullRequest
3 голосов
/ 05 июня 2019

Я делю тензор типа int32 на тензор типа int32, и в результате получается float64.Я не могу найти ответы относительно того, почему это происходит или есть неявные правила, объясняющие, как это делает Tensorflow.Я не определил явно dtype для любого тензора, но я проверил все из них, и ни один из них не имеет 64-битный тип до окончания деления.

Я пробовал использовать различные формулировки деления, такие как tf.поделитесь, все дают одинаковый результат.

Мой код выглядит так:

a_cdf = a / tf.size(a)

с существом типа tf.int32.

То, что я хочу получить, эторезультат как float32, так что я могу написать свою функцию без явного приведения.

1 Ответ

0 голосов
/ 07 июня 2019

Это по замыслу.«Истинное» деление в 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-разрядное число с плавающей запятой будет недостаточным.

Но опять же, это всего лишь догадка и больше упражнение на мысль, чем все остальное.

...