Error on custom dataset dimensions feeding transfer model in TensorFLow

Issue

Can someone explain this TensorFlow error for me, I’m having trouble understanding what I am doing wrong.

I have a dataset in Tensorflow constructed with a generator. When I test the output of the generator, output dimensions look correct (224 x 224 x 1). But when I try to train the model, I get an error:

WARNING:tensorflow:Model was constructed with shape (None, 224, 224, 1) for input   
KerasTensor(type_spec=TensorSpec(shape=(None, 224, 224, 1), dtype=tf.float32,   
name='input_2'), name='input_2', description="created by layer 'input_2'"),   
but it was called on an input with incompatible shape (224, 224, 1, 1).

I’m unsure why the dimension of this output has an extra 1 at the end.

Here is the code to create the generator and model. df is a dataframe with file-paths to data and labels. The data are 2D matrices of variable dimensions. I’m using cv2.resize to make them 224×224 and then np.reshape to transform dimensions to (224x224x1). Then I yield the result.

def datagen_row():
   # ======================== #
   # Import data
   # ======================== #
   df = get_data()
   rowsize = 224
   colsize = 224 
   # ======================== #
   # 
   # ======================== #
   for row in range(len(df)):
      data = get_data_from_filepath(df.iloc[row].file_path)      
      data = cv2.resize(data, dsize=(rowsize, colsize), interpolation=cv2.INTER_CUBIC)
      labels = df.iloc[row].label
      data = data.reshape( 224, 224, 1)
      yield data, labels

dataset = tf.data.Dataset.from_generator(
   datagen_row,
   output_signature=(
      tf.TensorSpec(shape = (int(os.getenv('rowsize')), int(os.getenv('colsize')), 1), dtype=tf.float32, name=None),
      tf.TensorSpec(shape=(), dtype=tf.int64, name=None)
   )
)

Testing the following I get what I expected:

iterator = iter(dataset.batch(8))
x = iterator.get_next()
x[0].shape # TensorShape([8, 224, 224, 1])
x[1].shape # TensorShape([8])

x[0] # <tf.Tensor: shape=(8, 224, 224, 1), dtype=float32, numpy=array(... 
x[1] # <tf.Tensor: shape=(8,), dtype=int64, numpy=array([1, 1, 1, 1, 1, 1, 1, 1], dtype=int64)>

I’m trying to plug this into InceptionV3 model to do a classification

from tensorflow.keras.applications.inception_v3 import InceptionV3
from tensorflow.keras.layers import Input
from tensorflow.keras import layers

origModel = InceptionV3(weights = 'imagenet', include_top = False) 
inputs = layers.Input(shape = (224, 224, 1))
modified_inputs = layers.Conv2D(3, 3, padding = 'same', activation='relu')(inputs) 
x = origModel(modified_inputs)
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dense(1024, activation = 'relu')(x)
x = layers.Dense(512, activation = 'relu')(x)
x = layers.Dense(256, activation = 'relu')(x)
x = layers.Dense(128, activation = 'relu')(x)
x = layers.Dense(64, activation = 'relu')(x)
x = layers.Dense(32, activation = 'relu')(x)
outputs = layers.Dense(2)(x)
model = tf.keras.Model(inputs, outputs)
model.summary() # 24.6 M trainable params


for layer in origModel.layers:
   layer.trainable = False

model.summary() # now shows 2.8 M trainable params

model.compile(
   optimizer = 'adam', 
   loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits = True),
   metrics = ['accuracy'] 
)

model.fit(dataset, epochs = 1, verbose = True, batch_size = 32)

Here is the output of model.summary

model.summary()
Model: "model"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input_2 (InputLayer)        [(None, 224, 224, 1)]     0         
                                                                 
 conv2d_94 (Conv2D)          (None, 224, 224, 3)       30        
                                                                 
 inception_v3 (Functional)   (None, None, None, 2048)  21802784  
                                                                 
 global_average_pooling2d (G  (None, 2048)             0         
 lobalAveragePooling2D)                                          
                                                                 
 dense (Dense)               (None, 1024)              2098176   
                                                                 
 dense_1 (Dense)             (None, 512)               524800    
                                                                 
 dense_2 (Dense)             (None, 256)               131328    
                                                                 
 dense_3 (Dense)             (None, 128)               32896     
                                                                 
 dense_4 (Dense)             (None, 64)                8256      
                                                                 
 dense_5 (Dense)             (None, 32)                2080      
                                                                 
 dense_6 (Dense)             (None, 2)                 66        
                                                                 
=================================================================
Total params: 24,600,416
Trainable params: 2,797,632
Non-trainable params: 21,802,784
_________________________________________________________________

Solution

This code worked after changing

model.fit(dataset, epochs = 1, verbose = True, batch_size = 32)

to

model.fit(dataset.batch(2), epochs = 1, verbose = True, batch_size = 32)

So… I will have to look into using dataset.batch versus batch_size in model.fit

Answered By – Frank

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published