# %% Import libraries
import numpy as np
import matplotlib.pyplot as plt
import cv2 as cv
import os
import glob
import random
from tensorflow.keras import backend as K
from tensorflow.keras.models import Sequential
from tensorflow.keras.preprocessing.image import ImageDataGenerator , img_to_array
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.layers import Dense, Conv2D, BatchNormalization, Flatten, MaxPooling2D, Dropout, Activation
from tensorflow.keras.utils import to_categorical, plot_model
# %% Intial parameters
epochs = 100
learning_rate = 1e-3
batch_size = 64
input_dim = (96,96,3)
# %% Load image file from dataset
data = []
labels = []
image_files = [file for file in glob.glob(r'G:\Machine Learning\Project\Face Detection\Male Female Classification' + '/**/*', recursive=True) if not os.path.isdir(file)]
random.shuffle(image_files)
# glob gives the path
# image_files[0] = 'G:\\Machine Learning\\Project\\Male Female Classification\\women\\w (42).jpeg'
# %% Resizing Images and converting images to array and labeling the categories
count = 0
for img in image_files:
if count >= 800:
im = cv.imread(img)
im = cv.resize(im, dimension) # Resizing will be completed here
im = img_to_array(im)
data.append(im)
# labeling the categories in 0 and 1
label = img.split(os.path.sep)[-2] # reverse indexing of files in folder # Machine Learning\Project\Male Female Classification\women\ w(1). png
if label == 'women':
label = 1
else:
label = 2
labels.append([label]) # because we need 2 dim array like [[0],[1],[0],[0],....]
# %% Preprocessing
# converting to array
data = np.array(data, dtype=np.float32)/255.0 # scalling
labels = np.array(labels)
# %% Spliting dataset for training and validation
x_train, x_test, y_train, y_test = train_test_split(
data, labels, test_size=0.2,random_state=42
)
y_train = to_categorical(y_train, num_classes=2) # [[1, 0], [0, 1], [0, 1], ...]
y_test = to_categorical(y_test, num_classes=2)
# %% augmenting datset
aug = ImageDataGenerator(
rotation_range=25,
width_shift_range=0.1,
height_shift_range=0.1,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode="nearest"
)
# %% define model
def build(width, height, depth, classes):
model = Sequential()
inputShape = (height, width, depth)
chanDim = -1
if K.image_data_format() == "channels_first": #Returns a string, either 'channels_first' or 'channels_last'
inputShape = (depth, height, width)
chanDim = 1
# The axis that should be normalized, after a Conv2D layer with data_format="channels_first",
# set axis=1 in BatchNormalization.
model.add(Conv2D(32, (3,3), padding="same", input_shape=inputShape))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling2D(pool_size=(3,3)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3,3), padding="same"))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(Conv2D(64, (3,3), padding="same"))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))
model.add(Conv2D(128, (3,3), padding="same"))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(Conv2D(128, (3,3), padding="same"))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(1024))
model.add(Activation("relu"))
model.add(BatchNormalization())
model.add(Dropout(0.5))
model.add(Dense(classes))
model.add(Activation("sigmoid"))
return model
# %% build model
model = build(
width=img_dims[0], height=img_dims[1], depth=img_dims[2], classes=2
)
# %% compile the model
opt = Adam(lr=lr, decay=lr/epochs)
model.compile(loss="binary_crossentropy", optimizer=opt, metrics=["accuracy"])
# %% train the model
process = model.fit_generator(aug.flow(trainX, trainY, batch_size=batch_size),
validation_data=(testX,testY),
steps_per_epoch=len(trainX) // batch_size,
epochs=epochs, verbose=1)
# %% save the model to disk
model.save('gender_detection.model')
# %% plot training/validation loss/accuracy
plt.style.use("ggplot")
plt.figure()
N = epochs
plt.plot(np.arange(0,N), process.history["loss"], label="train_loss")
plt.plot(np.arange(0,N), process.history["val_loss"], label="val_loss")
plt.plot(np.arange(0,N), process.history["acc"], label="train_acc")
plt.plot(np.arange(0,N), process.history["val_acc"], label="val_acc")
plt.title("Training Loss and Accuracy")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend(loc="upper right")
Comments
Post a Comment