Facial recognition systems have gained importance in studying computer vision, pattern recognition, and human-machine computer interfaces over the past few years. It is one of the tasks filled with complexities and challenges due to the possibility of variations. For example, humans’ illumination, posture, and facial expressions can be tricky to recognize quickly. Developers have suggested many approaches that they can utilize for such systems. Some of the most common approaches used for facial recognition systems are the PCA method and MLP classifier.

Facial Recognition with Python

What is PCA?

Principal component analysis, known as PCA, is a type of unsupervised learning method in Machine Learning. It is a non-parametric statistical method that helps in reducing dimensions in data sets. The developers use PCA to remove the extra number of features from data, leading to over-fitting the model. Since over-fitting causes generalization problems on examples outside the provided data set, PCA is used to remove the curse of dimensional to solve this problem.

Use of PCA in facial recognition

Performing Human facial recognition using PCA requires the generation of eigenfaces. In computer vision problems, eigenfaces are the set of eigenvectors that help facial recognition systems. Sirovich and Kirby developed this technique of using eigenvectors for developing facial recognition systems in 1987, which was later utilized by Mathew Turk and Alex Pentland to classify faces. The developers first transform the images provided for the algorithm’s training into a set of eigenfaces. They then convert the complete training data set of human images to eigenfaces by calculating standard face elements using statistical analysis. Therefore, they mostly express human images as a combination of different eigenfaces.

What is MLP?

A class of feed-forward artificial neural networks is known as Multilayer Perceptron or MLP. It includes three main types of layers of nodes. These layers are the following:

  1. Input Layer
  2. Hidden Layer
  3. Output Layer

In every layer, some neurons usually use a nonlinear activation function. This function returns true for all the layers, excluding input layer nodes. For training of such algorithms, a technique is used, which is known as the backpropagation method. Backpropagation is a technique of supervised learning and helps to differentiate the data, which is linearly inseparable. The perceptron in every layer of MLP is deeply connected. Therefore, there may be a considerable number of total parameters involved due to multiplication in different layers. Consequently, the high dimensional data sets become redundant.

Facial recognition using MLP classifier and PCA

In this tutorial, the user loads the dataset, called, Labelled faces in the wild (LFW), from the UMass website. However, although the developers can use their own labeled set, this article uses the LFW dataset to implement the facial recognition system.

Fetching the Dataset

The users can import the LFW data set from the sklearn library. The benefit of using it is that if the dataset is not available on the disk, it automatically downloads it from the internet. Moreover, they can also specify the minimum faces per person by giving the minimum number to the fetch_lfw_people() function.

from sklearn.datasets import fetch_lfw_people
lfw_dataset = fetch_lfw_people(min_faces_per_person=100)

#printing the set side by side
print("Size of data set: \n") 
samples, h, w = lfw_dataset.images.shapeprint("samples: \t %d \n" % samples)

X = lfw_dataset.data
features = X.shape[1]faces = X.shape[0]
print("features: \t %d \n" % features) 

y = lfw_dataset.target 
target_names = lfw_dataset.target_names
classes = target_names.shape[0]
print("classes: \t %d \n" % classes)

The user specifies the limit to be a hundred in the above coding example.  It means that the function should fetch the data of only those people who have equal to or more than a hundred faces. So, the function fetches the requested data as a numpy array for the developer to use later.
Note: All the images in the dataset should be of the same size to store them in a numpy array. Additionally, the images should not be so large to slow down the algorithm.

Splitting the dataset

In building a recognition system, the first step is to split the above data into testing and training data. Fortunately, the users can split the data by merely calling a function named train_test_split()and can control the splitting ratio and randomization in its arguments. The users can then store the returned data in independent testing and training variables.

from sklearn.model_selection import train_test_split
# split into a training and testing set
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state = 0)
n_components =100

Dimension reduction using PCA

The next step is to use the PCA method to reduce the dimensionality of the data. The sklearn provides the functions to compute the PCA of any data. The user specifies the component count, which is otherwise known as the output dimensionality. In the example below, the developer is reducing the dimensionality to 100 eigenvectors. Moreover, the users can choose to whiten the data as in the below example. The whitening of the data makes it have a unit variance, which gives improved predictive accuracy.

Furthermore, the users can only apply the PCA () function on the training data and then apply the transformation to both data sets to generalize the testing data.

# PCA computation 
from sklearn.decomposition import PCA 

def pca_1 (xtrain, xtest, c):
 #whiten : bool, optional argument and by default "False."
 #Whitening removes some information from the transformed signal but improves the predictive accuracy
 
 start =time()
 n_components =100;
 print("Computing PCA.....")
 pca = PCA(n_components=n_components, whiten=True)
 pca.fit(xtrain)      #standardizing the training data to mean =0 & variance =1 

# # apply PCA transformation to training data
 X_train_pca = pca.transform(xtrain)
 X_test_pca = pca.transform(xtest)
 end = time()
 print("Time taken to compute PCA: %f sec" % ((end-start)))

Additionally, the user is calling the time () function inside the method, which is optional. It measures the starting and ending time of the function, which he uses to find the function’s time to compute PCA.

Multi-layer perceptron (MLP) classification

In the MLP method, the MLPClassifier () trains a multi-layer perceptron and fits the classifier on the data. In this classification function, the users can specify the size of hidden layers in the neural network and the batch size.  Moreover, the user can choose to give the bool argument for verbose and early stopping parameters. Verbose is an optional parameter that specifies whether the user wants the function to print progress messages to stdout or not. The early stopping argument gives it the authority that if the average accuracy does not increase significantly after a certain number of epochs, it stops training to prevent the model’s overfitting.

Secondly, it calls the predict method based on the classifier to predict the testing data. In this case, the testing data are the image faces that this method has to predict to tell which face belongs to whom.

Finally, the method calls for the classification report and the confusion matrix to show this classification’s predictive accuracy. The users can tweak the classifier parameters and compare the results to get a better classifier for their dataset.

#MLP classification
from sklearn.neural_network import MLPClassifier
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix 

def MLP(xtrain, xtest, ytrain, ytest):
 # train a multi-layer perceptron
 #verbose : bool, optional, default False (Whether to print progress messages to stdout)
 #batch_size :  number of samples that will be propagated through the network
 
 start =time()
 print("Fitting the classifier to the training set")
 clf = MLPClassifier(hidden_layer_sizes=(1024,), batch_size=256, verbose=False, early_stopping=True).fit(xtrain, ytrain)
 end = time()
 print("Time taken to train MLP: %f sec" % (end-start))
 start = time()
 y_pred = clf.predict(xtest)
 end = time()
 print("Time taken by MLP to predict: %f sec" % (end-start))
 print("classfication report:")
 print(classification_report(ytest, y_pred, target_names=target_names))
 print("confusion matrix:")
 print(confusion_matrix(ytest, y_pred, labels=range(classes)))