I have trained an image classifier using Tensorflow, but while loading its weights afterwards, I get an error

36 views Asked by At

I have tried it with multiple frameworks be it VGG, Resnet, ConvNext. But i'm getting the same error.

While training the model, there are no problems. It even evaluates the model flawlessly. But if I try to load the model afterwards I keep on getting the following error

Traceback (most recent call last):
  File "G:\classifier\test.py", line 19, in <module>
    model = load_model("best_model_ResNet50.keras", compile=False)
  File "G:\tensor\lib\site-packages\keras\src\saving\saving_api.py", line 176, in load_model
    return saving_lib.load_model(
  File "G:\tensor\lib\site-packages\keras\src\saving\saving_lib.py", line 155, in load_model
    model = deserialize_keras_object(
  File "G:\tensor\lib\site-packages\keras\src\saving\serialization_lib.py", line 711, in deserialize_keras_object
    instance = cls.from_config(inner_config)
  File "G:\tensor\lib\site-packages\keras\src\models\sequential.py", line 335, in from_config
    model.add(layer)
  File "G:\tensor\lib\site-packages\keras\src\models\sequential.py", line 116, in add
    self._maybe_rebuild()
  File "G:\tensor\lib\site-packages\keras\src\models\sequential.py", line 135, in _maybe_rebuild
    self.build(input_shape)
  File "G:\tensor\lib\site-packages\keras\src\layers\layer.py", line 223, in build_wrapper
    original_build_method(*args, **kwargs)
  File "G:\tensor\lib\site-packages\keras\src\models\sequential.py", line 176, in build
    x = layer(x)
  File "G:\tensor\lib\site-packages\keras\src\utils\traceback_utils.py", line 122, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "G:\tensor\lib\site-packages\keras\src\layers\reshaping\flatten.py", line 72, in compute_output_spec
    output_shape = self.compute_output_shape(inputs.shape)
AttributeError: Exception encountered when calling Flatten.call().

←[1m'list' object has no attribute 'shape'←[0m

Arguments received by Flatten.call():
  • args=(['<KerasTensor shape=(None, 1, 1, 1536), dtype=float32, sparse=False, name=keras_tensor_637>'],)
  • kwargs=<class 'inspect._empty'>

The following is the script I used for training the model.

import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras.applications import ResNet50
from tensorflow.keras import layers, models, optimizers
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping, CSVLogger, ReduceLROnPlateau, TensorBoard
from sklearn.metrics import classification_report, confusion_matrix



# Load your dataset
train_dir = r'F:\new\classifier\train'
validation_dir = r'F:\new\classifier\val'
test_dir = r'F:\new\classifier\test'

# Setting some variables
INPUT_SIZE = (50, 50) 
FREEZE_EPOCHS = 30
UNFREEZE_EPOCHS = 100

# Data Augmentation
train_datagen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=20,
    width_shift_range=0.2,
    height_shift_range=0.2,
    brightness_range=[0.5, 1.5],
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=False,
    fill_mode='nearest')

test_datagen = ImageDataGenerator(rescale=1./255)  # Only rescaling for validation and test sets

train_generator = train_datagen.flow_from_directory(
    train_dir,
    target_size=INPUT_SIZE,  
    batch_size=20,
    class_mode='categorical')

validation_generator = test_datagen.flow_from_directory(
    validation_dir,
    target_size=INPUT_SIZE,
    batch_size=20,
    class_mode='categorical')

# Model architecture
def build_model(input_shape, num_classes):
    base_model = ResNet50(weights='imagenet', include_top=False, input_shape=input_shape)
    base_model.trainable = False  # Freeze the convolutional base
    
    model = models.Sequential([
        base_model,
        layers.Flatten(),
        layers.Dense(256, activation='relu'),
        layers.Dropout(0.5),
        layers.Dense(num_classes, activation='softmax')
    ])
 
    # Learning rate scheduling
    lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(
        initial_learning_rate=1e-4,
        decay_steps=100000,
        decay_rate=0.96,
        staircase=True)

# Model compilation

    model.compile(optimizer=optimizers.Adam(learning_rate=lr_schedule),
                  loss='categorical_crossentropy',
                  metrics=['accuracy'])
    return model

model = build_model((*INPUT_SIZE, 3), 34)  # Adjust the target size and number of classes

# Model Checkpoint to save the best model
checkpoint_cb = ModelCheckpoint("best_model_ResNet50.keras", save_best_only=True)

# Learning Rate Scheduling
reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=5, min_lr=0.001)

# Initial Training before unfreezing the base model
history = model.fit(
    train_generator,
    steps_per_epoch=100, 
    epochs=FREEZE_EPOCHS,
    validation_data=validation_generator,
    validation_steps=50,  
    callbacks=[checkpoint_cb, csv_logger, reduce_lr])

# Unfreeze the base model for fine-tuning
model.layers[0].trainable = True  # Unfreeze the VGG16 base model

# Recompile the model to apply the change
model.compile(optimizer=optimizers.Adam(learning_rate=1e-5),  # Use a smaller learning rate
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# Fine-tuning Training
history_fine = model.fit(
    train_generator,
    steps_per_epoch=100,  
    epochs=UNFREEZE_EPOCHS,  
    validation_data=validation_generator,
    validation_steps=50,  
    callbacks=[checkpoint_cb, csv_logger, reduce_lr])

# Evaluating the Model on the Test Set
test_generator = test_datagen.flow_from_directory(
    test_dir,
    target_size= INPUT_SIZE,
    batch_size=20,
    class_mode='categorical',
    shuffle=False)


# Print the model structure
model.summary()

test_loss, test_acc = model.evaluate(test_generator, steps=50)  # Adjust steps accordingly
print(f"Test Accuracy: {test_acc*100:.2f}%")

# Confusion Matrix and Classification Report
Y_pred = model.predict(test_generator, test_generator.samples // test_generator.batch_size+1)
y_pred = np.argmax(Y_pred, axis=1)


# Get the true class labels
true_classes = test_generator.classes

# Get the class labels for each index from the generator
class_labels = list(test_generator.class_indices.keys())  

confusion_mtx = confusion_matrix(true_classes, y_pred)
print('Confusion Matrix')
print(confusion_mtx)

The script I used to load the model afterwards.

import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras.applications import ResNet50
from tensorflow.keras import layers, models, optimizers
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping, CSVLogger, ReduceLROnPlateau, TensorBoard
from sklearn.metrics import classification_report, confusion_matrix
import itertools
from tensorflow.keras.models import load_model

# Load your dataset
test_dir = r'F:\new\classifier\test'

INPUT_SIZE = (50, 50) 

test_datagen = ImageDataGenerator(rescale=1./255)  # Only rescaling for validation and test sets

model = load_model("best_model_ResNet50.keras", compile=False)

# Evaluating the Model on the Test Set
test_generator = test_datagen.flow_from_directory(
    test_dir,
    target_size= INPUT_SIZE,
    batch_size=20,
    class_mode='categorical',
    shuffle=False)


# Print the model structure
model.summary()

test_loss, test_acc = model.evaluate(test_generator, steps=50)  # Adjust steps accordingly
print(f"Test Accuracy: {test_acc*100:.2f}%")

# Confusion Matrix and Classification Report
Y_pred = model.predict(test_generator, test_generator.samples // test_generator.batch_size+1)
y_pred = np.argmax(Y_pred, axis=1)

# Get the true class labels
true_classes = test_generator.classes

# Get the class labels for each index from the generator
class_labels = list(test_generator.class_indices.keys())  

confusion_mtx = confusion_matrix(true_classes, y_pred)
print('Confusion Matrix')
print(confusion_mtx)

# Classification report
classification_rep = classification_report(true_classes, y_pred, target_names=class_labels)
print('Classification Report')
print(classification_rep)

0

There are 0 answers