0% found this document useful (0 votes)
8 views

a-1

The document outlines a comprehensive approach to building a deep learning model for emotion detection using image data. It includes data preprocessing, model architecture using VGG16 and ResNet50V2, training with callbacks for monitoring performance, and evaluation through confusion matrices and classification reports. The code also handles image loading, augmentation, and class weight computation to address class imbalances.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

a-1

The document outlines a comprehensive approach to building a deep learning model for emotion detection using image data. It includes data preprocessing, model architecture using VGG16 and ResNet50V2, training with callbacks for monitoring performance, and evaluation through confusion matrices and classification reports. The code also handles image loading, augmentation, and class weight computation to address class imbalances.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 9

import os

import random
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import cv2
import imghdr
import tensorflow as tf
from PIL import Image
import seaborn as sns

from sklearn.metrics import confusion_matrix, classification_report, roc_curve, auc


from sklearn.utils.class_weight import compute_class_weight

from tensorflow.keras import layers, models, regularizers, optimizers


from tensorflow.keras.applications import VGG16, ResNet50V2
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping,
ReduceLROnPlateau, TensorBoard, CSVLogger
from tensorflow.keras.layers import Conv2D, MaxPooling2D, BatchNormalization,
Dropout, Flatten, Dense, Activation, GlobalAveragePooling2D
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.optimizers import Adam, Adamax
from tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img,
img_to_array
from keras.utils import plot_model

# Define the list of acceptable image extensions


image_exts = ['jpeg', 'jpg', 'png']

# Path to the directory containing image classes and possibly other nested
subdirectories
data_dir = 'archive\train'

# Walk through all directories and files in the dataset


for root, dirs, files in os.walk(data_dir):
for file in files:
# Construct the path to the current file
file_path = os.path.join(root, file)

try:
# Check the file type of the current file
file_type = imghdr.what(file_path)

# If the file extension is not in the allowed list, remove it


if file_type not in image_exts:
print(f'Image not in ext list {file_path}')
os.remove(file_path)
else:
# Proceed to process the image if needed, for example, reading it
with OpenCV
img = cv2.imread(file_path)

except Exception as e:
# Print out the issue and the path of the problematic file
print(f'Issue with file {file_path}. Error: {e}')
# Optionally, remove files that cause exceptions
os.remove(file_path)

def count_files_in_subdirs(directory, set_name):


counts = {}
for item in os.listdir(directory):

item_path = os.path.join(directory, item)

if os.path.isdir(item_path):
counts[item] = len(os.listdir(item_path))

df = pd.DataFrame(counts, index=[set_name])
return df

train_dir = 'archive/train'
test_dir = 'archive/test'

train_count = count_files_in_subdirs(train_dir, 'train')


print(train_count)
print("-" * 60)
test_count = count_files_in_subdirs(test_dir, 'test')
print(test_count)

train_count.transpose()
train_count.transpose().plot(kind='bar')
test_count.transpose().plot(kind='bar')
emotions = os.listdir(train_dir)
plt.figure(figsize=(15,10))

for i, emotion in enumerate(emotions, 1):#i m index emotion m subfolder


folder = os.path.join(train_dir, emotion)
img_path = os.path.join(folder, os.listdir(folder)[42])#42 image sbki
img = plt.imread(img_path)
plt.subplot(3, 4, i)
plt.imshow(img, cmap='gray')
plt.title(emotion)
plt.axis('off')
def plot_images_from_directory(directory_path, class_name, num_images=9):
# Retrieve list of all file names in the directory
image_filenames = os.listdir(directory_path)

