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

TypeError: Exception encountered when calling layer "custom_crop_layer_2" " f"(type CustomCropLayer). #63788

Closed
pzy2000 opened this issue Mar 15, 2024 · 6 comments
Assignees
Labels
comp:keras Keras related issues stale This label marks the issue/pr stale - to be closed automatically if no activity stat:awaiting response Status - Awaiting response from author TF 2.10 type:bug Bug

Comments

@pzy2000
Copy link

pzy2000 commented Mar 15, 2024

Issue type

Bug

Have you reproduced the bug with TensorFlow Nightly?

Yes

Source

binary

TensorFlow version

tf 2.10.0

Custom code

Yes

OS platform and distribution

Linux Ubuntu 20.04.4

Mobile device

No response

Python version

3.7.6

Bazel version

No response

GCC/compiler version

No response

CUDA/cuDNN version

12.2

GPU model and memory

No response

Current behavior?

Expect:
successfully saved to tf format ckpt.
Now:
image

Traceback (most recent call last):
File "issue_tf2onnx_001.py", line 207, in
model.save(f'tmp/lenet5_sb', save_format='tf')
File "/opt/conda/envs/tf2onnx/lib/python3.7/site-packages/keras/utils/traceback_utils.py", line 70, in error_handler
raise e.with_traceback(filtered_tb) from None
File "/opt/conda/envs/tf2onnx/lib/python3.7/contextlib.py", line 119, in exit
next(self.gen)
File "issue_tf2onnx_001.py", line 77, in call
indices.append(slice(0 + crop[0], shape - crop[1]))
TypeError: Exception encountered when calling layer "custom_crop_layer_2" " f"(type CustomCropLayer).

unsupported operand type(s) for -: 'NoneType' and 'int'

Call arguments received by layer "custom_crop_layer_2" " f"(type CustomCropLayer):
• args=('tf.Tensor(shape=(None, None, None, 32), dtype=float32)',)
• kwargs={'training': 'False'}

Standalone code to reproduce the issue

import keras
import tensorflow as tf


class CustomCastLayer(keras.layers.Layer):
    def __init__(self, target_dtype, **kwargs):
        self.target_dtype = target_dtype
        super().__init__(**kwargs)

    def build(self, input_shape):
        """
        Do Nothing
        """
        super().build(input_shape)

    def call(self, inputs, **kwargs):
        output = tf.cast(inputs, self.target_dtype)
        return output

    def get_config(self):
        config = super().get_config()
        config.update({"target_dtype": self.target_dtype})
        return config

    def compute_output_shape(self, input_shape):
        """
        Do Nothing
        """
        return input_shape


class CustomPadLayer(keras.layers.Layer):
    def __init__(self, padding=[[0, 0]], constant_values=0, **kwargs):
        self.padding = padding  # add [0,0] to padding so we will not change the shape of batch dimension
        self.constant_values = constant_values
        super().__init__(**kwargs)

    def build(self, input_shape):
        super().build(input_shape)

    def call(self, inputs, **kwargs):
        output = tf.pad(inputs, paddings=tf.constant([[0, 0]] + self.padding), mode="CONSTANT",
                        constant_values=self.constant_values)
        return output

    def get_config(self):
        config = super().get_config()
        config.update({"padding": self.padding, "constant_values": self.constant_values})
        return config

    def compute_output_shape(self, input_shape):
        """
        Formula to calculate the output shape
        Suppose the input_shape is (None, N, W, C), the `paddings` is [[a, b], [c, d]].
        The output_shape is (None, N+a+b, W+c+d, C).
        """
        input_shape_list = list(input_shape)
        padding = [[0, 0]] + self.padding
        assert len(input_shape_list) == len(padding)  # Two dimensions should match.
        output_shape = [None]
        for i, pad in zip(input_shape_list[1:], padding[1:]):
            output_shape.append(i + pad[0] + pad[1])
        return tuple(output_shape)


