keras icon indicating copy to clipboard operation
keras copied to clipboard

Loading model Conv2DTranspose from h5 file results in error complaining about group:1 parameter

Open dmagee opened this issue 1 year ago • 13 comments
trafficstars

Loading a .h5 model created in TensorFlow.keras containing Conv2DTranspose layer in keras-core results in an error:

Exception encountered: Unrecognized keyword arguments passed to Conv2DTranspose: {'groups': 1}

A hacky fix is to edit keras_core/src/ops/operation.py in the method from_config() so:

    try:
        if cls.__name__=="Conv2DTranspose" and "groups" in config: 
            config.pop("groups")
        return cls(**config)
....

I've yet to confirm the resultant network behaves exactly the same as the original, but it seems to work. It's obviously not the ideal solution. I'm not quite sure what that parameter does, as it's not something I used when creating the network. I imagine most legacy networks using Conv2DTranspose will have the same issue.

Model is here if helpful: https://drive.google.com/file/d/1Jn9C4vTRVWgHCqAXnMfO_i-B3pK4c14I/view?usp=sharing

Note:it also has the issue raised here about Lambda layers: https://github.com/keras-team/keras/issues/19151 (I proposed a hack there, and it looks like a better solution is being worked on)

Derek

dmagee avatar Apr 04 '24 14:04 dmagee

Can you try to create a model in Keras 3 instead of keras_core and try to load it in the same version and let us know the outcome of it. Thanks

sachinprasadhs avatar Apr 04 '24 23:04 sachinprasadhs

I'm a bit confused about keras versions. I thought Keras 3 and keras-core were basically the same thing? The model I'm having issues with was created by tf-keras, and I'm trying to load into the latest version of keras-core (installed via pip as keras-core). Do you actually want me to try to install keras 3 (if so how), or do you wnat me to try to generate a model in keras-core (this is on the todo list for next week anyway).

dmagee avatar Apr 05 '24 14:04 dmagee

keras-core was a pre-release for Keras 3, now Keras 3 is available and all the latest updates will be made available in the Keras 3 release. you can install it though pip install -U keras

sachinprasadhs avatar Apr 05 '24 19:04 sachinprasadhs

I'm only getting keras 2.15.0 when I do that? I'm on windows with Python 3.8. Am I doing something wrong, or has Keras 3 not reached windows yet?

dmagee avatar Apr 08 '24 10:04 dmagee

Also, 2.15.0 doesn't actually allow you to import keras as it fails with a tensorflow related error. The maximum tensorflow version that seems to be available is 2.13.1, which works with keras 2.13.1.

dmagee avatar Apr 08 '24 10:04 dmagee

