این پروژه به منظور تشخیص احساسات از تصاویر چهرهها با استفاده از شبکههای عصبی کانولوشنی (CNN) طراحی شده است. در این پروژه از کتابخانههای TensorFlow و OpenCV استفاده شده تا یک مدل یادگیری عمیق برای طبقهبندی احساسات ایجاد کنیم. همچنین، از دادههای تصویری برای آموزش و ارزیابی مدل استفاده شده و نتایج به صورت گرافیکی نمایش داده شدهاند.
ابتدا کتابخانههای TensorFlow و OpenCV نصب میشوند:
!pip install tensorflow opencv-python-headless
دادهها شامل تصاویر چهرههای با برچسبهای احساسات مختلف هستند که در دو پوشه train و test قرار دارند. تصاویر به اندازه 48x48 تغییر اندازه داده شده و به صورت مقادیر بین 0 و 1 نرمالسازی میشوند.
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import os
# Paths to the extracted train and test directories
train_dataset_path = './newarchive/train'
test_dataset_path = './newarchive/test'
image_size = (48, 48)
batch_size = 32
# Data augmentation and rescaling
datagen = ImageDataGenerator(
rescale=1./255,
validation_split=0.2
)
# Load training data
train_generator = datagen.flow_from_directory(
train_dataset_path,
target_size=image_size,
batch_size=batch_size,
class_mode='categorical',
subset='training'
)
# Load validation data
validation_generator = datagen.flow_from_directory(
train_dataset_path,
target_size=image_size,
batch_size=batch_size,
class_mode='categorical',
subset='validation'
)
یک مدل شبکه عصبی کانولوشنی با سه لایه کانولوشنی و سه لایه MaxPooling، به همراه لایههای Dense و Dropout برای کاهش Overfitting تعریف شده است. سپس مدل با استفاده از دادههای آموزشی و دادههای اعتبارسنجی آموزش داده میشود.
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
# Define the model
model = Sequential([
Conv2D(32, (3, 3), activation='relu', input_shape=(image_size[0], image_size[1], 3)),
MaxPooling2D((2, 2)),
Conv2D(64, (3, 3), activation='relu'),
MaxPooling2D((2, 2)),
Conv2D(128, (3, 3), activation='relu'),
MaxPooling2D((2, 2)),
Flatten(),
Dense(128, activation='relu'),
Dropout(0.5),
Dense(len(train_generator.class_indices), activation='softmax')
])
# Compile the model
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# Train the model
model.fit(train_generator, validation_data=validation_generator, epochs=15)
# Save the model
model.save('emotion_model.h5')
مدل آموزش دیده بر روی دادههای تست ارزیابی میشود تا دقت و میزان خطا مشخص گردد.
from tensorflow.keras.models import load_model
# Load the trained model
model = load_model('emotion_model.h5')
# Data generator for test data
test_datagen = ImageDataGenerator(rescale=1./255)
# Load test data
test_generator = test_datagen.flow_from_directory(
test_dataset_path,
target_size=image_size,
batch_size=batch_size,
class_mode='categorical',
shuffle=False
)
# Evaluate the model
test_loss, test_accuracy = model.evaluate(test_generator)
print(f'Test Loss: {test_loss}')
print(f'Test Accuracy: {test_accuracy}')
برای پیشبینی احساسات از تصاویر، ابتدا تصویر ورودی پیشپردازش شده و سپس با استفاده از مدل، احساسات پیشبینی میشود. نتایج پیشبینی شده با برچسبهای واقعی مقایسه شده و ماتریس اشتباه و گزارش طبقهبندی نمایش داده میشود.
import numpy as np
import cv2
# Function to preprocess image for prediction
def preprocess_image(image):
image = cv2.resize(image, (48, 48))
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image = image.astype('float32') / 255
image = np.expand_dims(image, axis=0)
return image
# Predict emotion from image
def predict_emotion(image):
preprocessed_image = preprocess_image(image)
prediction = model.predict(preprocessed_image)
return class_labels[np.argmax(prediction)]
# Load class labels
class_labels = list(test_generator.class_indices.keys())
# Predict emotions for all images in the test set
def predict_test_set(test_generator):
predictions = model.predict(test_generator)
predicted_classes = np.argmax(predictions, axis=1)
true_classes = test_generator.classes
class_labels = list(test_generator.class_indices.keys())
return predicted_classes, true_classes, class_labels
# Get predictions
predicted_classes, true_classes, class_labels = predict_test_set(test_generator)
# Print some results
import pandas as pd
results_df = pd.DataFrame({
'Filename': test_generator.filenames,
'Predicted': [class_labels[i] for i in predicted_classes],
'True': [class_labels[i] for i in true_classes]
})
# Display some prediction results
print(results_df.head())
# Calculate and print confusion matrix
from sklearn.metrics import confusion_matrix, classification_report
import seaborn as sns
import matplotlib.pyplot as plt
conf_matrix = confusion_matrix(true_classes, predicted_classes)
plt.figure(figsize=(10, 7))
sns.heatmap(conf_matrix, annot=True, fmt="d", xticklabels=class_labels, yticklabels=class_labels)
plt.ylabel('Actual')
plt.xlabel('Predicted')
plt.show()
# Print classification report
print(classification_report(true_classes, predicted_classes, target_names=class_labels))
در این مرحله، ایموجیهای مرتبط با احساسات مختلف بر روی تصاویر پیشبینی شده قرار داده شده و نتایج نمایش داده میشود.
# Load emoji images
emoji_images = {}
for label in class_labels:
emoji_images[label] = cv2.imread(os.path.join("./emoji", f'{label}.png'), cv2.IMREAD_UNCHANGED)
def overlay_emoji(image, emoji, position=(0, 0), size=(48, 48)):
image = cv2.resize(image, (200,200))
(x, y) = position
emoji = cv2.resize(emoji, size, interpolation=cv2.INTER_AREA)
(h, w) = emoji.shape[0], emoji.shape[1]
alpha_s = emoji[:, :, 3] / 255.0
alpha_l = 1.0 - alpha_s
for c in range(0, 3):
image[y:y+h, x:x+w, c] = (alpha_s * emoji[:, :, c] + alpha_l * image[y:y+h, x:x+w, c])
return image
# Predict emotion from image and overlay emoji
def predict_and_overlay(image_path, model, class_labels, emoji_images):
image = cv2.imread(image_path)
preprocessed_image = preprocess_image(image)
prediction = model.predict(preprocessed_image)
predicted_label = class_labels[np.argmax(prediction)]
emoji = emoji_images[predicted_label]
result_image = overlay_emoji(image, emoji)
return result_image, predicted_label
test_images=['./newarchive/test/neutral/PrivateTest_26814656.jpg',
'./newarchive/test/angry/PrivateTest_1221822.jpg',
'./newarchive/test/happy/PrivateTest_218533.jpg',
'./newarchive/test/surprise/PrivateTest_642696.jpg',
'./newarchive/test/sad/PrivateTest_5060451.jpg',
]
for image_path in test_images:
emoji_image, predicted_label = predict_and_overlay(image_path, model, class_labels, emoji_images)
cv2.imshow(f'Predicted: {predicted_label}', emoji_image)
cv2.waitKey(0) # Press any key to move to the next image
cv2.destroyAllWindows()
در این پروژه، یک مدل شبکه عصبی کانولوشنی برای تشخیص احساسات از تصاویر چهرهها طراحی و پیادهسازی شد. مدل با دقت مناسبی توانست احساسات مختلف را تشخیص دهد. همچنین، نتایج به صورت گرافیکی و با استفاده از ایموجیها نمایش داده شدند که نشاندهنده کاربرد عملی این مدل در سیستمهای مختلف میباشد.