class CustomCropLayer(keras.layers.Layer):
    def __init__(self, cropping, **kwargs):
        self.cropping = cropping
        super().__init__(**kwargs)

    def build(self, input_shape):
        super().build(input_shape)

    def call(self, inputs, **kwargs):
        input_shape = inputs.shape.as_list()
        indices = [slice(None)]
        cropping = [[0, 0]] + self.cropping  # add [0,0] to padding so we will not change the shape of batch dimension
        for shape, crop in zip(input_shape[1:], cropping[1:]):
            indices.append(slice(0 + crop[0], shape - crop[1]))
        return inputs[indices]

    def get_config(self):
        config = super().get_config()
        config.update({"cropping": self.cropping})
        return config

    def compute_output_shape(self, input_shape):
        """
        Formula to calculate the output shape
        Suppose the input_shape is (None, N, W, C), the `cropping` is [[a, b], [c, d]].
        The output_shape is (None, N-a-b, W-c-d, C).
        """
        input_shape_list = list(input_shape)
        cropping = [[0, 0]] + self.cropping
        assert len(input_shape_list) == len(cropping)  # Two dimensions should match.
        output_shape = [None]
        for i, crop in zip(input_shape[1:], cropping[1:]):
            output_shape.append(i - crop[0] - crop[1])
        return tuple(output_shape)


class CustomExpandLayer(keras.layers.Layer):
    def __init__(self, axis=1, **kwargs):
        self.axis = axis
        super().__init__(**kwargs)

    def build(self, input_shape):
        super().build(input_shape)

    def call(self, inputs, **kwargs):
        return tf.expand_dims(inputs, self.axis)

    def get_config(self):
        config = super().get_config()
        config.update({"axis": self.axis})
        return config

    def compute_output_shape(self, input_shape):
        """
        Formula to calculate the output shape
        Suppose the input_shape is [None, N, W, C]:
        axis=0:
            output_shape: [1, None, N, W, C]
        axis=1 (default):
            output_shape: [None, 1, N, W, C]
        axis=2:
            output_shape: [None, N, 1, W, C]
        axis=3:
            output_shape: [None, N, W, 1, C]
        axis=4:
            output_shape: [None, N, W, C, 1]
        axis=5:
            raise Exception
        """
        input_shape_list = list(input_shape)
        if self.axis > len(input_shape_list):
            raise ValueError(f"axis {self.axis} should be smaller than input_shape + 1: {len(input_shape_list) + 1}")
        output_shape = input_shape_list[0:self.axis] + [1] + input_shape_list[self.axis:]
        return tuple(output_shape)  # we should use tuple!!! not list !!!


class CustomDropDimLayer(keras.layers.Layer):
    def __init__(self, axis=1, **kwargs):
        self.axis = axis
        super().__init__(**kwargs)

    def build(self, input_shape):
        super().build(input_shape)

    def call(self, inputs, **kwargs):
        """
        Something magic to automatically generate indices for array slicing.
        To determine a specific axis, we can use slice(None) to replace `:`
        """
        dim = len(inputs.shape)
        if self.axis > dim - 1 or self.axis < 1:
            raise ValueError(f"axis: {self.axis} should be within the range: [1, {dim - 1}] for {dim}D tensor")
        indices = [slice(None) for i in range(dim)]
        indices[self.axis] = 0
        return inputs[indices]

    def get_config(self):
        config = super().get_config()
        config.update({"axis": self.axis})
        return config

    def compute_output_shape(self, input_shape):
        """
        Formula to calculate the output shape
        Suppose the input_shape is [None, N, W, C]:
        axis=0:  # Although it is feasible, we don't allow this to happen
            Raise Exception
        axis=1 (default):
            output_shape: [None, W, C]
        axis=2:
            output_shape: [None, N, C]
        axis=3:
            output_shape: [None, N, W]
        axis=4:
            Raise Exception
        """
        input_shape_list = list(input_shape)
        output_shape = input_shape_list[0:self.axis] + input_shape_list[self.axis + 1:]
        return tuple(output_shape)


