Simone Di Claudio
Simone Di Claudio

Reputation: 131

TensorFlow batch tensors with different shapes

I am studying Neural Network and I have encountered what is probably a silly problem which I can't figure out. For my first ever network, I have to create a flower image classifier in Keras and TensorFlow using the oxford_flowers102 and the MobileNet pre-trained model from TensorFlow Hub.

The issue seems to be that the images are not re-sized to (224,224,3), but they keep their original shapes which are different from one and other. However, according to my class material, my re-sizing code is correct so I don't understand what is going on and what I am doing wrong.

Thank you very much for all your help.

# LOADING 
dataset, dataset_info = tfds.load('oxford_flowers102', as_supervised=True, with_info=True)
training_set, testing_set, validation_set = dataset['train'], dataset['test'],dataset['validation']

# PROCESSING AND BATCHES 
def normalize(img, lbl):
        img = tf.cast(img, tf.float32)
        img = tf.image.resize(img, size=(224,224))
        img /= 255
        return img, lbl
    
batch_size = 64
                                                
training_batches = training_set.cache().shuffle(train_examples//4).batch(batch_size).map(normalize).prefetch(1)

validation_batches = validation_set.cache().batch(batch_size).map(normalize).prefetch(1)

testing_batches = testing_set.cache().batch(batch_size).map(normalize).prefetch(1)

# BUILDING THE NETWORK
URL = "https://tfhub.dev/google/tf2-preview/mobilenet_v2/feature_vector/4"

mobile_net = hub.KerasLayer(URL, input_shape=(224, 224,3))
mobile_net.trainable = False

skynet = tf.keras.Sequential([
         mobile_net,
         tf.keras.layers.Dense(256, activation='relu'),
         tf.keras.layers.Dropout(0.5),
         tf.keras.layers.Dense(num_classes, activation= 'softmax')
    ])

# TRAINING THE NETWORK
skynet.compile(optimizer='adam', loss= 'sparse_categorical_crossentropy', metrics=['accuracy'])

early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=5)

Epochss = 25

history = skynet.fit(training_batches,
                     epochs= Epochss,
                     validation_data=validation_set,
                     callbacks=[early_stopping])



ERROR:
InvalidArgumentError:  Cannot batch tensors with different shapes in component 0. First element had shape [590,501,3] and element 1 had shape [500,752,3].
     [[node IteratorGetNext (defined at /opt/conda/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py:1751) ]] [Op:__inference_distributed_function_18246]

Function call stack:
distributed_function

Upvotes: 0

Views: 1058

Answers (1)

pratsbhatt
pratsbhatt

Reputation: 1538

The problem was that in your input pipeline you were batching your dataset before you were making your images of equal size. You're def normalize(img, lbl) is only made to handle a single image and not a complete batch.

So in order to make your code run, you will have to make the following changes, you will have to call the map API before batch API as shown below.

batch_size = 64

training_batches = training_set.cache().map(normalize).batch(batch_size).prefetch(1)

validation_batches = validation_set.cache().map(normalize).batch(batch_size).prefetch(1)

testing_batches = testing_set.cache().map(normalize).batch(batch_size).prefetch(1)

Upvotes: 1

Related Questions