AttributeError: 'KerasTensor' object has no attribute 'node'

How to get rid of this:
AttributeError: 'KerasTensor' object has no attribute 'node'

Was working fine with TF 2.4.1 but giving problem with TF 2.7.0

Script

types_inp = Input(shape=(self.len_of_types, ), dtype='int32') 
.......
out = Dense(self.num_ways, activation='softmax')(prob)
model = keras.Model(inputs=[types_inp,..],outputs=out]

Error:

AttributeError: 'KerasTensor' object has no attribute 'node'

I don’t know if you could minimize a share few lines of standalone code to reproduce this (or a Colab).

In the meantime you could check if it could be related to:

I was trying to reproduce codes used in the above git repo, here is what I found.

python -c 'import tensorflow; print(tensorflow.__version__)'

> 2.4.1
>>> from keras.engine.keras_tensor import KerasTensor  # imported from keras-team/keras
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'keras'
>>> 
>>> from tensorflow.python.keras.engine.keras_tensor import KerasTensor as KerasTensorFromTF # This import should not exist anymore
2022-01-28 10:19:31.459850: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0
>>> 
>>> assert KerasTensorFromTF == KerasTensor
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'KerasTensor' is not defined
>>> import tensorflow as tf
>>> 
>>> from tensorflow.keras.backend import is_keras_tensor
>>> from tensorflow.python.keras.backend import is_keras_tensor as is_keras_tensor_tf  # this import should not exist anymore
>>> 
>>> assert is_keras_tensor(tf.keras.Input([10]))
>>> assert is_keras_tensor_tf(tf.keras.Input([10]))

TF 2.4.1 has no issue

While TF V 2.7.0

$ python -c 'import tensorflow; print(tensorflow.__version__)'
2.7.0
>>> from keras.engine.keras_tensor import KerasTensor  # imported from keras-team/keras
>>> 
>>> from tensorflow.python.keras.engine.keras_tensor import KerasTensor as KerasTensorFromTF # This import should not exist anymore
>>> 
>>> assert KerasTensorFromTF == KerasTensor
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError
>>> import tensorflow as tf
>>> 
>>> from tensorflow.keras.backend import is_keras_tensor
>>> from tensorflow.python.keras.backend import is_keras_tensor as is_keras_tensor_tf  # this import should not exist anymore
>>> 
>>> assert is_keras_tensor(tf.keras.Input([10]))
>>> assert is_keras_tensor_tf(tf.keras.Input([10]))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/ccs/home/asd/.conda/envs/gdy_v2/lib/python3.9/site-packages/tensorflow/python/keras/backend.py", line 1281, in is_keras_tensor
    raise ValueError('Unexpectedly found an instance of type `' + str(type(x)) +
ValueError: Unexpectedly found an instance of type `<class 'keras.engine.keras_tensor.KerasTensor'>`. Expected a symbolic tensor instance.

In your last example I think that probably there is something in the namespace:

import tensorflow as tf
from tensorflow.keras.backend import is_keras_tensor
from tensorflow.python.keras.engine import keras_tensor

y=keras_tensor.KerasTensor(tf.TensorSpec(shape=[None,10], dtype=tf.int32))
x=tf.keras.Input([10])
print(str(type(y)))
print(str(type(x)))
assert(isinstance(y,keras_tensor.KerasTensor))
assert(isinstance(x,keras_tensor.KerasTensor))
<class 'tensorflow.python.keras.engine.keras_tensor.KerasTensor'>
<class 'keras.engine.keras_tensor.KerasTensor'>

---------------------------------------------------------------------------

AssertionError                            Traceback (most recent call last)

<ipython-input-47-051d59c54d14> in <module>()
      9 print(str(type(x)))
     10 assert(isinstance(y,keras_tensor.KerasTensor))
---> 11 assert(isinstance(x,keras_tensor.KerasTensor))
     12 

AssertionError: 

/cc @Scott_Zhu is this expected or there is a small bug in the namespace?

The code under tensorflow.keras is legacy, and should not be used.

The correct way of importing keras code is always from “from tensorflow import keras” or “import tensorflow as tf; tf.keras”

Directly “import keras” will access keras package python code directly (not exactly same as the public Keras API), which might lead to method/class not found.

2 Likes

At the first question, I always use

import tensorflow as tf
from tensorflow import keras

Still, I was getting

AttributeError: 'KerasTensor' object has no attribute 'node'

Do you think that we need to add a deprecation in Doc? As it is still in the official doc without any claim:

https://www.tensorflow.org/api_docs/python/tf/keras/backend/is_keras_tensor

# tf nightly (should be same as 2.7)
import tensorflow as tf
from tensorflow import keras

x=tf.keras.Input([10])
dense = tf.keras.layers.Dense(1)
y = dense(x)

assert(keras.backend.is_keras_tensor(x))
assert(keras.backend.is_keras_tensor(y))

assert(tf.keras.backend.is_keras_tensor(x))
assert(tf.keras.backend.is_keras_tensor(y))

Note that tensorflow.python.keras is not a valid import, and it is accessing legacy code that is about to delete. You should never import that directly.

In the end you could only use something like:

import tensorflow as tf

x=tf.keras.Input([10])
print(str(type(x)))
tf.keras.backend.is_keras_tensor(x)

Correct. tf.keras.backend.is_keras_tensor() should be the only public API to use.

I guess it was arising because

import tensorflow as tf
from tensorflow import keras
from tensorflow.python.keras.layers import Input, Dense,LSTM

now I moved to

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.layers import Input, Dense, LSTM

no issue as of now with TF 2.7.0

from tensorflow.python.keras.layers import Input, Dense,LSTM

tensorflow.python.* is a private API namespace, but as you know it could not be strongly enforced in python.

1 Like