Tutorial on running keras model in C++ and python tensorflow
MIT License
So youve built an awesome machine learning model in Keras and now you want to run it natively through Tensorflow. This tutorial will show you how.
Keras is a wonderful high level framework for building machine learning models. It is able to utilize multiple backends such as Tensorflow or Theano to do so. When a keras model is saved via the .save method, the canonical save method serializes to an HDF5 format. Tensorflow works with Protocol Buffers, and therefore loads and saves .pb files. This tutorial demonstrates how to:
I am conducting this tutorial on macOS and Linux, using Tensorflow version 1.10 and Keras version 2.1.5 .
So we suppose you cloned this repository and you accessed it
https://github.com/Aazhar/keras2tensorflow && cd keras2tensorflow
In this tutorial we use the flowers classification data from the Tensorflow examples. Its about 218 MB, it's already included in this repository (downloaded from http://download.tensorflow.org/example_images/flower_photos.tgz).
A simple CNN as an example, however the techniques to port the models work equally well with the built-in Keras models such as Inception and ResNet. I have no illusions that this model will win any awards, but it will serve our purpose.
Few things to note from the code listed below:
see k2tf_trainer.py .
No train the model:
python k2tf_trainer.py --test=./data/flowers/raw-data/validation --train=./data/flowers/raw-data/train --cats=5 --shape=80 --batch=120 --epochs=400 --output=./temp
A few runs of this yielded val_acc in the 83-86% range, and while its no Inception, its good enough for this exercise.
Lets just do a quick gut-check on our model heres a small script to load your model, image, shape and indices (especially if you didnt use the flowers set) , see k2tf_eval.py.
Run the test :
python k2tf_eval.py -m '/home/work/keras2tensorflow/temp/k2tf-20181025175144/e-075-vl-0.481-va-0.837.h5' -i './data/flowers/raw-data/validation/dandelion/13920113_f03e867ea7_m.jpg' -s 80
Attribution: This script was adapted from https://github.com/amir-abdi/keras_to_tensorflow.
Adaptation were made from the link above to a script we can run from the command line. The code is almost identical except for the argument parsing. This code does the following:
And now lets run this little guy on our trained model.
python k2tf_convert.py -m '/home/work/keras2tensorflow/temp/k2tf-20181025175144/e-075-vl-0.481-va-0.837.h5' -n 1
As you can see, two files were written out. An ASCII and .pb file. Have a look at the graph structure, notice the input node name firstConv2D_input and the output name k2tfout_0, , we will use those in the next section.
We need to supply the following arguments to run the Python script :
python label_image.py --graph=./output_graph.pb --labels=./data/flowers/raw-data/labels.txt --input_width=80 --input_height=80 --input_layer=firstConv2D_input --output_layer=k2tfout_0 --image=./data/flowers/raw-data/validation/dandelion/13920113_f03e867ea7_m.jpg
To run our models in C++ we first need to obtain the Tensorflow source tree. The instructions are here, but well walk through them below.
Install all dependencies
git clone https://github.com/tensorflow/tensorflow && cd tensorflow/ && git checkout r1.10 && ls
You can install all dependencies using :
python tensorflow/tools/pip_package/setup.py install
On Linux or Mac Tensorflow uses Bazel as build tool, Windows uses CMake.
After installing bazel :
./configure
So here you can just skip all of suggested extensions.
Looking through the bazel BUILD files to find targets you will find the right target, and you can build the C++ extension using :
bazel build --jobs=6 --verbose_failures //tensorflow:libtensorflow_cc.so
(Up to you to choose the correct number of jobs before going to take a nap while it's compiling)
Once it's done, you should end up with bazel-bin/tensorflow/libtensorflow_cc.so, you need to copy them then, either to common lib directory or current one :
cd .. & cp -R tensorflow/bazel-bin/tensorflow/libtensorflow_* ./
If you have cmake, there is a CMakeList file that links the .so and all of the required header locations. Im including it for reference you DO NOT need cmake to build this. In fact, the g++ commands are provided to build.
g++ -c -pipe -g -std=gnu++11 -Wall -W -fPIC -I. -I./tensorflow -I./tensorflow/bazel-tensorflow/external/eigen_archive -I./tensorflow/bazel-tensorflow/external/protobuf_archive/src -I./tensorflow/bazel-genfiles -o main.o ./main.cpp
g++ -o k2tf main.o -ltensorflow_cc -ltensorflow_framework
Now you should have an executable in your directory and we can test our application:
./k2tf --graph=./output_graph.pb --labels=./data/flowers/raw-data/labels.txt --input_width=80 --input_height=80 --input_layer=firstConv2D_input --output_layer=k2tfout_0 --image=./data/flowers/raw-data/validation/dandelion/13920113_f03e867ea7_m.jpg
I hope this was useful.
Special attribution to bitbionic.