top of page

Facial Recognition

using Neural

Networks

 

 

Introduction

 

Backpropagation, an abbreviation for "backward propagation of errors", is a common method of training artificial neural networks. From a desired output, the network learns from many inputs, similar to the way a child learns to identify a dog from examples of dogs.The NN explained here contains three layers. These are input, hidden, and output Layers. During the training phase, the training data is fed into to the input layer. The data is propagated to the hidden layer and then to the output layer. This is called the forward pass of the back propagation algorithm. In forward pass, each node in hidden layer gets input from all the nodes from input layer, which are multiplied with appropriate weights and then summed. The output of the hidden node is the nonlinear transformation of the resulting sum. Similarly each node in output layer gets input from all the nodes from hidden layer, which are multiplied with appropriate weights and then summed. The output of this node is the non-linear transformation of the resulting sum. The output values of the output layer are compared with the target output values. The target output values are those that we attempt to teach our network. The error between actual output values and target output values is calculated and propagated back toward hidden layer. This is called the backward pass of the back propagation algorithm. The error is used to update the connection strengths between nodes, i.e. weight matrices between input-hidden layers and hidden-output layers are updated. During the testing phase, no learning takes place i.e., weight matrices are not changed. Each test vector is fed into the input layer. The feed forward of the testing data is similar to the feed forward of the training data.

 

In this assignment we were required to write/design a 3-layer backpropagation neural network ourselves to solve a 10-class face classification problem. The training and testing samples for this problem were obtained from the ORL face database.

