Jump to content

GSoC/2021/StatusReports/NghiaDuong: Difference between revisions

From KDE Community Wiki
Nghia (talk | contribs)
Nghia (talk | contribs)
Line 76: Line 76:
It seems like we run into a bottleneck of facial recognition in our implementation of the faces engine. As debugged during the previous Google Summer of Code, the main reason for the recognition error was due to the noise in the face embedding output by the [https://cmusatyalab.github.io/openface/ OpenFace] model.
It seems like we run into a bottleneck of facial recognition in our implementation of the faces engine. As debugged during the previous Google Summer of Code, the main reason for the recognition error was due to the noise in the face embedding output by the [https://cmusatyalab.github.io/openface/ OpenFace] model.


[[File:UMAP projection of faces embedding from Extended Yale B dataset.png|thumb|center|600px|'''UMAP projection of faces embedding output by the OpenFace model ''']]
[[File:UMAP projection of faces embedding from Extended Yale B dataset.png|thumb|center|600px|'''Figure 2: UMAP projection of faces embedding output by the OpenFace model ''']]


As a suggestion of Thanh Trung Dinh, we could use [https://github.com/davidsandberg/facenet David Sandberg's Facenet Tensorflow implementation] as a replacement in our faces engine. During [https://community.kde.org/GSoC/2019/StatusReports/ThanhTrungDinh his 2019 Google Summer of Code], he wanted to use [https://github.com/davidsandberg/facenet David Sandberg's Facenet], which was implemented very close to the [https://arxiv.org/abs/1503.03832 Facenet paper], for digiKam's faces engine. However, at that time, the translation of the Tensorflow pretrained model to an OpenCV readable format was not available. That is the reason why we are using [https://cmusatyalab.github.io/openface/ OpenFace] as an alternative. Lately, with the help of [https://github.com/TanFluent/facenet_opencv_dnn TanFluent], we are now able to use Facenet with OpenCV. Therefore, now may be a good time to use the Facenet model in the faces engine.
As a suggestion of Thanh Trung Dinh, we could use [https://github.com/davidsandberg/facenet David Sandberg's Facenet Tensorflow implementation] as a replacement in our faces engine. During [https://community.kde.org/GSoC/2019/StatusReports/ThanhTrungDinh his 2019 Google Summer of Code], he wanted to use [https://github.com/davidsandberg/facenet David Sandberg's Facenet], which was implemented very close to the [https://arxiv.org/abs/1503.03832 Facenet paper], for digiKam's faces engine. However, at that time, the translation of the Tensorflow pretrained model to an OpenCV readable format was not available. That is the reason why we are using [https://cmusatyalab.github.io/openface/ OpenFace] as an alternative. Lately, with the help of [https://github.com/TanFluent/facenet_opencv_dnn TanFluent], we are now able to use Facenet with OpenCV. Therefore, now may be a good time to use the Facenet model in the faces engine.
Line 82: Line 82:
After a few tests in python, with the original tensorflow facenet model, the result on the Extended Yale B dataset is outstanding. The Facenet model outputs a 512-dimensional face embedding for each face image. We extracted the face embeddings from the Extended Yale B dataset and saved them in a csv file. After that, same as in the experiment with OpenFace, we project these high dimensional data on 2D plan and here is the result:
After a few tests in python, with the original tensorflow facenet model, the result on the Extended Yale B dataset is outstanding. The Facenet model outputs a 512-dimensional face embedding for each face image. We extracted the face embeddings from the Extended Yale B dataset and saved them in a csv file. After that, same as in the experiment with OpenFace, we project these high dimensional data on 2D plan and here is the result:


[[File:Umap facenet.png|thumb|center|600px|'''UMAP projection of faces embedding output by the Facenet model ''']]
[[File:Umap facenet.png|thumb|center|600px|'''Figure 3: UMAP projection of faces embedding output by the Facenet model ''']]
 
Compare to the same projection on the face embeddings output by the OpenFace model shown in Figure 2, we can see that there is a huge difference in the result. On the projected data given in Figure 3, we can easily classify different classes with human eyes. When applying the algorithms mentioned in the previous section on this data, we achieve the highest accuracy of 98.7% with KNN and Gaussian SVM.

Revision as of 13:51, 11 July 2021

Digikam: Faces engine improvements

digiKam is a famous open-source photo management software. Face engine is a tool helping users recognize and label faces in photos. Following the advance of Deep Learning, digiKam development team has been working on the Deep Learning implementation of the Faces engine since 2018. During the past few years, with the huge effort of digiKam developers and the great support from users, the Faces engine has been improved gradually.

Last year, during the 2020 Google Summer of Codes, I had a chance to work on digiKam's faces engine, as a part of the DNN based Faces Recognition Improvements project. At the end of this project, we were able to finish the implementation of a machine-learning-based classification system for facial recognition. On top of that, we also remodeled the face database of digiKam which was specialized in face embedding storage. As the final result, we achieved an accuracy of 84% on facial recognition, with a processing speed of about 19 ms/face.

However, after receiving reviews and bug reports from users, we found out that there are a few remaining problems on the faces engine. Therefore the main goals of this project to pick up the previous work and focus on improving the accuracy of digiKam's faces engine.

Mentors : Gilles Caulier, Maik Qualmann, Thanh Trung Dinh

Important Links

Project Proposal

Digikam Faces engine improvements

GitLab development branch

gsoc21-faces-engine

Contacts

Email: [email protected]

Github: MinhNghiaD

Invent KDE: minhnghiaduong

LinkedIn: https://www.linkedin.com/in/nghia-duong-2b5bbb15a/

Project Goals

The current goals of this project are to :

  • Improve the accuracy of faces classifier with outlier detection
  • Improve the speed of facial recognition and detection, improve batch processing
  • Improve the face management pipeline organization

Project Report

Community Bonding period (May 17 - June 7)

The current version of the face classifier of the faces engine support K-Nearest neighbors and Linear Support vector machine as algorithms. With K-Nearest neighbors, we select a certain number of closest data points that lie inside a threshold area to select the best label to match with the data. If there aren't any points that satisfy the threshold, the classifier will consider that it is an outlier. This algorithm performs quite well on a large dataset. However, when the training data is limited, which is mostly the case for digiKam users, K-Nearest neighbors do not perform well with high dimensional data, due to the curse of dimensionality. On the other hand, SVM suffers less from the curse with dimensionality, but it only creates boundaries for a known number of labels. When it comes to face the image of a new entity, the classifier will try to assign it to a known label which is considered by the user a wrong label.

Therefore, during the community bonding period, my main goal is to prepare for the selection of the best classification algorithm for the face embedding distribution from the OpenFace CNN that we are currently using in the faces engine. The selection criteria are accuracy on multi-class classification and accuracy on outlier detection. This means that not only the selected algorithm has to perform well when it comes to classification between known labels, but also to be able to guess if a face is already "known" or not.

For this phase, some machine learning analytical tools like R or Python are suitable for quick experimentation and statistical exploration. Therefore, we decided to perform model selection in R, using the extract data from the Extended Yale B dataset that contains over 12900 face images. For this process, we split the entire dataset into 3 subsets, a validation set contains 50% of the data for the final performance evaluation of the selected model, a training set that contains 40% of the data, and a test set that contains 10% of the data for cross-validation. To support classification and novelty detection, we have algorithms that output the posterior probability of the data point belong to a group, for example, Discriminant analytics and Logistic regression. Or, we can use a dedicated algorithm to filter out the outliers, like One-class SVM, and then perform the classification using another algorithm.

Coding period : Phase one (June 7 - July 12)

In this phase, my work mostly concentrated on testing and improving the accuracy and speed of the facial recognition module of the faces engine. The works include finding suitable classification algorithms, trying out other deep learning models for facial recognition if needed, and implement data processing to improve general performance.

June 7 to June 21 (Week 1 - 2) - Experimentation on face embedding data

DONE

  • Exploring face embedding data.
  • Evaluating the performance of different classification algorithms on this dataset.
  • Implementing the suitable algorithm in C++.
  • Evaluating the performance of the C++ implementation.

TODO

  • Try out the Keras-Facenet implementation of the Facenet model.


As mentioned in the section above, the first goal of this project is to select a suitable model for the face classifier of digiKam's faces engine. Currently, we are using the Openface pre-trained model as the neural network of the faces engine. Cropped-face images are passed through the neural network to output 128-dimension face representation vectors called face embeddings. After exporting the face embedding data extracted from digiKam's faces engine, we stored it in a csv formatted file for easier experimentation and to eliminate the overhead recomputation. With R scripting language, we can easily manipulate the data and explore some classical algorithms like LDA, QDA and SVM.

Firstly, we can see that the data is high-dimensional (128 predictors and 1 label to explain). Therefore, we need to reduce the high dimensionality of the problem before applying machine learning algorithms. A simple dimensional reduction method is Principal component analysis (PCA), which computes the eigen vectors (data orientation) and eigen values (projection of data on new vectorial space). Other more complex dimensional reduction techniques like UMAP and T-SNE will be explored in more detail in the next sections.

Figure 1: Principal component analysis on face embedding data

Here we can see, with PCA, 90% of the data variance can be explained with only 27 principal components. Therefore, we can select these 27 components as new predictors of our data set. After the experiment with LDA, QDA, and SVM, I find that the QDA and Gaussian-SVM give the best results. Therefore, we can find that the non-linear decision boundaries responses best to this problem. However, the best result is still not good enough (86% accuracy for classification without outlier and 74% accuracy for classification with outliers). Therefore, we need to find another way to boost the performance of the faces engine.

June 22 to July 11 (Week 3 - 4 - 5) - Boost the accuracy of facial recognition to 98.54% with Facenet and T-SNE

DONE

  • Export facenet neural network to OpenCV.
  • Reconstruct the preprocessing pipeline for facenet in OpenCV.
  • Reduce recognition error by reducing data dimension with UMAP and T-SNE.
  • Export Multicore T-SNE to compile with digiKam code base.

TODO

  • Integrate the new implementation with the main pipeline.
  • Improve batch processing and background processing in faces engine.

It seems like we run into a bottleneck of facial recognition in our implementation of the faces engine. As debugged during the previous Google Summer of Code, the main reason for the recognition error was due to the noise in the face embedding output by the OpenFace model.

Figure 2: UMAP projection of faces embedding output by the OpenFace model

As a suggestion of Thanh Trung Dinh, we could use David Sandberg's Facenet Tensorflow implementation as a replacement in our faces engine. During his 2019 Google Summer of Code, he wanted to use David Sandberg's Facenet, which was implemented very close to the Facenet paper, for digiKam's faces engine. However, at that time, the translation of the Tensorflow pretrained model to an OpenCV readable format was not available. That is the reason why we are using OpenFace as an alternative. Lately, with the help of TanFluent, we are now able to use Facenet with OpenCV. Therefore, now may be a good time to use the Facenet model in the faces engine.

After a few tests in python, with the original tensorflow facenet model, the result on the Extended Yale B dataset is outstanding. The Facenet model outputs a 512-dimensional face embedding for each face image. We extracted the face embeddings from the Extended Yale B dataset and saved them in a csv file. After that, same as in the experiment with OpenFace, we project these high dimensional data on 2D plan and here is the result:

Figure 3: UMAP projection of faces embedding output by the Facenet model

Compare to the same projection on the face embeddings output by the OpenFace model shown in Figure 2, we can see that there is a huge difference in the result. On the projected data given in Figure 3, we can easily classify different classes with human eyes. When applying the algorithms mentioned in the previous section on this data, we achieve the highest accuracy of 98.7% with KNN and Gaussian SVM.