keras-team / keras

Deep Learning for humans
http://keras.io/
Apache License 2.0
61.37k stars 19.39k forks source link

Irregular Tensors as output from Generator class with batch size = 1 #19925

Closed hansschaa closed 6 days ago

hansschaa commented 3 weeks ago

Hello, I have a problem creating a generator and expecting it to work with tensors of different dimensions. I am using Keras 3.4.0 and I am getting the error message: TypeError: generator yielded an element of shape (1, 3, 3, 7) where an element of shape (None, 4, 4, 7) was expected.

You can try the following and you will obtain the difference error between the dimensions of the tensors for independent batches.

def __getitem__(self, index):

        height_X = np.random.randint(3, 6)
        width_X = np.random.randint(3, 6)   
        X = np.random.rand(1, height_X, width_X, 7)
        Y = np.array([0])

        return X, Y

Thanks for help!

mohammad0081 commented 3 weeks ago

Hello there because of the randomness you are adding to your code , the "generator" you are calling is simply returning this error, it expects a fixed input shape but you are giving it a random shape every time you call the getitem() method .

look at this example that i tested for you :

import numpy as np

def get_item(index):
    height_X = np.random.randint(3, 6)
    width_X = np.random.randint(3, 6)   
    X = np.random.rand(1, height_X, width_X, 7)
    Y = np.array([0])

    return X, Y

X, Y = get_item(0)
print(X.shape, Y.shape)
X, Y = get_item(1)
print(X.shape, Y.shape)
X, Y = get_item(2)
print(X.shape, Y.shape)

outputs are :

(1, 5, 5, 7) (1,)
(1, 3, 4, 7) (1,)
(1, 4, 5, 7) (1,)
hansschaa commented 2 weeks ago

Hello there because of the randomness you are adding to your code , the "generator" you are calling is simply returning this error, it expects a fixed input shape but you are giving it a random shape every time you call the getitem() method .

look at this example that i tested for you :

import numpy as np

def get_item(index):
    height_X = np.random.randint(3, 6)
    width_X = np.random.randint(3, 6)   
    X = np.random.rand(1, height_X, width_X, 7)
    Y = np.array([0])

    return X, Y

X, Y = get_item(0)
print(X.shape, Y.shape)
X, Y = get_item(1)
print(X.shape, Y.shape)
X, Y = get_item(2)
print(X.shape, Y.shape)

outputs are :

(1, 5, 5, 7) (1,)
(1, 3, 4, 7) (1,)
(1, 4, 5, 7) (1,)

Hi, thanks for your response.

It happens that I need to give my network tensors of different dimensions. I have set the batch to 1 so that it accepts tensors of different dimensions in each call to getItem. Still it doesn't work.

divyashreepathihalli commented 1 week ago

@hansschaa this is a fundamental constraint in how deep learning models expect input data. The batch size can vary but the input tensor shape will have to be fixed.

hertschuh commented 1 week ago

@hansschaa you can have a generator which yields tensors with different dimension values. There is however one constraint, which is that the first two batches returned must have different values for all the dimensions in question. That is how Keras detects the dynamic dimensions.

You can look at this test for an example: https://github.com/keras-team/keras/blob/master/keras/src/trainers/data_adapters/generator_data_adapter_test.py#L105

More context in https://github.com/keras-team/keras/issues/19748

google-ml-butler[bot] commented 6 days ago

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