Install TensorFlow 2.1.0 on Raspberry Pi 4 - Q-engineering
Q-engineering
Q-engineering
Go to content
images/empty-GT_imagea-1-.png
TensorFlow on Raspberry Pi

Install TensorFlow 2.1.0 on Raspberry Pi 4

TensorFlow 1.15.2
32-OS TensorFlow 2.2.0
64-OS TensorFlow 2.2.0

Introduction.

This article will help you install TensorFlow 2.1.0 on Raspberry Pi 4 with a 32-bit operation system. We discuss two installations, one for Python 3 and one C++ API library. This manual is written for the Raspberry Pi 4. It can be used for the Raspberry 3 B +, but we don't encourage the idea given the computing power of the Raspberry Pi 3. TensorFlow occupies about 1 GByte on your SD-microcard. Unfortunately, there is no official pip3 wheel available for the 2.1.0 version. However, we created our wheel with Bazel and put it on GitHub for your convenience.

TensorFlow is a large software library specially developed for deep learning. It consumes a vast amount of resources. You can execute TensorFlow on a Raspberry Pi 4, but don't expect miracles. It can run your models, if not too complex, but it will not be able to train new models. Nor can it perform the so-called transfer learning. In addition to running your pre-built deep learning models, you may use the library to convert so-called frozen TensorFlow models to TensorFlow Lite flat buffer models.

If you only want to get some impression of deep learning, please consider installing TensorFlow Lite. It is much faster and uses far fewer recourses, as being designed for small computers like a Raspberry Pi. There are many ready build models you can use. See our installation guide here.

Recently there are some issues with an atomic library on the Raspberry Pi. Although available, the Raspbian operation system will only use this library when forced to do by the LD_PRELOAD trick. The latest OpenCV version but also the later TensorFlow versions depend on this library. When not found it generates undefined symbol: __atomic_fetch_add_8 errors. Our procedure will incorporate the atomic library during the build so no errors are to be expected.

The shortcut.

TensorFlow is installed by a Google software installer called Bazel. In the end, Bazel generates a wheel to install the TensorFlow Python version or a tarball when it comes to installing the C++ version. Both methods are well known to Raspberry Pi users. We have posted the Bazel outcomes on our GitHub page. Feel free to use these shortcuts. The whole TensorFlow installation procedure from start to end takes many hours (±19 for Python, ±8 for the C++ library). With all the tedious work already done, it takes twenty minutes to install TensorFlow 2.1.0 on your Raspberry Pi 4. For the diehards, the complete procedure is covered later in this manual.
TensorFlow 2.1.0 for Python 3.
The whole shortcut procedure is found below. Please make sure you have latest pip3 and python3 version installed, otherwise, pip may comes with the message ".whl is not a supported wheel on this platform".
# get a fresh start
$ sudo apt-get update
$ sudo apt-get upgrade
# remove old versions, if not placed in a virtual environment (let pip search for them)
$ sudo pip uninstall tensorflow
$ sudo pip3 uninstall tensorflow
# install the dependencies (if not already onboard)
$ sudo apt-get install gfortran
$ sudo apt-get install libhdf5-dev libc-ares-dev libeigen3-dev
$ sudo apt-get install libatlas-base-dev libopenblas-dev libblas-dev
$ sudo apt-get install liblapack-dev cython
$ sudo pip3 install pybind11
$ sudo pip3 install h5py
# download the wheel
$ wget https://github.com/Qengineering/Tensorflow-Raspberry-Pi/raw/master/tensorflow-2.1.0-cp37-cp37m-linux_armv7l.whl
# install TensorFlow
$ sudo -H pip3 install tensorflow-2.1.0-cp37-cp37m-linux_armv7l.whl
# and complete the installation by rebooting
$ reboot
When the installation is succesful, you should get the following screendump.

TensorFlow 2.1.0 succes
TensorFlow 2.1.0 C++ API.
If you are planning to program in C++, you will  need the C++ API build of TensorFlow instead of the Python version. Installing the C ++ library using the pre-build tarball from our GitHub page saves you a lot of time. Please follow the procedure below.
# get a fresh start
$ sudo apt-get update
$ sudo apt-get upgrade
# remove old versions (if found)
$ sudo rm -r /usr/local/lib/libtensorflow*
$ sudo rm -r /usr/local/include/tensorflow
# the dependencies
$ sudo apt-get install wget curl libhdf5-dev libc-ares-dev libeigen3-dev 
$ sudo apt-get install libatomic1 libatlas-base-dev zip unzip
# download the tarball
$ wget https://github.com/Qengineering/Tensorflow-Raspberry-Pi/raw/master/libtensorflow_2_1_0.tar.gz
# unpack the ball
$ sudo tar -C /usr/local -xzf libtensorflow_2_1_0.tar.gz
# and finish by rebooting
$ reboot
You should end up having your TensorFlow library installed at the /usr/local/lib location and the header files in the folder usr/local/include/tensorflow/c.