I managed to install keras3 by starting with a fresh installation of python 3.11 and just installing pytorch and keras (plus packaging and pandas which appear to be dependencies of keras but aren't configured as such). The same problem(s) exist with this version as with keras_core loading historic models from tf-keras, and the same hacky fix(es) work to get the model loaded. I'm going to port our model generation code over now, and see if a h5 generated by keras3 will have the same issue (not that that solves anything for legacy models). I'll report back.

dmagee avatar Apr 08 '24 11:04 dmagee

I can now confirm that if the model is created in Keras 3, and saved as .h5 the problem does not occur. It only occurs with historic models created in tf.keras. However, we (and customers) have a large collections of such models.

dmagee avatar Apr 08 '24 12:04 dmagee

Could you please provide some sample reproducible code to replicate the reported behavior. Thanks

sachinprasadhs avatar Apr 09 '24 18:04 sachinprasadhs

The minimal code below will throw that error with the model I linked above. However, first you need to fix https://github.com/keras-team/keras/issues/19151. I proposed a hack for that there, but I see there are some posts, so I'll go respond to that now.

import os
os.environ["KERAS_BACKEND"] = "torch"

import keras 
from keras.layers import Lambda

@keras.saving.register_keras_serializable()
class Linear(keras.layers.Layer):
    def __init__(self, units=32, input_shape=None, name=None,**kwargs):
        super(Linear, self).__init__(trainable=True, name=name)
        self.op_shape = input_shape
        self.units=units
        self.name=name


    def build(self, input_shape):

        self.b = self.add_weight(
            name="b",
            shape=(self.units,),
            initializer=keras.initializers.RandomNormal(mean=0.0, stddev=0.01),
            trainable=True
        )
        super(Linear, self).build(input_shape)
        

    def get_config(self):
        config = super(Linear, self).get_config()
        config['units'] = self.units
        config['input_shape'] = self.op_shape
        return dict(list(config.items()))
    @classmethod
    def from_config(cls, config):
        units_config = config.pop("units")
        units = keras.saving.deserialize_keras_object(units_config)
        input_shape_config = config.pop("input_shape")
        input_shape = keras.saving.deserialize_keras_object(input_shape_config)
        name = config.pop("name")
		
        return cls(units=units,input_shape=input_shape,name=name)
		
    def call(self, inputs):

        return keras.layers.LeakyReLU(negative_slope=0.01)(inputs + keras.ops.broadcast_to(self.b,[self.op_shape[0],self.op_shape[1],self.units]))

with keras.utils.custom_object_scope({'Linear': Linear}):		
        model = keras.models.load_model('old_keras_model.h5',compile=False, custom_objects={'LeakyReLU': keras.layers.LeakyReLU(negative_slope=0.01),'Linear':Linear})

dmagee avatar Apr 10 '24 12:04 dmagee

Unfortunately this code snippet is not reproducible since it refers to 'old_keras_model.h5'. Do you have a reproducible code snippet? You can attach files to GitHub comments.

fchollet avatar Apr 12 '24 16:04 fchollet

@fchollet I attached the model above. For convenience it is here: https://drive.google.com/file/d/1Jn9C4vTRVWgHCqAXnMfO_i-B3pK4c14I/view?usp=sharing

dmagee avatar Apr 12 '24 18:04 dmagee

Adding this solves the problem (click me.)
# hack to change model config from keras 2->3 compliant
import h5py
f = h5py.File("/content/old_keras_model.h5", mode="r+")
model_config_string = f.attrs.get("model_config")
if model_config_string.find('"groups": 1,') != -1:
    model_config_string = model_config_string.replace('"groups": 1,', '')
    f.attrs.modify('model_config', model_config_string)
    f.flush()
    model_config_string = f.attrs.get("model_config")
    assert model_config_string.find('"groups": 1,') == -1

f.close()

As it was indicated in #19151, in this comment.

Is the it fixed for you @dmagee ?

I include a GIST that downloads and instantiates the model and problem (removing the snippet I provided above from it).

newresu avatar Aug 06 '24 01:08 newresu

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

github-actions[bot] avatar Aug 21 '24 01:08 github-actions[bot]

This issue was closed because it has been inactive for 28 days. Please reopen if you'd like to work on this further.

github-actions[bot] avatar Sep 04 '24 01:09 github-actions[bot]

Are you satisfied with the resolution of your issue? Yes No

google-ml-butler[bot] avatar Sep 04 '24 01:09 google-ml-butler[bot]

try using tensorflow version 2.12.1, worked for me.

CS-DaviMagalhaes avatar Oct 26 '24 19:10 CS-DaviMagalhaes

try using tensorflow version 2.12.1, worked for me.

Yeah using this version helped me too.

danyQe avatar Jan 05 '25 17:01 danyQe

try using tensorflow version 2.12.1, worked for me.

help me tooooooo much 😊

luojin avatar Jan 07 '25 07:01 luojin

I'm facing the exact same issue when trying to load a model file that was given to me (no access to training data):

# Python 3.9.23 (main, Sep 30 2025, 00:43:48) 
# [GCC 14.2.0] on linux
# Type "help", "copyright", "credits" or "license" for more information.

import tensorflow as tf
from tensorflow import keras

tf.version.VERSION # '2.20.0'
keras.__version__  # '3.10.0'

file = '/app/model.h5'
m = keras.models.load_model(file)

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/keras/src/ops/operation.py", line 256, in from_config
    return cls(**config)
  File "/usr/local/lib/python3.9/site-packages/keras/src/layers/convolutional/conv2d_transpose.py", line 115, in __init__
    super().__init__(
  File "/usr/local/lib/python3.9/site-packages/keras/src/layers/convolutional/base_conv_transpose.py", line 94, in __init__
    super().__init__(
  File "/usr/local/lib/python3.9/site-packages/keras/src/layers/layer.py", line 291, in __init__
    raise ValueError(
ValueError: Unrecognized keyword arguments passed to Conv2DTranspose: {'groups': 1}

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.9/site-packages/keras/src/saving/saving_api.py", line 196, in load_model
    return legacy_h5_format.load_model_from_hdf5(
  File "/usr/local/lib/python3.9/site-packages/keras/src/legacy/saving/legacy_h5_format.py", line 133, in load_model_from_hdf5
    model = saving_utils.model_from_config(
  File "/usr/local/lib/python3.9/site-packages/keras/src/legacy/saving/saving_utils.py", line 88, in model_from_config
    return serialization.deserialize_keras_object(
  File "/usr/local/lib/python3.9/site-packages/keras/src/legacy/saving/serialization.py", line 495, in deserialize_keras_object
    deserialized_obj = cls.from_config(
  File "/usr/local/lib/python3.9/site-packages/keras/src/models/model.py", line 651, in from_config
    return functional_from_config(
  File "/usr/local/lib/python3.9/site-packages/keras/src/models/functional.py", line 560, in functional_from_config
    process_layer(layer_data)
  File "/usr/local/lib/python3.9/site-packages/keras/src/models/functional.py", line 523, in process_layer
    layer = saving_utils.model_from_config(
  File "/usr/local/lib/python3.9/site-packages/keras/src/legacy/saving/saving_utils.py", line 88, in model_from_config
    return serialization.deserialize_keras_object(
  File "/usr/local/lib/python3.9/site-packages/keras/src/legacy/saving/serialization.py", line 504, in deserialize_keras_object
    deserialized_obj = cls.from_config(cls_config)
  File "/usr/local/lib/python3.9/site-packages/keras/src/ops/operation.py", line 258, in from_config
    raise TypeError(
TypeError: Error when deserializing class 'Conv2DTranspose' using config={'name': 'conv2d_transpose', 'trainable': True, 'dtype': 'float32', 'filters': 512, 'kernel_size': [3, 3], 'strides': [2, 2], 'padding': 'same', 'data_format': 'channels_last', 'dilation_rate': [1, 1], 'groups': 1, 'activation': 'linear', 'use_bias': True, 'kernel_initializer': {'class_name': 'GlorotUniform', 'config': {'seed': None}}, 'bias_initializer': {'class_name': 'Zeros', 'config': {}}, 'kernel_regularizer': None, 'bias_regularizer': None, 'activity_regularizer': None, 'kernel_constraint': None, 'bias_constraint': None, 'output_padding': None}.

Exception encountered: Unrecognized keyword arguments passed to Conv2DTranspose: {'groups': 1}

swiss-knight avatar Oct 03 '25 12:10 swiss-knight