Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding TensorFlow Hub KerasLayer to Sequential Model Raises ValueError #63849

Open
ruddyscent opened this issue Mar 17, 2024 · 16 comments
Open
Assignees
Labels
awaiting PR merge awaiting PR merge comp:keras Keras related issues TF 2.16 type:bug Bug

Comments

@ruddyscent
Copy link

Issue type

Bug

Have you reproduced the bug with TensorFlow Nightly?

Yes

Source

source

TensorFlow version

2.16.1

Custom code

No

OS platform and distribution

Ubuntu 22.04.3 LTS

Mobile device

No response

Python version

Python 3.11.0rc1

Bazel version

No response

GCC/compiler version

No response

CUDA/cuDNN version

12.3.0

GPU model and memory

No response

Current behavior?

I can execute the following code without any issues in TensorFlow 2.15.0 and TensorFlow Hub 1.16.1. However, when I upgrade the TensorFlow version to 2.16.0 or above, I encounter an error stating that KerasLayer cannot be added to the Sequential model.

Standalone code to reproduce the issue

import tensorflow as tf
import tensorflow_hub as hub

image_size = 224
URL = "https://tfhub.dev/tensorflow/efficientnet/b0/feature-vector/1"

model = tf.keras.Sequential([
        hub.KerasLayer(URL, input_shape=(image_size, image_size, 3))
])

Relevant log output

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[29], line 1
----> 1 model = tf.keras.Sequential([
      2         feature_extractor,
      3         tf.keras.layers.Dense(2, activation = 'softmax')
      4 ])
      6 model.build([None, image_size, image_size, 3])
      7 model.summary()

File /usr/local/lib/python3.10/dist-packages/keras/src/models/sequential.py:70, in Sequential.__init__(self, layers, trainable, name)
     68 if layers:
     69     for layer in layers:
---> 70         self.add(layer, rebuild=False)
     71     self._maybe_rebuild()

File /usr/local/lib/python3.10/dist-packages/keras/src/models/sequential.py:92, in Sequential.add(self, layer, rebuild)
     90         layer = origin_layer
     91 if not isinstance(layer, Layer):
---> 92     raise ValueError(
     93         "Only instances of `keras.Layer` can be "
     94         f"added to a Sequential model. Received: {layer} "
     95         f"(of type {type(layer)})"
     96     )
     97 if not self._is_layer_name_unique(layer):
...
    101         "the name of a layer in this model. Update the `name` argument "
    102         "to pass a unique name."
    103     )

ValueError: Only instances of `keras.Layer` can be added to a Sequential model. Received: <tensorflow_hub.keras_layer.KerasLayer object at 0x7a4ac7e30f40> (of type <class 'tensorflow_hub.keras_layer.KerasLayer'>)
@Aloqeely
Copy link
Contributor

Aloqeely commented Mar 17, 2024

After investigating the code, I found a potential cause of the issue in tensorflow_hub/keras_layer.py lines 26-31:

# Use Keras 2.
version_fn = getattr(tf.keras, "version", None)
if version_fn and version_fn().startswith("3."):
  import tf_keras as keras
else:
  keras = tf.keras

Depending on the Keras version, the module might either import tf_keras or directly use tf.keras, the former causes the isinstance(layer, Layer) check in Sequential.add to return False for hub.KerasLayer, even though it inherits from keras.layers.Layer

@SuryanarayanaY SuryanarayanaY added comp:keras Keras related issues TF 2.16 labels Mar 18, 2024
@SuryanarayanaY
Copy link
Collaborator

Hi @ruddyscent ,

TFHub has dependency on tf_keras package (i.e Keras2) as per the setup.py of TFHub.

https://github.com/tensorflow/hub/blob/ff72e25fef44bd67d5c14fb5328aa44e303e3404/tensorflow_hub/pip_package/setup.py#L31

Since TF2.16 comes with Keras3 the problem arises. As a workaround, you can install tf_keras package and set environment variable TF_USE_LEGACY_KERAS=1 to ensure Keras2 will be used with tf.keras.

@SuryanarayanaY
Copy link
Collaborator

After investigating the code, I found a potential cause of the issue in tensorflow_hub/keras_layer.py lines 26-31:

# Use Keras 2.
version_fn = getattr(tf.keras, "version", None)
if version_fn and version_fn().startswith("3."):
  import tf_keras as keras
else:
  keras = tf.keras

