Home > Software design >  Model cannot fit on Tensorflow data pipline with unknown TensorShape
Model cannot fit on Tensorflow data pipline with unknown TensorShape

Time:04-29

I have a data loader pipeline for video data. Although I specify the output of the pipeline, I still get the following error when calling model.fit. "ValueError: as_list() is not defined on an unknown TensorShape". I searched for the error and most people say it is because of the tf.numpy_function that returns an (to the Tensorflow pipeline) unknown shape. Specifying the shape after that function should solve the problem. However, it does not.

AUTOTUNE = tf.data.experimental.AUTOTUNE

#get list of numpy files in directory
train_ds = tf.data.Dataset.list_files("dir") 

#load numpy files (video with shape 40,160,160,3), get corresponding label and output both
#video and label
def get_label(file_path):
    label = tf.strings.split(file_path, os.path.sep)
    return label [-2]

def process_image(file_path):
    label = get_label(file_path)
    video= np.load(file_path, allow_pickle=True)
    video= tf.convert_to_tensor(video/255, dtype=tf.float32) 
    return video, np.float32(label)

train_ds = train_ds.map(lambda item: tf.numpy_function(
          process_image, [item], (tf.float32, tf.float32)),num_parallel_calls = AUTOTUNE ) 

#Convert video to tf object
def set_shape(video, label):
  video = tf.reshape(video, (40,160,160,3))
  #video = tf.ensure_shape(video, (40,160,160,3)) #also does not work
  #video = tf.convert_to_tensor(video, dtype=tf.float32) #also does not work
  return video, label

train_ds = train_ds.map(set_shape)

#batching
train_ds = train_ds.batch(batch_size =5)

#optimazation
train_ds = train_ds.prefetch(AUTOTUNE)


train_ds.take(1) 

Although the rest of the code seems fine (it does work when I manually input data), I will paste it in case it is not.


def create_LRCN_model():
    '''
    This function will construct the required LRCN model.
    Returns:
        model: It is the required constructed LRCN model.
    '''
 
    # We will use a Sequential model for model construction.
    model = Sequential()
    
    # Define the Model Architecture.

    ########################################################################################
    
    model.add(TimeDistributed(Conv2D(128, (3, 3), padding='same',activation = 'relu'),
                              input_shape = (40, 160, 160, 3)))
    
    model.add(TimeDistributed(MaxPooling2D((4, 4)))) 
    model.add(TimeDistributed(Dropout(0.25)))
    
    model.add(TimeDistributed(Conv2D(256, (3, 3), padding='same',activation = 'relu')))
    model.add(TimeDistributed(MaxPooling2D((4, 4))))
    model.add(TimeDistributed(Dropout(0.25)))
    
    model.add(TimeDistributed(Conv2D(128, (3, 3), padding='same',activation = 'relu')))
    model.add(TimeDistributed(MaxPooling2D((2, 2))))
    model.add(TimeDistributed(Dropout(0.25)))
    
    model.add(TimeDistributed(Conv2D(64, (3, 3), padding='same',activation = 'relu')))
    model.add(TimeDistributed(MaxPooling2D((2, 2))))
    #model.add(TimeDistributed(Dropout(0.25)))
                                      
    model.add(TimeDistributed(Flatten()))
                                      
    model.add(LSTM(32))
                                      
    model.add(Dense(1, activation = 'sigmoid'))
 
    ########################################################################################
    # Display the models summary.
    model.summary()
    
    # Return the constructed LRCN model.
    return model

LRCN_model = create_LRCN_model()
early_stopping_callback = EarlyStopping(monitor = 'val_loss', patience = 15, mode = 'min', restore_best_weights = True)
LRCN_model.compile(loss='binary_crossentropy', optimizer = 'Adam', metrics = ["accuracy"])
LRCN_model_training_history = LRCN_model.fit(train_ds, validation_data= val_ds, epochs = 70,   callbacks = [early_stopping_callback])


CodePudding user response:

Okay I found another solution. I do not exactly know why it works, just calling the following function does the job.


def set_shape(video, label):

  video.set_shape((40,160,160, 3))
  label.set_shape([])

  return video, label

CodePudding user response:

Got it! You just need to change "accuracy" to "binary_accuracy" in model compile. It worked for me with your code and some dummy video and label input data.

  • Related