(http://www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html)

Although there were 40 classes in this database we were to choose the first 10 classes for our usage in the first section 1. There were 10 samples for each class.

 

Research

 

Before the project was started a lot of research was done on matlab and its functions as this was the first assignment based entirely on matlab.

Functions

Concatenate strings horizontally

str=strcat(‘Good’,’morning’)
combinedStr=strcat(s1,s2,….,sN)
str =
Goodmorning

Create array of all zeros

X = zeros(n) returns an n-by-n matrix of zeros.

X = zeros(sz1,...,szN,classname) returns an sz1-by-...-by-szN array of zeros of data type classname.

Read image from graphics file

A = imread(filename, fmt) reads a grayscale or color image from the file specified by the string filename. If the file is not in the current folder, or in a folder on the MATLAB® path, specify the full pathname.

Format data into string

str = sprintf(formatSpec,A1,...,An) formats the data in arrays A1,...,An according to formatSpec in column order, and returns the results to string str.

Random numbers and arrays

Y = rand(m,n) or Y = rand([m n]) returns an m-by-n matrix of random entries.

2-D Discrete Cosine Transform

B = dct2(A,m,n) pads the matrix A with 0's to size m-by-n before transforming. If m or n is smaller than the corresponding dimension of A,dct2 truncates A.

 

 

Indexing Vectors

Let's start with the simple case of a vector and a single subscript. The vector is:
v = [16 5 9 4 2 11 7 14];
The subscript can be a single value:
v(3)     % Extract the third element
ans = 9
Or the subscript can itself be another vector:
v([1 5 6])      % Extract the first, fifth, and sixth elements
ans = 16   2   11
The colon notation in MATLAB provides an easy way to extract a range of elements from v:  v(3:7)     % Extract the third through the seventh elements
ans = 9   4   2   11   7
Swap the two halves of v to make a new vector:
v2 = v([5:8 1:4])     % Extract and swap the halves of v
v2 = 2   11   7   14   16   5   9   4

Indexing Matrices with Two Subscripts
 A(2,4)   % Extract the element in row 2, column 4
 A(2:4,1:2)  % Extract row 2 to 4 and column 1 to 2.
 A(3,:)   % Extract third row
 A(:,end)   % Extract last column

Image Input Methods

 

Mainly two types of methods were looked into which are as follows

- Discrete cosine transform (DCT) is closely related to the discrete Fourier transform. It is a separable linear transformation; that is, the two-dimensional transform is equivalent to a one-dimensional DCT performed along a single dimension followed by a one-dimensional DCT in the other dimension.



- Eigenvector mean technique: This method uses principal component analysis to determine the most discriminant features between images of face. The reason this technique was not used is because it is more complex and requires additional m file to operate the command.

 

Methodology

 

The task required us to write a code in matlab which would solve a 10 class classification problem using backprobogation method of neural networks. A sample code was given to us which solves a simple XOR Gate problem.

Matlab recognizes images as pixels and each pixel has a color value (as shown in figure 1).
These pixel form a matrix of values which in our case is 112 X 92.To simplify our process complexity the images were rescaled to   
1000 X 1 matrix. This way we can feed the pixel values as input elements of the Network. The images are then feed into the network for training process and the output /target matrix is defined. The output matrix contains only zeroes and ones.

 

The class number is defined by the location of the number of ones. The training process is then started and the network keeps updating the weights until the sum error reaches the tolerance value. After the training process a sample images is feed into the network. The trained weights of the network are feed into another algorithm which multiples the weights with their respective neurons and gives the output numbers of the image. The highest value of the matrix is found (variable ‘max’) along with its corresponding position (variable ‘index’). This matrix is then converted into zeroes and one (one at the max value number) and then compared with the target matrix .This procedure is repeated for 5 images of all the 10 classes. The number of pictures correctly classified is then calculated and thus the percentage accuracy.

The code for Section 1 task one is given in the appendix.

 

 

 

The Sum error was around 6-20% which is good error percentage. The accuracy percentage varied around 50 -75% which is quiet good as the number of input dimension (100) is considered it seems quite reasonable. If the input dimension was increased the process gets very slow and sometimes even hangs the computer

Percentage error vs Itterations

The code

TRAINING CODE

 

clc;

clear;

Input_dimension = 100;

 

number_of_classes=10;

input_images_per_class=5;

number_of_column =1;

Total_inputs=number_of_classes*input_images_per_class;

inputs = zeros(Total_inputs,Input_dimension) ;

 

 

for a= 1 : number_of_classes

  

    for b= 1 :input_images_per_class

   % Location of the files.

   input_image = strcat('C:\Users\Murtaza Hassan\Desktop\Year 3\Neural networks\Neural Networks Project\s',sprintf('%d',a),'\',sprintf('%d',b),'.pgm');

   % Storing the image.

   stored_image = imread(input_image);

   % Reshaping the image to respective dimension.

   reshaped_image = dct2(stored_image,[Input_dimension,1]);

   % Storing the image to the zero matrix.

   inputs(number_of_column,:)=reshaped_image;

   % Updating the number of coloumn for next image.

   number_of_column =number_of_column+1;

    end

end

 

 

% BACK PROPAGATION ALGORITHM

 

eta = 1;

alpha = 0.1;

tol = 0.5;

Q = Total_inputs ;  %number of samples

n = Input_dimension; % number of input elements

q = 150; % number of output elements

p = 10; % number of classes

Iterate = 1;

 

D1=ones(1,input_images_per_class);

D0=zeros(1,input_images_per_class);

 

 

Wih = 2 * rand(n+1,q) - 1; %Input-hidden weight matrix

Whj = 2 * rand(q+1,p) - 1; %Hidden-Output weight matrix

 

DeltaWih = zeros(n+1,q); %Weight Change Matrix

DeltaWhj = zeros(q+1,p); %Weight Change Matrix

 

DeltaWihOld = zeros(n+1,q);

DeltaWhjOld = zeros(q+1,p);

 

Si = [ones(Q,1) inputs]; %input signals

D2 =[D1 D0 D0 D0 D0 D0 D0 D0 D0 D0

    D0 D1 D0 D0 D0 D0 D0 D0 D0 D0

    D0 D0 D1 D0 D0 D0 D0 D0 D0 D0

    D0 D0 D0 D1 D0 D0 D0 D0 D0 D0

    D0 D0 D0 D0 D1 D0 D0 D0 D0 D0

    D0 D0 D0 D0 D0 D1 D0 D0 D0 D0

    D0 D0 D0 D0 D0 D0 D1 D0 D0 D0

    D0 D0 D0 D0 D0 D0 D0 D1 D0 D0

    D0 D0 D0 D0 D0 D0 D0 D0 D1 D0

    D0 D0 D0 D0 D0 D0 D0 D0 D0 D1];

 D=transpose(D2);              %Desired values

 

Sh = [1 zeros(1,q)];            %hidden Neural Signals

Sy = zeros(1,p);                %output Neuron Signal

deltaO = zeros(1,p);            %Error-slope product at output

deltaH = zeros(1,q+1);          %Error-slope product at hidden

sumerror = 2*tol;               %To get in to the loop

 

while (sumerror > tol)             %iterate

    sumerror = 0;

    for k = 1:Q

        Zh = Si(k,:) * Wih;      %Hidden activations

        Sh = [1 1./(1 + exp(-Zh))];

        Yj = Sh * Whj;

        Sy = 1./(1 + exp(-Yj));

        Ek =D(k,:) - Sy;

        deltaO = Ek .* Sy .* (1 - Sy);

        for h = 1:q+1

            DeltaWhj(h,:) = deltaO * Sh(h);

        end

        for h = 2:q+1

            deltaH(h) = (deltaO * Whj(h,:)') * Sh(h) * (1-Sh(h));

        end

        for i= 1:n+1

            DeltaWih(i,:) = deltaH(2:q+1) * Si(k,i);

        end

        Wih = Wih + eta * DeltaWih + alpha * DeltaWihOld;

        Whj = Whj + eta * DeltaWhj + alpha * DeltaWhjOld;

        DeltaWihOld = DeltaWih;             %Store changes

        DeltaWhjOld = DeltaWhj;

        sumerror = sumerror + sum (Ek.^2);  %Compute error

    end

    sumerror;

    Iterate;

    error (Iterate) = sumerror

    plot (error);figure(gcf)

    Iterate = Iterate + 1;

end

 

 

TESTING CODE

 

Total_inputs=50;

 

inputs = zeros(Total_inputs,Input_dimension) ;

 number_of_column=1;

for a= 1 : number_of_classes

  

    for b= 6 : 10

   % Location of the files.

   input_image = strcat('C:\Users\Murtaza Hassan\Desktop\Year 3\Neural networks\Neural Networks Project\s',sprintf('%d',a),'\',sprintf('%d',b),'.pgm');

   % Storing the image.

   stored_image = imread(input_image);

   % Reshaping the image to respective dimension.

   reshaped_image = dct2(stored_image,[Input_dimension,1]);

   % Storing the image to the zero matrix.

   inputs(number_of_column,:)=reshaped_image;

   % Updating the number of coloumn for next image.

   number_of_column =number_of_column+1;

    end

end

 

% Output of Neural network for testing

 

 

 

 

Si = [ones(Total_inputs,1) inputs];

net_outputs = zeros(Total_inputs,number_of_classes);

for k = 1:Total_inputs

    Zh = Si(k,:) * Wih; % Hidden activations

    Sh = [1 1./(1 + exp(-Zh))];  % Hidden signals

    Yj = Sh * Whj;          % Output activations

    Sy = 1./(1 + exp(-Yj));  % Output signals

    net_outputs(k,:) = Sy;

end

 

test = vec2ind(net_outputs');

% test matrix

a = [1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5 6 6 6 6 6 7 7 7 7 7 8 8 8 8 8 9 9 9 9 9 10 10 10 10 10];

 

Number_of_pics_matched = sum(test == a);  % check classification accuracy

 Accuracy_percentage= 100*(Number_of_pics_matched/50)

 

bottom of page