Depending on the Keras version, the module might either import tf_keras or directly use tf.keras, the latter causes the isinstance(layer, Layer) check in Sequential.add to return False for hub.KerasLayer, even though it inherits from keras.layers.Layer

Hi, When I tried with TF2.16v on Colab environment the error stack seems generated from the _ensure_keras_2_importable() function from tensorflow_hub/__init__.py as per attached gist.

@SuryanarayanaY
Copy link
Collaborator

# Use Keras 2.
version_fn = getattr(tf.keras, "version", None)
if version_fn and version_fn().startswith("3."):
  import tf_keras as keras
else:
  keras = tf.keras

Even this code seems confusing to me. If version_fn results in Keras3 then it tries to import tf_keras to use Keras2 else it assumes Keras2 is alreday there(i.e TF<=2.15v) hence it takes keras=tf.keras.

But version_fn = getattr(tf.keras, "version", None) returns None making this to use tf.keras (i.e Keras3) which ic not compatible with TF_Hub.

@SuryanarayanaY SuryanarayanaY added the stat:awaiting response Status - Awaiting response from author label Mar 18, 2024
@Aloqeely
Copy link
Contributor

# Use Keras 2.
version_fn = getattr(tf.keras, "version", None)
if version_fn and version_fn().startswith("3."):
  import tf_keras as keras
else:
  keras = tf.keras

Even this code seems confusing to me. If version_fn results in Keras3 then it tries to import tf_keras to use Keras2 else it assumes Keras2 is alreday there(i.e TF<=2.15v) hence it takes keras=tf.keras.

But version_fn = getattr(tf.keras, "version", None) returns None making this to use tf.keras (i.e Keras3) which ic not compatible with TF_Hub.

Actually, version_fn is not None, that code works as intended, which is to use Keras 2

tf.keras.Sequential is on Keras 3. and hub.KerasLayer is on Keras 2, so I believe due to the version difference, it causes isinstance(layer, Layer) to fail and return False

@google-ml-butler google-ml-butler bot removed the stat:awaiting response Status - Awaiting response from author label Mar 18, 2024
@SuryanarayanaY
Copy link
Collaborator

# Use Keras 2.
version_fn = getattr(tf.keras, "version", None)
if version_fn and version_fn().startswith("3."):
  import tf_keras as keras

From the code above if version_fn is not None and if it starts with "3" (which means Keras 3 found) in that case it is importing tf_keras package as keras. Please note that tf_keras package is for Keras2. This indicates TFHub supports only Keras2 package.

The else part it assumes that version_fn doesn't starts with "3" which case it assumes Keras2 installed with TF package and it marks keras=tf.keras. But for any case if version_fn becomes None and if Keras3 installed with TF then tf.keras will become Keras3 which might a problem.

@Aloqeely , Could you please import TF2.16 and confirm what will be the version_fn output ?

@SuryanarayanaY SuryanarayanaY added the stat:awaiting response Status - Awaiting response from author label Mar 21, 2024
@Aloqeely
Copy link
Contributor

Here you go

import tensorflow as tf

version_fn = getattr(tf.keras, "version", None)
print("TF Version: " + tf.__version__)
print("TF Keras Version: " + version_fn())

Output:

TF Version: 2.16.1
TF Keras Version: 3.0.5

@google-ml-butler google-ml-butler bot removed the stat:awaiting response Status - Awaiting response from author label Mar 21, 2024
@Aloqeely
Copy link
Contributor

Aloqeely commented Mar 21, 2024

Hi @ruddyscent ,

TFHub has dependency on tf_keras package (i.e Keras2) as per the setup.py of TFHub.

https://github.com/tensorflow/hub/blob/ff72e25fef44bd67d5c14fb5328aa44e303e3404/tensorflow_hub/pip_package/setup.py#L31

Since TF2.16 comes with Keras3 the problem arises. As a workaround, you can install tf_keras package and set environment variable TF_USE_LEGACY_KERAS=1 to ensure Keras2 will be used with tf.keras.

If this workaround fixes ruddyscent's problem, then I think we should mark this issue as resolved, because the problem is tensorflow hub not supporting Keras 3, so it is not relevant to this repository.

@SuryanarayanaY
Copy link
Collaborator

3.0.5

This means when tf.keras version is 3.x then Hub suggesting to import tf_keras as keras which is a Keras2 package. For that we should install with tf_keras package using pip install tf_keras. But from the error log the package is having keras/src which seems to be from Keras3 package for me.

