Experiment with Support Vector Machine and Kernel Support Vector Machine classifiers to detect whether there is a face in a small image patch. And compare their performance. (Part of my course work during University)
The dataset contains face and non-face images with 19x19 pixel values.
REMARK:This project only used part of the images as dataset is large.
Data overview | Face and non-face sample |
---|---|
This project mainly relied on the library Scikit-learn, and the SVM module provides 3 classes capable of performing binary and multi-class classification.
Image from https://scikit-learn.org/stable/modules/svm.html
The accuracy only tells part of the classifier's performance. We can also look at the different types of errors that the classifier makes:
- True Positive (TP): classifier correctly said face
- True Negative (TN): classifier correctly said non-face
- False Positive (FP): classifier said face, but not a face
- False Negative (FN): classifier said non-face, but was a face
This is summarized in the following table:
Actual | |||
---|---|---|---|
Face | Non-face | ||
Prediction | Face | True Positive (TP) | False Positive (FP) |
Non-face | False Negative (FN) | True Negative (TN) |
We can then look at the true positive rate and the false positive rate.
- true positive rate (TPR): proportion of true faces that were correctly detected
- false positive rate (FPR): proportion of non-faces that were mis-classified as faces.
Train the SVM classifiers directly based on the pixel.
==============
Method : pixel_based
Training Accuracy - svm-lin: 0.9833810888252149
Testing Accuracy - svm-lin: 0.6430084745762712
Training Accuracy - svm-rbf: 1.0
Testing Accuracy - svm-rbf: 0.6578389830508474
Training Accuracy - svm-poly: 1.0
Testing Accuracy - svm-poly: 0.6620762711864406
==============
Method : pixel_based
TP= 154
FP= 1
TN= 471
FN= 318
TPR= 0.326271186440678
FPR= 0.00211864406779661
The support vector
There are a total of 307 images are chosen to be the support vectors from the best classifier - SVM-Poly
The detection performance is not that good using pixel values.
The problem is that we are using the raw pixel values as features, so it is difficult for the classifier to interpret larger structures of the face that might be important. We can see that there is only one false positive but so many false negatives, which means it predicts it to be non-face when it is supposed to predict it as a face. In addition, we can see that the true positive rate is also less, which means it is not able to predict the faces properly.
To fix the problem of SVM using pixel values, we can extract features from the image using a set of filters. The filters are sets of black and white boxes that respond to similar structures in the image. After applying the filters to the image, the filter response map is aggregated over a 4x4 window. Hence each filter produces a 5x5 feature response. Since there are 4 filters, then the feature vector is 100 dimensions.
Target image | Feature extraced |
---|---|
Train the SVM classifiers on feature extracted from images.
==============
Method : feature_extraction
Training Accuracy - svm-lin: 0.9621776504297994
Testing Accuracy - svm-lin: 0.7129237288135594
Training Accuracy - svm-rbf: 0.9977077363896848
Testing Accuracy - svm-rbf: 0.7341101694915254
Training Accuracy - svm-poly: 0.9914040114613181
Testing Accuracy - svm-poly: 0.7542372881355932
==============
Method : feature_extraction
TP= 226
FP= 32
TN= 665
FN= 21
TPR= 0.9149797570850202
FPR= 0.04591104734576758
Although it doesn't seem very accurate since we can see that it detected a few faces, it also had some false positives and didn't detect as many True positives as it should have.
But please be reminded that this project only used one-quarter of the dataset, the performance could be improved if numbers of images increase.
pip install -r requirements.txt
python main.py --data_subsample 4 --max_test 472 --random_seed --seed 2024 --method all
--data_subsample : The factor of sample the dataset
--max_test : The maximum number of test samples for each class
--random_seed :Fixing the random seed
--seed : The random seed
--method : ["all", "pixel_based", "feature_based"]
--test_img : Your own test_img, default using the nasa-small.png