predict function when used on a Dataset_iterator is returning labels of a single type CNN Tensorflow

19 Views Asked by At

I've trained a Convolutional Neural Network (CNN) for a facial emotion recognition task using TensorFlow and Keras. The training process appears to go smoothly, and the model shows reasonable performance on the validation set. However, when I use the trained model to make predictions on a test dataset, all the predictions turn out to be the same class, which is class 7.

I've considered several potential causes for this issue, including data imbalance, model complexity, overfitting, incorrect labeling, and data preprocessing. Despite experimenting with different architectures, hyperparameter tuning, and preprocessing steps, the problem persists.

import tensorflow as tf
import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from math import ceil

# Constants
DATASET_PATH = "/kaggle/input/facial-emotion-recognition/images"
TEST_PATH = "/kaggle/input/genral-test"
IMAGE_SIZE = (256, 256)
BATCH_SIZE = 16

# Function to extract images and labels
def extract(dataset_path):
    X, y = [], []
    for batch in sorted(os.listdir(DATASET_PATH), key=lambda x: int(x)):
        batch_path = os.path.join(dataset_path, batch)
        for idx, img_filename in enumerate(sorted(os.listdir(batch_path))):
            img_path = os.path.join(batch_path, img_filename)
            img = cv2.imread(img_path)

            if img is not None:
                img = img / 255.0
                img = cv2.resize(img, IMAGE_SIZE)
                X.append(img)
                y.append(idx)

    X = np.array(X)
    y = np.array(y)
    return X, y

# Extract images and labels
X, y = extract(DATASET_PATH)

# Split dataset into train and validation sets
x_train, x_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42, shuffle=False)

# Function to create and train a simple CNN
def train_cnn(x_train, y_train, x_val, y_val):
    cnn = tf.keras.Sequential([
        tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(256, 256, 3)),
        tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
        tf.keras.layers.BatchNormalization(),
        tf.keras.layers.MaxPooling2D((2, 2)),
        tf.keras.layers.Dropout(0.25),
        tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),
        tf.keras.layers.MaxPooling2D((2, 2)),
        tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),
        tf.keras.layers.BatchNormalization(),
        tf.keras.layers.MaxPooling2D((2, 2)),
        tf.keras.layers.Dropout(0.25),
        tf.keras.layers.Flatten(),
        tf.keras.layers.Dense(516, activation='relu'),
        tf.keras.layers.BatchNormalization(),
        tf.keras.layers.Dropout(0.5),
        tf.keras.layers.Dense(8, activation="softmax"),
    ])

    cnn.compile(
        optimizer="adam",
        loss="sparse_categorical_crossentropy",
        metrics=["sparse_categorical_accuracy"]
    )

    cnn.summary()

    # Train the model
    cnn.fit(x_train, y_train, validation_data=(x_val, y_val), epochs=5)
    return cnn

# Train the CNN
trained_cnn = train_cnn(x_train, y_train, x_val, y_val)

# Predictions on a sample test dataset
test_datagen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=0.1/255.0)
test_generator = test_datagen.flow_from_directory(
    directory="/kaggle/input/genral-test",
    target_size=IMAGE_SIZE,
    batch_size=BATCH_SIZE,
    shuffle=False,
    class_mode=None
)

# Get predictions
probabilities = trained_cnn.predict(test_generator)
predictions = np.argmax(probabilities, axis=1)

# Print predictions
print(predictions)

I think the problem is related to the testgenerator for I tried my model initially on individual images and it works perfectly fine.I tired several thing googled it but was unable to find proper answer , the classes of the test set are completely random ,not of the same type.please check the way i initialized the generator
"test
_generator".

img = cv2.imread("/kaggle/input/genral-test/images/Crying-Girl.jpg")
resized_img = tf.image.resize(img,(256,256))
prepro_img = np.expand_dims(resized_img,axis=0)/255
prediction = np.argmax(cnn.predict(prepro_img))
print(predicion)
0

There are 0 best solutions below