@SuryanarayanaY SuryanarayanaY added the stat:awaiting response Status - Awaiting response from author label Mar 21, 2024
@Aloqeely
Copy link
Contributor

This means when tf.keras version is 3.x then Hub suggesting to import tf_keras as keras which is a Keras2 package. For that we should install with tf_keras package using pip install tf_keras. But from the error log the package is having keras/src which seems to be from Keras3 package for me.

Yep, hub does that.
The error log is caused by tf.keras.Sequential (Keras 3, hence the error is produced from keras/src) after it received a hub.KerasLayer (Keras 2)

@google-ml-butler google-ml-butler bot removed the stat:awaiting response Status - Awaiting response from author label Mar 21, 2024
@sj-yoon
Copy link

sj-yoon commented Mar 23, 2024

win10, no gpu, no colab

tensorflow_hub를 사용하시려면 다음과 같이 해보세요
import tensorflow as tf
import tensorflow_hub as hub
import tf_keras as keras """tensorflow_hub 설치시 자동으로 설치됩니다."

...
...
model = keras.Sequential([ """"tf.keras --> keras"""
hub,KerasLayer(url, input_shape=(size, size, 3)
...
...
imgfile = keras.utils.get_file('image.jpg', 'https://..........') """"tf.keras --> keras"""
작동이 잘됩니다.

@ruddyscent
Copy link
Author

Thank you, @sj-yoon, for your assistance.

The solution provided by @SuryanarayanaY works well for my situation.

@alishhde
Copy link

alishhde commented May 3, 2024

I had the same issue, and I could fix it with the solution provided by @SuryanarayanaY. Thanks

Others can check my notebook for steps to fix it at this page.

piotrsok2 pushed a commit to piotrsok2/cv-course that referenced this issue May 20, 2024
@tilakrayal
Copy link
Contributor

Could you please check whether this issue is resolved with the latest tensorflow v2.17 which contains Keras 3.0 version. As Keras3 now built to support multiple backends there are some changes in design.

Also this issue is more related to Keras, please try to raise the issue in keras-team/Keras repo for the quick resolution. Thank you!

@tilakrayal tilakrayal added the stat:awaiting response Status - Awaiting response from author label Aug 16, 2024
Copy link

This issue is stale because it has been open for 7 days with no activity. It will be closed if no further activity occurs. Thank you.

@github-actions github-actions bot added the stale This label marks the issue/pr stale - to be closed automatically if no activity label Aug 24, 2024
@Dobiasd
Copy link

Dobiasd commented Aug 26, 2024

Could you please check whether this issue is resolved with the latest tensorflow v2.17 which contains Keras 3.0 version.

The problem still exists with the latest tensorflow version (currently 2.17.0) as the following minimal Dockerfile shows:

FROM python:3.12.5

RUN pip3 install tensorflow==2.17.0 tensorflow-hub==0.16.1

RUN echo 'import tensorflow as tf' > main.py
RUN echo 'import tensorflow_hub as hub' >> main.py
RUN echo 'model = tf.keras.Sequential([hub.KerasLayer("https://tfhub.dev/tensorflow/efficientnet/b0/feature-vector/1", input_shape=(224, 224, 3))])' >> main.py

RUN python main.py
docker build --rm --progress=plain .

Output:

...
6.058   File "//main.py", line 3, in <module>
6.058     model = tf.keras.Sequential([hub.KerasLayer("https://tfhub.dev/tensorflow/efficientnet/b0/feature-vector/1", input_shape=(224, 224, 3))])
6.058             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6.058   File "/usr/local/lib/python3.12/site-packages/keras/src/models/sequential.py", line 74, in __init__
6.058     self.add(layer, rebuild=False)
6.058   File "/usr/local/lib/python3.12/site-packages/keras/src/models/sequential.py", line 96, in add
6.058     raise ValueError(
6.058 ValueError: Only instances of `keras.Layer` can be added to a Sequential model. Received: <tensorflow_hub.keras_layer.KerasLayer object at 0x7ff1f3d0be60> (of type <class 'tensorflow_hub.keras_layer.KerasLayer'>)

@google-ml-butler google-ml-butler bot removed stale This label marks the issue/pr stale - to be closed automatically if no activity stat:awaiting response Status - Awaiting response from author labels Aug 26, 2024
@tilakrayal tilakrayal added the awaiting PR merge awaiting PR merge label Sep 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting PR merge awaiting PR merge comp:keras Keras related issues TF 2.16 type:bug Bug
Projects
None yet
Development

No branches or pull requests

8 participants