# If there are fewer images than requested, we'll just show them all
if len(image_filenames) < num_images:
print(f"Only found {len(image_filenames)} images in {directory_path},
displaying them all.")
num_images = len(image_filenames)

# Randomly select 'num_images' number of file names


selected_images = random.sample(image_filenames, num_images)# select names of 9
images from list image_filenames

# Plotting the images


fig, axes = plt.subplots(3, 3, figsize=(6, 6)) # Adjust the size as needed
axes = axes.ravel()

for i, image_file in enumerate(selected_images):


image_path = os.path.join(directory_path, image_file)
# image = Image.open(image_path)
image = load_img(image_path)
axes[i].imshow(image)
axes[i].set_title(f"Image: {class_name}")
axes[i].axis('off') # Hide the axis

plt.tight_layout()
plt.show()
# Placeholder for the directory path
angry_directory_path = 'archive/train/angry' # Replace with your directory path
plot_images_from_directory(angry_directory_path, class_name = 'Angry')
image = 'archive/train/angry/Training_10118481.jpg'

import cv2

img = cv2.imread(image) # Default load in color format.

# If the image is loaded successfully, print its pixel values


if img is not None:
# print(img)
print("Shape:", img.shape)
else:
print("The image could not be loaded. Please check the path and file
permissions.")
import cv2

image_path = 'archive/train/angry/Training_10118481.jpg'

# Load the image in grayscale


img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)

# If the image is loaded successfully, print its pixel values


if img is not None:
# print(img)
print("Shape:", img.shape) # This should now print (48, 48)
else:
print("The image could not be loaded. Please check the path and file
permissions.")
# Define paths to the train and validation directories
train_data_dir = 'archive/train'
test_data_dir = 'archive/test'

img_width, img_height = 224, 224 # Size of images


batch_size = 26
epochs = 10
num_classes = 7
data_generator = ImageDataGenerator(
rescale = 1 / 255.,
rotation_range=10,
zoom_range=0.2,
width_shift_range=0.1,
height_shift_range=0.1,
horizontal_flip=True,
fill_mode='nearest',
)

test_preprocessor = ImageDataGenerator(
rescale = 1 / 255.,
)

# Automatically retrieve images and their classes for train and validation sets
train_generator = data_generator.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical',
color_mode='rgb',
subset='training',
shuffle = True)

test_generator = test_preprocessor.flow_from_directory(
test_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical',
color_mode='rgb',)
# subset='validation')
# Accessing class labels for the training data
train_class_labels = train_generator.class_indices
print("Training class labels:", train_class_labels)

# Accessing class labels for the validation data


validation_class_labels = validation_generator.class_indices
print("Validation class labels:", validation_class_labels)

# Accessing class labels for the validation data


test_class_labels = test_generator.class_indices
print("Validation class labels:", test_class_labels)
# Extract class labels for all instances in the training dataset
classes = np.array(train_generator.classes)

# Calculate class weights to handle imbalances in the training data


# 'balanced' mode automatically adjusts weights inversely proportional to class
frequencies
class_weights = compute_class_weight(
class_weight='balanced', # Strategy to balance classes
classes=np.unique(classes), # Unique class labels
y=classes # Class labels for each instance in the training dataset
)

# Create a dictionary mapping class indices to their calculated weights


class_weights_dict = dict(enumerate(class_weights))

# Output the class weights dictionary


print("Class Weights Dictionary:", class_weights_dict)
classes = 7

# Clear the previous TensorFlow sessionx


tf.keras.backend.clear_session()

# Load the VGG16 base model, excluding its top (fully connected) layers
vgg = VGG16(input_shape=(224, 224, 3), include_top=False, weights='imagenet')
vgg.summary()
# Make the specified layers non-trainable
for layer in vgg.layers[:-3]:
layer.trainable = False

vgg.summary()
classes
# Flattening the layer and adding custom Dense layers
x = Flatten()(vgg.output)
# Adding a fully connected layer with ReLU activation and He normal initializer
x = Dense(1024, activation='relu', kernel_initializer='he_normal')(x)
x = Dropout(0.5)(x) # Adding dropout for regularization

x = Dense(512, activation='relu', kernel_initializer='he_normal')(x)


x = Dropout(0.5)(x) # Adding dropout for regularization

# Adding the output layer with softmax activation


# Note: Adjust the number of units to match the number of classes you have
output = Dense(7, activation='softmax', kernel_initializer='he_normal')(x)

# Creating the model


model = Model(inputs=vgg.input, outputs=output)

# Compile the model


model.compile(loss='categorical_crossentropy',
optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001, beta_1=0.9,
beta_2=0.999, amsgrad=False),
metrics=['accuracy'])

# Model summary to see all layers


model.summary()

# File path for the model checkpoint


cnn_path = 'Emotion_Detection/VGG16_Transfer_Learning'
name = 'VGG16_Transfer_Learning.keras'
chk_path = os.path.join(cnn_path, name)

# Callback to save the model checkpoint


checkpoint = ModelCheckpoint(filepath=chk_path,
save_best_only=True,
verbose=1,
mode='min',
monitor='val_loss')
# the ModelCheckpoint callback is an automated and dynamic alternative to using
model.save.
#While model.save allows you to save your model manually at specific
#points in your training script, ModelCheckpoint handles this process automatically
based on the performance of your model.

# Callback for early stopping


earlystop = EarlyStopping(monitor='val_loss',
min_delta=0,
patience=3,
verbose=1,
restore_best_weights=True)

# Callback to reduce learning rate


reduce_lr = ReduceLROnPlateau(monitor='val_loss',
factor=0.2,
patience=6,
verbose=1,
min_delta=0.0001)

# Callback to log training data to a CSV file


csv_logger = CSVLogger(os.path.join(cnn_path,'training.log'))

# Aggregating all callbacks into a list


callbacks = [checkpoint, earlystop, reduce_lr, csv_logger] # Adjusted as per your
use-case

train_steps_per_epoch = train_generator.samples // train_generator.batch_size + 1


# validation_steps_epoch = validation_generator.samples //
validation_generator.batch_size + 1
test_steps_epoch = test_generator.samples // test_generator.batch_size + 1
history = model.fit(
train_generator,
steps_per_epoch=train_steps_per_epoch,
epochs=50,
validation_data=test_generator,
validation_steps=test_steps_epoch,
class_weight=class_weights_dict,
callbacks = callbacks
)
plot_training_history(history)
# Assuming your true_classes and predicted_classes are already defined
true_classes = test_generator.classes
predicted_classes = np.argmax(model.predict(test_generator,
steps=np.ceil(test_generator.samples/test_generator.batch_size)), axis=1)
class_labels = list(test_generator.class_indices.keys())