TensorFlow API succes



Installation from scratch

Swap space.

If you decide to install TensorFlow from scratch, there are two things to consider.
First, the procedure uses additional software and generates a lot of intermediate files. In the end, it takes about an extra 8 Gbyte on your SD-card.
Second, it will take many hours. So grab a cup of coffee and a good book once the process starts.

Before we can start the actual build, the memory swap space needs to be enlarged. For daily use a swap memory of 100 Mbyte is sufficient. However, with the massive build ahead of use, extra memory space is crucial, just like when we installed OpenCV. Enlarge the swap space with the following command.
$ sudo nano /etc/dphys-swapfile
This command loads the system file dphys-swapfile in Nano, a very lightweight text editor. Move the cursor with the arrow keys to the CONF_SWAPSIZE line where the new value 2048 can be entered. Next, close the session with the <Ctrl+X> key combination. With <Y> and <Enter> changes are being saved in the same file.
Two additional commands are required before the new enlarge swap space is active.
$ sudo /etc/init.d/dphys-swapfile stop
$ sudo /etc/init.d/dphys-swapfile start

Bazel.


Bazel is a free software tool from Google used for automatically building and testing software packages. You could compare it to CMake used by OpenCV, but the latter only builds software and has no test facility. Bazel is written in Java, a platform-independent language, largely based on C ++ in terms of syntax. To compile Bazel, we must first install Java and some other dependencies with the following commands.
# get a fresh start
$ sudo apt-get update
$ sudo apt-get upgrade
# install some tools
$ sudo apt-get install build-essential zip unzip
# install Java
$ sudo apt-get install openjdk-8-jdk
Next, we can download and unzip the Bazel software. We need Bazel release 0.29.1 for TensorFlow 2.1.0, so be sure you install the right version.
$ wget https://github.com/bazelbuild/bazel/releases/download/0.29.1/bazel-0.29.1-dist.zip
$ unzip -d bazel bazel-0.29.1-dist.zip
$ cd bazel
During installation, Bazel uses a predefined ratio of the available working memory. This ratio is too small due to the limited size of the RAM of the RaspBerry Pi. To prevent crashes, we must to increase the size of this memory to a minimum 800 Mbyte during the procedure. This is done by adding some extra information to the script file compile.sh. You can add the text -J-Xmx800M to the line that begins with run..(around line 132). See the screen below. Use the well-known <Ctrl + X>, <Y>, <Enter> to save the change (see the slide show above).
$ nano scripts/bootstrap/compile.sh -c
Bazel 800 Mb heap

Once the Java environment for Bazil has been maximized to 800 Mb, you can start building the Bazel software with the next commands. When finished, copy the binary file to the /usr/local/bin location so that bash can find the executable anywhere. The final action is to delete the zip file. The total build takes about 33 minutes.
# start the build
$ env EXTRA_BAZEL_ARGS="--host_javabase=@local_jdk//:jdk" bash ./compile.sh
# copy the binary
$ sudo cp output/bazel /usr/local/bin/bazel
# clean up
$ cd ~
$ rm bazel-0.29.1-dist.zip
Bazel succes


Install TensorFlow 2.1.0 for Python 3.

With Bazel up and running we can start building TensorFlow 2.1.0 on our Raspberry PI 4 for Python 3. It is almost becoming standard practice. First, install some dependencies, then download the zip from GitHub and finally unpack the software.
# the dependencies
$ sudo apt-get install build-essential make cmake wget zip unzip
$ sudo apt-get install libhdf5-dev libc-ares-dev libeigen3-dev
$ sudo apt-get install libatomic1 libatlas-base-dev
$ sudo pip3 install keras_applications==1.0.8 --no-deps
$ sudo pip3 install keras_preprocessing==1.1.0 --no-deps
$ sudo pip3 install h5py==2.10.0
# download TensorFlow 2.1.0
$ wget -O tensorflow.zip https://github.com/tensorflow/tensorflow/archive/v2.1.0.zip
# unpack and give the folder a convenient name
$ unzip tensorflow.zip
$ mv tensorflow-2.1.0 tf
The final step before building the Python 3 installation wheel is to configure Bazel. This is done by a script file and the command-line options. Let's start with the script file. With the following command, Bazel asks you a few questions. Most important, define Python 3 as default Python version. Python 2 generates a lot of missing dependencies errors. Give 'no' to all other questions.
$ cd tf
$ ./configure
pi@raspberrypi:~/tf $ ./configure
Extracting Bazel installation...
WARNING: --batch mode is deprecated. Please instead explicitly shut down your Bazel server using the command "bazel shutdown".
You have bazel 0.26.1- (@non-git) installed.
Please specify the location of python. [Default is /usr/bin/python]: /usr/bin/python3

