-
Notifications
You must be signed in to change notification settings - Fork 0
/
NunCavCNN.py
163 lines (130 loc) · 6.11 KB
/
NunCavCNN.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import os
import cv2
import numpy as np
from tensorflow import keras
from keras.preprocessing.image import ImageDataGenerator
from keras import layers, models
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, BatchNormalization
# Training and test data
train_dir = '/Users/eunanpro/Desktop/CNN/Data/nunez-cavani/train'
test_dir = '/Users/eunanpro/Desktop/CNN/Data/nunez-cavani/test'
# Initialize lists to store the training and testing data
train_data = []
train_labels = []
test_data = []
test_labels = []
# Resize of input images
target_size = (150, 150)
# Data augmentation using ImageDataGenerator
datagen = ImageDataGenerator(width_shift_range=0.2)
# Function that prepares images including Haar cascade based head zoom ('haarcascade_frontalface_default.xml')
def ImageProcessing(dir, type):
for class_name in os.listdir(dir):
class_dir = os.path.join(dir, class_name)
if not os.path.isdir(class_dir):
continue # Skip non directory files
class_label = 1 if class_name == 'nunez' else 0 # Assign label based on class name
for file in os.listdir(class_dir):
img_path = os.path.join(class_dir, file)
img = cv2.imread(img_path)
# Skip the image if it cannot be read or has an empty size
if img is None or img.size == 0:
print(f"Skipped image: {img_path}")
continue
# Perform face detection and crop around the head region
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
if len(faces) > 0:
(x, y, w, h) = faces[0] # Crop around the first detected face
img = img[y:y + h, x:x + w]
img = cv2.resize(img, target_size)
img = img / 255.0 # Normalize the image pixels to the range [0, 1]
img = np.squeeze(img) # Remove single-dimensional entries from the shape of the array
img = img.astype(np.float32) # Convert image data type to np.float32
# If statement that proccess data based on if it is training or test
if type != 1:
test_data.append(img)
test_labels.append(class_label)
else:
# Apply random data augmentation with randomly selected transformation parameters
if np.random.rand() < 0.5:
augmented_images = datagen.flow(np.expand_dims(img, axis=0), batch_size=1)
for augmented_image in augmented_images:
augmented_image = augmented_image[0]
train_data.append(augmented_image)
train_labels.append(class_label)
break # Break the loop to generate only one augmented image
else:
train_data.append(img)
train_labels.append(class_label)
# Calling the image processing function for the training and test data
ImageProcessing(train_dir,1)
ImageProcessing(test_dir,0)
# Convert the data and labels to NumPy arrays
train_data = np.array(train_data)
train_labels = np.array(train_labels)
test_data = np.array(test_data)
test_labels = np.array(test_labels)
# Print the shapes of the train and test data - just a check
print(f"Train Data Shape: {train_data.shape}")
print(f"Train Labels Shape: {train_labels.shape}")
print(f"Test Data Shape: {test_data.shape}")
print(f"Test Labels Shape: {test_labels.shape}")
# Build the model, based on tensorflow/keras
model = models.Sequential()
model.add(layers.Conv2D(64, (3, 3), activation='relu', input_shape=(150, 150, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(256, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(512, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Flatten())
model.add(layers.Dropout(0.5)) # Add dropout for regularization
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
model.compile(optimizer=keras.optimizers.Adam(learning_rate=0.001), loss='binary_crossentropy', metrics=['accuracy'])
model.summary()
# Set the number of epochs
num_epochs = 10
# Train the model
history = model.fit(train_data, train_labels, epochs=num_epochs, validation_split=0.2)
# Evaluate the model on the training set
train_loss, train_accuracy = model.evaluate(train_data, train_labels)
print(f"Training Loss: {train_loss:.4f}")
print(f"Training Accuracy: {train_accuracy:.4f}")
# Evaluate the model on the test data
test_loss, test_accuracy = model.evaluate(test_data, test_labels)
# Print the evaluation results
print("Test Loss:", test_loss)
print("Test Accuracy:", test_accuracy)
# Get the model predictions on the test data
test_predictions = model.predict(test_data)
test_predictions = (test_predictions > 0.5).astype(int) # Convert probabilities to binary predictions
# Calculate evaluation metrics
true_positives = 0
true_negatives = 0
false_positives = 0
false_negatives = 0
for i in range(len(test_labels)):
if test_predictions[i] == 1 and test_labels[i] == 1:
true_positives += 1
elif test_predictions[i] == 0 and test_labels[i] == 0:
true_negatives += 1
elif test_predictions[i] == 1 and test_labels[i] == 0:
false_positives += 1
elif test_predictions[i] == 0 and test_labels[i] == 1:
false_negatives += 1
# Calculate evaluation metrics
accuracy = (true_positives + true_negatives) / len(test_labels)
precision = true_positives / (true_positives + false_positives)
recall = true_positives / (true_positives + false_negatives)
f1_score = 2 * (precision * recall) / (precision + recall)
# Print the evaluation metrics
print("Accuracy:", accuracy)
print("Precision:", precision)
print("Recall:", recall)
print("F1 Score:", f1_score)