# Generate the confusion matrix


cm = confusion_matrix(true_classes, predicted_classes)

# Plotting with seaborn


plt.figure(figsize=(10, 8))
sns.heatmap(cm, annot=True, fmt="d", cmap="Blues", xticklabels=class_labels,
yticklabels=class_labels)
plt.title('Confusion Matrix')
plt.ylabel('True label')
plt.xlabel('Predicted label')
plt.show()
# Printing the classification report
report = classification_report(true_classes,
predicted_classes,
target_names=class_labels,
zero_division=0)
print("Classification Report:\n", report)

model.save('model_vgg1.keras', save_format='keras')

model = tf.keras.models.load_model('model_vgg1.keras')

# Define paths to the train and validation directories


train_data_dir = 'archive/train'
test_data_dir = 'archive/test'

img_width, img_height = 224, 224 # Size of images


batch_size = 26
epochs = 10
num_classes = 7
data_generator = ImageDataGenerator(
rescale = 1 / 255.,
rotation_range=10,
zoom_range=0.2,
width_shift_range=0.1,
height_shift_range=0.1,
horizontal_flip=True,
fill_mode='nearest',
)

test_preprocessor = ImageDataGenerator(
rescale = 1 / 255.,
)

# Automatically retrieve images and their classes for train and validation sets
train_generator = data_generator.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical',
color_mode='rgb',
subset='training',
shuffle = True)

test_generator = test_preprocessor.flow_from_directory(
test_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical',
color_mode='rgb',)
# subset='validation')
# Extract class labels for all instances in the training dataset
classes = np.array(train_generator.classes)

# Calculate class weights to handle imbalances in the training data


# 'balanced' mode automatically adjusts weights inversely proportional to class
frequencies
class_weights = compute_class_weight(
class_weight='balanced', # Strategy to balance classes
classes=np.unique(classes), # Unique class labels
y=classes # Class labels for each instance in the training dataset
)

# Create a dictionary mapping class indices to their calculated weights


class_weights_dict = dict(enumerate(class_weights))

# Output the class weights dictionary


print("Class Weights Dictionary:", class_weights_dict)
ResNet50V2 = tf.keras.applications.ResNet50V2(input_shape=(224, 224, 3),
include_top= False,
weights='imagenet'
)
# Freezing all layers except last 50

ResNet50V2.trainable = True

for layer in ResNet50V2.layers[:-50]:


layer.trainable = False
def Create_ResNet50V2_Model():

model = Sequential([
ResNet50V2,
Dropout(0.25),
BatchNormalization(),
Flatten(),
Dense(64, activation='relu'),
BatchNormalization(),
Dropout(0.5),
Dense(7,activation='softmax')
])
return model
model = Create_ResNet50V2_Model()
model.summary()
model.compile(optimizer='adam', loss='categorical_crossentropy',
metrics=['accuracy'])
# File path for the model checkpoint
cnn_path = 'Emotion_Detection/ResNet50_Transfer_Learning'
name = 'ResNet50_Transfer_Learning.keras'
chk_path = os.path.join(cnn_path, name)

# Callback to save the model checkpoint


checkpoint = ModelCheckpoint(filepath=chk_path,
save_best_only=True,
verbose=1,
mode='min',
monitor='val_loss')

# Callback for early stopping


earlystop = EarlyStopping(monitor = 'val_accuracy',
patience = 7,
restore_best_weights = True,
verbose=1)

# Callback to reduce learning rate


reduce_lr = ReduceLROnPlateau(monitor='val_loss',
factor=0.2,
patience=2,
# min_lr=0.00005,
verbose=1)

# Callback to log training data to a CSV file


csv_logger = CSVLogger(os.path.join(cnn_path,'training.log'))

# Aggregating all callbacks into a list


callbacks = [checkpoint, earlystop, csv_logger] # Adjusted as per your use-case

train_steps_per_epoch = train_generator.samples // train_generator.batch_size + 1


# validation_steps_epoch = validation_generator.samples //
validation_generator.batch_size + 1
test_steps_epoch = test_generator.samples // test_generator.batch_size + 1
train_history = model.fit(
train_generator,
steps_per_epoch=train_steps_per_epoch,
epochs=30,
validation_data=test_generator,
validation_steps=test_steps_epoch,
class_weight=class_weights_dict,
callbacks = callbacks
)
model.save('ResNet50_Transfer_Learning.keras', save_format='keras')

model = tf.keras.models.load_model('ResNet50_Transfer_Learning.keras')

true_classes = test_generator.classes
predicted_classes = np.argmax(model.predict(test_generator,
steps=np.ceil(test_generator.samples/test_generator.batch_size)), axis=1)
class_labels = list(test_generator.class_indices.keys())

# Generate the confusion matrix


cm = confusion_matrix(true_classes, predicted_classes)

# Plotting with seaborn


plt.figure(figsize=(10, 8))
sns.heatmap(cm, annot=True, fmt="d", cmap="Blues", xticklabels=class_labels,
yticklabels=class_labels)
plt.title('Confusion Matrix')
plt.ylabel('True label')
plt.xlabel('Predicted label')
plt.show()

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy