Cross platform Tensorflow deployment with Python
Python code to run inference with Tensorflow Lite that works on Android, iOS, Windows, MacOS and Linux.
Why insist on using Python?
Python is a fantastic ecosystem. There are so many high quality open source libraries available that help you quickly build quite complex projects that just work. This no doubt contributes to Python’s popularity as a Deep Learning framework. Crucially, pip (or pipenv) handles the dependencies for you so that you avoid descending into version hell. This makes Python great for prototyping, but getting to a polished product that is easy to use can sometimes be more work than all the rest put together. As the joke goes, the answer might be “I wouldn’t start from here”.
Web app or mobile app?
Often the best option is to deploy an application over the web so that the browser effectively takes care of the platform specifics. Your Python code can then run as a service and be integrated into a scalable architecture that runs on the cloud. But what if the amount of data that needs to be sent back and forth is too large or sensitive? Given that most of us carry around the equivalent of an 80s super computer in our pockets, it makes sense to tap into the power of the mobile phone.
As an example, I developed a music recommendation algorithm based on raw audio data using deep learning. Given a collection of MP3s, it automatically creates playlists of music that goes well together or that smoothly transition from one song to another. I wanted to be able to run it on my phone, tablet or computer without having to upload all my tracks to the cloud for analysis. I figured that as Tensorflow Lite was available on almost every platform imaginable, it should be possible without having to rewrite lots of code.
Qt versus Kivy
There are a number of cross platform development tools around, but few of them work on desktops and mobiles and make it easy to integrate Python code. I explored two which claim to do exactly this: Qt and Kivy.
Qt comes in the form of PyQt5 and pyqtdeploy. Platform specific stuff like playing audio is abstracted away by Qt and so, in theory, you only have to write this code once. The downside of this generic approach is that you may not be able to fully exploit the capabilities of your target device. My experience was that it was very difficult to build with Numpy for Android and I didn’t get as far as even attempting it with iOS. It really felt like trying to force a round peg into a square hole.
Kivy, on the other hand, is written in Python and works with libraries like buildozer (for building on iOS and Android), PyInstaller (for packaging desktop applications), p4a (Python for Android) and kivy-ios. I got a basic application using Numpy up and running very quickly, was able to make it look smart with KivyMD (Material Design) and at the same time have full control of platform specific functionality using pyobjus (for calling Objective C from Python on iOS), pyjnius (for calling Java from Python on Android) and plyer. I got a bit of a head start thanks to an example running Tensorflow Lite on Android by one of the pyjnius developers, Tito.
It took me a lot longer to get the iOS version to work, mainly because I don’t have a Mac and so I had to use an emulator, but also because Objective C is horrible and not easy to call from Python. (I also had a taste of version hell in the form of duplicate symbols from audio libraries included both by kivy-ios and a Cocoapod.) Another approach would be to call Tensorflow Lite and Python from Swift instead, but this would mean rewriting my app completely.
The following snippet extends Kivy by allowing you to run inference on Tensorflow Lite in a platform independent way. It assumes that your model has only one input and output tensor — which is usually the case — but it is quite straightforward to generalize to multiple inputs and outputs.
To make it easy to get started, I have created a “Hello World” Tensorflow Lite app that runs on Android, iOS, MacOS, Windows and Linux. It should be fairly straightforward for you to adapt it to your needs. Now there is nothing stopping you from developing a Deep Learning app that leverages the sensors and capabilities of your device!
In conclusion, I would say that Kivy is very promising and the developers are busy improving it all the time. In my view it is very close to being able to produce production quality applications.