def custom_objects(mode="custom"):
    def no_activation(x):
        return x

    def leakyrelu(x):
        import keras.backend as K
        return K.relu(x, alpha=0.01)

    # objects = {}
    objects = {'no_activation': no_activation, 'leakyrelu': leakyrelu}
    if mode == "custom":
        objects['CustomPadLayer'] = CustomPadLayer
        objects['CustomCropLayer'] = CustomCropLayer
        objects['CustomDropDimLayer'] = CustomDropDimLayer
        objects['CustomExpandLayer'] = CustomExpandLayer
        objects['CustomCastLayer'] = CustomCastLayer

    return objects


model_path = "/data1/pzy/MUTANTS/LEMON/lenet5_fashion/lenet5-fashion-mnist_origin-NLAll30-LMerg38-Edge63-NLAll90-92/lenet5-fashion-mnist_origin-NLAll30-LMerg38-Edge63-NLAll90.h5"
model = tf.keras.models.load_model(model_path, custom_objects=custom_objects())
# model = tf.keras.models.load_model(model_path,)
model.save(f'tmp/lenet5_sb', save_format='tf')

Relevant log output

Traceback (most recent call last):
  File "issue_tf2onnx_001.py", line 207, in <module>
    model.save(f'tmp/lenet5_sb', save_format='tf')
  File "/opt/conda/envs/tf2onnx/lib/python3.7/site-packages/keras/utils/traceback_utils.py", line 70, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "/opt/conda/envs/tf2onnx/lib/python3.7/contextlib.py", line 119, in __exit__
    next(self.gen)
  File "issue_tf2onnx_001.py", line 77, in call
    indices.append(slice(0 + crop[0], shape - crop[1]))
TypeError: Exception encountered when calling layer "custom_crop_layer_2" "                 f"(type CustomCropLayer).

unsupported operand type(s) for -: 'NoneType' and 'int'

Call arguments received by layer "custom_crop_layer_2" "                 f"(type CustomCropLayer):
  • args=('tf.Tensor(shape=(None, None, None, 32), dtype=float32)',)
  • kwargs={'training': 'False'}
@tilakrayal
Copy link
Contributor

@pzy2000,
The error message "unsupported operand type(s) for -: 'NoneType' and 'int'" suggests that a computation is attempted between NoneType (which indicates a missing value) and an integer. Also I tried to execute the mentioned code and it was executed with a different error. Kindly find the gist of it here and share the required dependencies. Thank you!

@tilakrayal tilakrayal added comp:keras Keras related issues stat:awaiting response Status - Awaiting response from author labels Mar 18, 2024
@pzy2000
Copy link
Author

pzy2000 commented Mar 18, 2024

@pzy2000, The error message "unsupported operand type(s) for -: 'NoneType' and 'int'" suggests that a computation is attempted between NoneType (which indicates a missing value) and an integer. Also I tried to execute the mentioned code and it was executed with a different error. Kindly find the gist of it here and share the required dependencies. Thank you!

sorry, I forgot to share the model file, it is here:
https://drive.google.com/file/d/14Lph3YKjXJVy3huIFCYoQJ4DrqgKs5tf/view?usp=sharing

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

@pzy2000,
I tried to execute the mentioned code using the .h5 file provided and execute with the different error. AFAIK I tried to execute the model with tensorflow v2.16, and tried to run the inference for the .h5 model which was on tensorflow older versions and it was failing due to this extra layer which was not present in before versions. Kindly find the gist of it here.

And also this issue is related to Keras, Could you please reach out to keras-team/keras repo for the quick response. Thank you!

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

github-actions bot commented Apr 9, 2024

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 Apr 9, 2024
Copy link

This issue was closed because it has been inactive for 7 days since being marked as stale. Please reopen if you'd like to work on this further.

Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
comp:keras Keras related issues stale This label marks the issue/pr stale - to be closed automatically if no activity stat:awaiting response Status - Awaiting response from author TF 2.10 type:bug Bug
Projects
None yet
Development

No branches or pull requests

2 participants