По сути, это то, что я делаю:
print (P, Q, R)
>>> tf.Tensor(4.0, shape=(), dtype=float32) 1024.0 tf.Tensor(315.0, shape=(), dtype=float32)
P*R/Q
>>> <tf.Tensor: shape=(), dtype=float32, numpy=1.2304688>
4.0*315.0/1024.0
>>> 1.23046875
Арифметика, выполненная с использованием констант, дает тот же результат, что и точное вычисление. Однако арифметика, выполненная с использованием тензоров, дает ответ, который отличается в двух последних местах.
Чтобы разобраться в этом, я попытался понять, как тензорное умножение происходит под капотом. По-видимому, сценарий, подробно описывающий процесс умножения тензоров TF, создается автоматически (Where скрипт gen_math_ops в тензорном потоке?)
Я сделал так, как предложил ответ, и нашел следующую функцию mul
:
def mul(x, y, name=None):
r"""Returns x * y element-wise.
*NOTE*: `Multiply` supports broadcasting. More about broadcasting
[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
Args:
x: A `Tensor`. Must be one of the following types: `bfloat16`, `half`, `float32`, `float64`, `uint8`, `int8`, `uint16`, `int16`, `int32`, `int64`, `complex64`, `complex128`.
y: A `Tensor`. Must have the same type as `x`.
name: A name for the operation (optional).
Returns:
A `Tensor`. Has the same type as `x`.
"""
_ctx = _context._context or _context.context()
tld = _ctx._thread_local_data
if tld.is_eager:
try:
_result = pywrap_tfe.TFE_Py_FastPathExecute(
_ctx, "Mul", name, x, y)
return _result
except _core._NotOkStatusException as e:
_ops.raise_from_not_ok_status(e, name)
except _core._FallbackException:
pass
try:
return mul_eager_fallback(
x, y, name=name, ctx=_ctx)
except _core._SymbolicException:
pass # Add nodes to the TensorFlow graph.
# Add nodes to the TensorFlow graph.
_, _, _op, _outputs = _op_def_library._apply_op_helper(
"Mul", x=x, y=y, name=name)
_result = _outputs[:]
if _execute.must_record_gradient():
_attrs = ("T", _op._get_attr_type("T"))
_inputs_flat = _op.inputs
_execute.record_gradient(
"Mul", _inputs_flat, _attrs, _result)
_result, = _result
return _result
К сожалению, я не мог понять этого и, следовательно, зашел в тупик.
Итак, мой вопрос двоякий:
- ожидается ли тензорная арифметика TF менее точной в том виде, в котором она представлена во фрагменте кода? Если да, то хотелось бы понять, почему так.
- Есть ли способ заставить тензорную арифметику TF быть настолько точной, насколько позволяет арифметика с постоянным числом с плавающей запятой, с минимальными изменениями в коде, например, с дополнительным аргументом или чем-то еще?
Любая помощь будет принята с благодарностью.