Found possible Python library paths:
 /usr/local/lib/python3.7/dist-packages
 /usr/lib/python3/dist-packages
Please input the desired Python library path to use.  Default is [/usr/local/lib/python3.7/dist-packages] <enter>

Do you wish to build TensorFlow with XLA JIT support? [Y/n]: n
No XLA JIT support will be enabled for TensorFlow.

Do you wish to build TensorFlow with OpenCL SYCL support? [y/N]: n
No OpenCL SYCL support will be enabled for TensorFlow.

Do you wish to build TensorFlow with ROCm support? [y/N]: n
No ROCm support will be enabled for TensorFlow.

Do you wish to build TensorFlow with CUDA support? [y/N]: n
No CUDA support will be enabled for TensorFlow.

Do you wish to download a fresh release of clang? (Experimental) [y/N]: n
Clang will not be downloaded.

Do you wish to build TensorFlow with MPI support? [y/N]: n
No MPI support will be enabled for TensorFlow.

Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -march=native -Wno-sign-compare]: <enter>

Would you like to interactively configure ./WORKSPACE for Android builds? [y/N]: n
Not configuring the WORKSPACE for Android builds.

Preconfigured Bazel build configs. You can use any of the below by adding "--config=<>" to your build command. See .bazelrc for more details.
--config=mkl          # Build with MKL support.
--config=monolithic   # Config for mostly static monolithic build.
--config=gdr          # Build with GDR support.
--config=verbs        # Build with libverbs support.
--config=ngraph       # Build with Intel nGraph support.
--config=numa         # Build with NUMA support.
--config=dynamic_kernels # (Experimental) Build kernels into separate shared objects.
--config=v2           # Build TensorFlow 2.x instead of 1.x.  <---
Preconfigured Bazel build configs to DISABLE default on features:
--config=noaws        # Disable AWS S3 filesystem support.
--config=nogcp        # Disable GCP support.
--config=nohdfs       # Disable HDFS support.
--config=noignite     # Disable Apache Ignite support.
--config=nokafka      # Disable Apache Kafka support.
--config=nonccl       # Disable NVIDIA NCCL support.
Configuration finished
With the script file all set and done, the massive build can start with the command below. The -Xmx1624m sets the memory size of the Java environment where Bazel runs. Give it as much space as possible. We advise 80% of your Raspberry Pi memory size. In our case we have 2 Gbyte onboard, so 1624 Mbyte leaves just enough space for other threads apart from Bazel.
Another point is the number of cores Bazel uses. With more than two, Bazel will certainly crash due to intensive memory swapping. Even with two, you get considerable delays when both CPU-cores are queuing for swap space. We always use just one core. Better a bit slower than a crash and starting all over again.
Close all other applications during the build. If you use VNC, close it as well. The less other processes are running, the faster your compilation will be.
$ sudo bazel --host_jvm_args=-Xmx1624m build \
             --config=noaws \
             --config=nogcp \
             --config=nohdfs \
             --config=nonccl \
             --config=monolithic \
             --config=v2 \
             --local_cpu_resources=1 \
             --copt=-mfpu=neon-vfpv4 \
             --copt=-ftree-vectorize \
             --copt=-funsafe-math-optimizations \
             --copt=-ftree-loop-vectorize \
             --copt=-fomit-frame-pointer \
             --copt=-DRASPBERRY_PI \
             --host_copt=-DRASPBERRY_PI \
             --linkopt=-Wl,-latomic \
             --host_linkopt=-Wl,-latomic \
             //tensorflow/tools/pip_package:build_pip_package

After 18 hours compilation, hopefully, you will see with the following screen.



