Machine Vision: Making a Face Recognition Back-end
In my previous article, I promised to write a more technical series of articles that chronicle the journey of creating a face recognition Android app that uses a python back-end and TensorFlow. I shall break the process into a three-part article. In this first article, we shall look at the process of creating the backend. Then, in the next article, we shall look at how the app was. Finally, we shall have a third article to address miscellanies and curate lessons learned. Any arising questions from the reader shall also be addressed in that final article.
Getting the back-end up and running was probably where most of the time was spent on my journey to create the face recognition app. Most of the technologies I had to work with were either completely new to me or I lacked substantial experience in them. Flask used to be a thermos, Python was a snake, and Docker(s) were some cool shoes my dad never bought me in high school. But over the course of two months all that changed, and now I cannot imagine life without Python, Docker, and TensorFlow Serving.
I only know how to do data science, ML, and AI using Python. Therefore, when I realized I needed to host a face recognition AI model in the back-end, I automatically knew it had to be a Python back-end. But raw Python did not appeal to me. I have worked with both vanilla PHP and a couple of PHP frameworks and have a healthy respect for the quantity of work and stupidity frameworks can save you. Without going into many details, I ended up choosing Flask over Django. The latter seemed too heavy and needed more configurations to get started, and it gave me a hard time just to serve a “Hello World!”.
Once the choice of a framework was made, I had to prepare Flask for the task ahead. Flask is very lightweight and that means a fair amount of work is left to the developer. At first, I just focused on getting things to work. I later came back to organize the code into a standard MVC project. This approach served me really well. By the time I started moving the pieces around to clean the code I already knew how the pieces fitted together. It was thus easier to solve the occasional bug or two that I introduced by renaming a class here or moving some code there to a different module.
In the end, my back-end was as illustrated in the diagram below. Nginx is used for socket management, load balancing, and HTTP parsing and rule matching. uWSGI manages Python’s virtual environment and the Flask process(es) and its socket(s). Flask itself maps URLs to specific requests, wraps requests, and acts a middleware to the custom code I wrote and to the Docker container running TensorFlow Serving. TensorFlow Serving is responsible for handling, queuing, and processing requests to the face recognition model itself.
As a beginner in almost all the technologies above, I struggled with almost every single task. Every small milestone turned out to be a Herculean task which required me to research a lot of background information just to accomplish it. But, on the upside, I learned a lot and can now recreate the entire back-end in a tiny fraction of the time it took at first.
If you want to do something similar yourself, I am sharing the code on GitHub. I have seen the benefits of building on top of other people’s work instead of starting your own. This not only makes things move faster but ultimately makes them move further. I may not have much more energy and/or time to explore where this project could go, but maybe you do and I would encourage you to give it a try.
All in all, it was quite a challenge to come up with the simple system structure above. I believe once you see how the parts go together, it is easy to replicate it using your preferred technology stack. Personally, I implemented an Android app as a client. However, given the fact that the back-end is exposed as an API, one could just as easily call it from any other client which can send and receive JSON e.g. an iOS app, a website, desktop software, etc. Check out the next article to see how I made the Android app. If you have any questions on how to achieve anything here, please leave a comment below. What I cannot fully answer in the comments, I will include in the final article.