Creating an image classifier on Android using TensorFlow (part 2)
This post assumes you’ve already read part 1!
In this article, we’re going to rebuild the Android TensorFlow demo app inside a Docker container. You’ll need at least 7GB of free disk space, and you’ll need to understand how to use the command line.
Update: from May 2017 it became possible to build the Android TensorFlow app using only Android Studio — see this section of the demo app README. You can read my article for more detail about this awesome way of embedding a pre-trained TensorFlow model in an Android app. The rest of this article is still a useful introduction to using Bazel to build TensorFlow in a Docker container, and prepares you for part 3. :-)
Rebuild the TensorFlow demo app from source
Using a virtual machine
I strongly recommend using a virtual machine (also called a “container”). Here’s why:
- It is easier to get started. This is because we can create a virtual machine image that already has most of the dependencies we need.
- It protects your computer from any unwanted side effects. If you follow the TensorFlow Android demo app build instructions without thinking, you might accidentally mess up your development environment by installing or upgrading tools needed for the TensorFlow build.
Install Docker and create a TensorFlow-ready container
Follow these steps:
- Install Docker (Mac, Windows). Wait for Docker to finish starting.
- Check Docker is installed correctly:
$ docker run hello-world | grep Hello
You should see
Hello from Docker! be printed out. If something goes wrong, remove the
| grep Hello from the end of the command (it just filters the output).
The TensorFlow project has some Docker containers that you can use. Unfortunately, those don’t contain all the Android dependencies you need. To make your life easier, I’ve created a Docker container which has all the dependencies already on it. If you want the gory details, I’ve documented every step here.
- Download my Docker image with all the dependencies:
$ docker pull danjarvis/tensorflow-android:1.0.0
- Start a Docker container using this image:
$ docker run -it danjarvis/tensorflow-android:1.0.0
This downloads all the TensorFlow dependencies, and creates a 5.9GB Docker container. This step only takes a few minutes if you have a fast internet connection.
You’ve now started your Docker container, and your command prompt will now show a
# at the prompt (because you’re now inside the container).
- Check Python and all the TensorFlow dependencies are working by copying and pasting in the code in this Gist.
This runs a tiny Python program that tries to use the TensorFlow framework. You might see a few warnings, but the final line should say:
Hello from TensorFlow. Everything seems to be working!
Press enter after the
exit() command to exit the Python shell (this takes you back to the
# command prompt for the Docker container).
(The instructions above were inspired by page 2 in the TensorFlow For Poets code lab. Unless you get stuck, don’t read it now — we’ll look at it later).
The key thing to know about Docker is that any changes you make inside the container will be lost when you exit. If you want to save any changes, you need to explicitly commit them.
For more information about using Docker, read the article I mentioned above.
Building the TensorFlow project
First, start your Docker virtual machine (if you aren’t already inside it).
Make a small update to the demo project
Before we build the project, let’s make a minor UI change so we will know for sure when we’re testing our version of the demo app.
We’re going to open RecognitionScoreView.java and change the background color, highlighted here:
I always use the
find command to get the path to a file I want to edit:
# find /tensorflow/ -name RecognitionScoreView.java
Now modify the color in this file. I recommend
0xcc008500 (the format is
0xARGB— docs). I’m going to assume you know how to edit a file from the command line.
I tend to use vi. Only run these commands if you know how to use vi!
# vi /tensorflow/tensorflow/examples/android/src/org/tensorflow/demo/RecognitionScoreView.java
Reminder: this change will be lost if you exit your Docker container. If you want to save it, you should commit the change (for details, see the article I mentioned above).
Build the demo project
Since our Docker container has everything it needs, we only need to follow one of the build instructions in the Android demo app README. :-)
# cd /tensorflow
# bazel build -c opt
--local_resources 4096,4.0,1.0 -j 1//tensorflow/examples/android:tensorflow_demo
This step takes around 30 minutes on a MacBook Pro (3.1 GHz, 16GB RAM).
Reminder: don’t exit your Docker container yet! Leave your Terminal/Command Prompt open so you can run more commands inside the Docker container later if you want to.
Testing the APK
We need to copy our freshly built APK out of our Docker container and onto our local machine, otherwise we have no way of using it.
With the Docker container still running in a separate window, open a new Terminal/Command Prompt window on your local machine, and grab the Docker container ID. We generally only ever want to run the
docker command from our local machine (more Docker tips here). :-)
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS 68f8994d3b19 <image>:<version> "/bin/bash" 7 hours ago Up 7 hours
Tip: In this tutorial, commands to run in your Docker container with
#, whereas the commands to run on your local machine do not.
Now copy the file out from the container to your local machine. Change
/tmp/ to be the folder on your local machine that you want the APK to be copied into (e.g.
$HOME or wherever).
$ docker cp 68f8994d3b19:/tensorflow/bazel-bin/tensorflow/examples/android/tensorflow_demo.apk /tmp/
Now install the APK on your device. If you have adb installed, this is the quickest way:
$ adb install -r /tmp/tensorflow_demo.apk
The updated demo app will now have your custom background color!
Now that we are able to build TensorFlow and the Android demo app, you can move onto part 3 to learn how retrain a TensorFlow model and use it in an Android app!