Now we have to generate the wheel and install it. This is done by the commands below.
A few words about the installation of scipy. TensorFlow 2.1.0 uses scipy version 1.14.1. It is known to be problematic to install this version on a Raspberry Pi, due to the lack of a proper wheel. Some may install scipy from source. However, if you install the dependencies of scipy first, your newly created TensorFlow wheel will install scipy 1.14.1 correctly in the end. These dependencies are marked in light blue. By the way, this installation takes about half an hour to complete.
# synthesize the wheel
$ sudo bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
# install some dependencies (if not already done)
$ sudo apt-get install libatlas3-base libopenblas-dev libopenblas-base libblas-dev
$ sudo apt-get install gcc gfortran python3-dev libgfortran5
$ sudo apt-get install liblapack-dev cython
$ sudo pip3 install pybind11
$ sudo pip3 install -U --user six wheel mock
# get to the folder where the wheel is located and install tensowflow
$ cd /tmp/tensorflow_pkg
$ sudo pip3 install tensorflow-2.1.0-cp37-cp37m-linux_armv7l.whl
If you are not planning to install the C++ API next, your last action of the installation will be restoring the swap space to its initial value.
$ sudo nano /etc/dphys-swapfile

set CONF_SWAPSIZE=100 with the Nano text editor

$ sudo reboot

Install the TensorFlow 2.1.0 C++ API.
As mentioned earlier, you can install the TensorFlow 2.1.0 C++ API very quickly by using the tarball on our GitHub page; no need to go through lengthy installation procedures. For those who want to build the API themselves, the installation guide now follows.
First, make sure your swap space is at least 2048 Mbyte. The value can be set in the /etc/dphys-swap file, as explained at the beginning of this page.
Next, install Bazel if not already done. The procedure is also descript above. Once Bazel is working, you can install the dependencies and download TensorFlow 2.1.0, if not already done for the Python 3 installation of TensorFlow.
# the dependencies
$ sudo apt-get install build-essential make cmake wget zip unzip
$ sudo apt-get install libhdf5-dev libc-ares-dev libeigen3-dev
$ sudo apt-get install libatomic1 libatlas-base-dev
# download TensorFlow 2.1.0
$ wget -O tensorflow.zip https://github.com/tensorflow/tensorflow/archive/v2.1.0.zip
# unpack and give the folder a convenient name
$ unzip tensorflow.zip
$ mv tensorflow-2.1.0 tf
Again, we need to configure Bazel before the actual build can start. Despite we are going to build a C++ API, the Bazel script file needs to be set to Python 3 as default Python version. Python 2 still generates a lot of missing dependencies errors. Give 'no' to all other questions.
$ cd tf
$ ./configure
Once all the questions of the script file are answered, you end up with the same output screen as shown above.
The last step is the command line with its options. Again, almost identical to the one earlier used. Most important here is the --config=monolithic flag. Without this direction, TensorFlow will not work with OpenCV or visa versa. Just like the pip compilation, the memory for Java environment (-Xmx1624m) has to be maximized to 80% of the memory the Raspberry Pi has onboard. The last line indicates a tarball library build instead of a pip wheel.
$ sudo bazel --host_jvm_args=-Xmx1624m build \
             --config=noaws \
             --config=nogcp \
             --config=nohdfs \
             --config=nonccl \
             --config=monolithic \
             --config=v2 \
             --local_cpu_resources=1 \
             --copt=-mfpu=neon-vfpv4 \
             --copt=-ftree-vectorize \
             --copt=-funsafe-math-optimizations \
             --copt=-ftree-loop-vectorize \
             --copt=-fomit-frame-pointer \
             --copt=-DRASPBERRY_PI \
             --host_copt=-DRASPBERRY_PI \
             --linkopt=-Wl,-latomic \
             --host_linkopt=-Wl,-latomic \
             //tensorflow/tools/lib_package:libtensorflow

After a long 9 hours wait, hopefully, you will see with the following screen.

TF succes 2_1_0

The last step is installing the tarball. This is done by the command below.
$ sudo tar -C /usr/local -xzf bazel-bin/tensorflow/tools/lib_package/libtensorflow.tar.gz
Once installed you must have the same folders (/usr/local/lib and usr/local/include/tensorflow/c) as shown at the beginning of this page.
The last step resetting the swap space to its default value of 100.
$ sudo nano /etc/dphys-swapfile

set CONF_SWAPSIZE=100 with the Nano text editor

$ sudo reboot
Deep learning examples for Raspberry Pi
Raspberry and alt
Install 32 OS
Raspberry Pi 4
Install 64 OS
Back to content