tensorflow: [TF 2.4] KerasTensor breaks typing compatibility
System information
- Have I written custom code (as opposed to using a stock example script provided in TensorFlow): yes
- OS Platform and Distribution (e.g., Linux Ubuntu 16.04): macOS
- TensorFlow installed from (source or binary): binary
- TensorFlow version (use command below): v2.4.0-rc0 and tf-nightly
- Python version: 3.8
The Problem
Since version 2.4 functional Keras models use KerasTensor
instead of tf.Tensor
as layer output types. Unfortunately KerasTensor
doesn’t subclass tf.Tensor
which breaks isinstance(x, tf.Tensor)
checks:
https://github.com/tensorflow/tensorflow/blob/6d9e0887f6bce8fbeeb430364e520d05350d96d5/tensorflow/python/keras/engine/keras_tensor.py#L63
The release notes recommend to use tf.is_tensor
instead.
In my opinion this is not really Pythonic and breaks compatibility with the TF Types RFC (/cc @mdanatg) wich even mentiones that tf.is_tensor
is expected to be deprecated eventually.
Concretely, switching from isinstance(x, tf.Tensor)
to tf.is_tensor
is also not possible in all cases. E.g. this breaks usage of static typecheckers like pytype
or typeguard
:
A common pattern which can also be found in TensorFlow Addons (/cc @seanpmorgan) is the following:
from typeguard import typechecked
import tensorflow as tf
@typechecked
def foo(x: tf.Tensor):
print(x.dtype)
foo(tf.keras.Input(shape=(32, 32, 3))) # Throws in TF 2.4 since `isintance` is used for typechecking
Possible solutions
-
Make
KerasTensor
a subclass oftf.Tensor
. @mihaimaruseac @fchollet is there a reason why this isn’t currently the case? -
Make
KerasTensor
a subclass oftypes.Tensor
. I don’t see any disadvantage of doing this in general, but it wouldn’t really fix this issue sincetypes.Tensor
is not exposed as part of the public API yet so users would need to rely on private TensorFlow APIs -
In usercode this could be fixed by directly relying on
KerasTensor
to replace the usage oftf.Tensor
with:from typing import Union from tensorflow.python.keras.engine.keras_tensor import KerasTensor TensorType = Union[tf.Tensor, KerasTensor]
I do not think this is a proper solution since it requires users to rely on internal APIs and implementation details that might change in the future.
I am currious to hear back from you on what the bestpractices for type checking of Tensors are, or whether I am just missing somthing obvious here.
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 15
- Comments: 17 (11 by maintainers)
Is there a way to convert KerasTensor to Tensorflow Tensor/Numpy Array? I’m trying to save the output of a model’s dense layer into an numpy array after training, but with no avail ;-;
We discussed creating a TF interface that KerasTensor can use, but unfortunately it not be available in 2.5.
Is there already a decision made on whether a fix for this will make it into the 2.5 release?
@Saduf2019 yes this is still an issue. The current temporary workaround relies on private TensorFlow function which isn’t a longterm solution. See https://github.com/tensorflow/tensorflow/issues/44613#issuecomment-732215759
@mdanatg Thanks for the info. It’s a bit cumbersome for library authors who want to support multiple versions of TensorFlow, but the workaround works fine.
I probably missed the RFC for the
KerasTensor
changes, otherwise I would’ve opened the issue earlier. In projects I maintain we don’t usually test againsttf-nightly
as broken builds are mostly false positives that get resolved shortly afterwards, but maybe I’ll reevaluate that to catch issues like this before the release branch gets cut.@mdanatg Any idea if a public KerasTensor or tf.Tensor subclass will land in TF2.4?