{"id":1376,"date":"2016-11-18T10:50:38","date_gmt":"2016-11-18T02:50:38","guid":{"rendered":"https:\/\/www.strongd.net\/?p=1376"},"modified":"2016-11-18T10:50:38","modified_gmt":"2016-11-18T02:50:38","slug":"building-tensorflow-for-raspberry-pi-a-step-by-step-guide","status":"publish","type":"post","link":"https:\/\/www.strongd.net\/?p=1376","title":{"rendered":"Building TensorFlow for Raspberry Pi: a Step-By-Step Guide"},"content":{"rendered":"<h2>What You Need<\/h2>\n<ul>\n<li>Raspberry Pi 2 or 3 Model B<\/li>\n<li>An SD card running Raspbian with several GB of free space\n<ul>\n<li>An 8 GB card with a fresh install of Raspbian <strong>does not<\/strong> have enough space. A 16 GB SD card minimum is recommended.<\/li>\n<li>These instructions may work on Linux distributions other than Raspbian<\/li>\n<\/ul>\n<\/li>\n<li>Internet connection to the Raspberry Pi<\/li>\n<li>A USB memory drive that can be installed as swap memory (if it is a flash drive, make sure you don&#8217;t care about the drive). Anything over 1 GB should be fine<\/li>\n<li>A fair amount of time<\/li>\n<\/ul>\n<h2><a id=\"user-content-overview\" class=\"anchor\" href=\"https:\/\/github.com\/samjabrahams\/tensorflow-on-raspberry-pi\/blob\/master\/GUIDE.md#overview\"><\/a>Overview<\/h2>\n<p>These instructions were crafted for a <a href=\"https:\/\/www.raspberrypi.org\/products\/raspberry-pi-3-model-b\/\">Raspberry Pi 3 Model B<\/a> running a vanilla copy of Raspbian 8.0 (jessie). It appears to work on Raspberry Pi 2, but <a href=\"https:\/\/github.com\/tensorflow\/tensorflow\/issues\/445#issuecomment-196021885\">there are some kinks that are being worked out<\/a>. If these instructions work for different distributions, let me know!<\/p>\n<p>Here&#8217;s the basic plan: build a 32-bit version of <a href=\"https:\/\/github.com\/google\/protobuf\">Protobuf<\/a>, use that to build a RPi-friendly version of <a href=\"https:\/\/github.com\/bazelbuild\/bazel\">Bazel<\/a>, and finally use Bazel to build TensorFlow.<\/p>\n<h2>The Build<\/h2>\n<h3><a id=\"user-content-1-install-basic-dependencies\" class=\"anchor\" href=\"https:\/\/github.com\/samjabrahams\/tensorflow-on-raspberry-pi\/blob\/master\/GUIDE.md#1-install-basic-dependencies\"><\/a>1. Install basic dependencies<\/h3>\n<p>First, update apt-get to make sure it knows where to download everything.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>sudo apt-get update<\/pre>\n<\/div>\n<p>Next, install some base dependencies and tools we&#8217;ll need later.<\/p>\n<p>For Protobuf:<\/p>\n<pre><code>sudo apt-get install autoconf automake libtool maven\r\n<\/code><\/pre>\n<p>For gRPC:<\/p>\n<pre><code>sudo apt-get install oracle-java7-jdk\r\n# Select the jdk-7-oracle option for the update-alternatives command\r\nsudo update-alternatives --config java\r\n<\/code><\/pre>\n<p>For Bazel:<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>sudo apt-get install pkg-config zip g++ zlib1g-dev unzip<\/pre>\n<\/div>\n<p>For TensorFlow:<\/p>\n<pre><code># For Python 2.7\r\nsudo apt-get install python-pip python-numpy swig python-dev\r\nsudo pip install wheel\r\n\r\n# For Python 3.3+\r\nsudo apt-get install python3-pip python3-numpy swig python3-dev\r\nsudo pip3 install wheel\r\n<\/code><\/pre>\n<p>To be able to take advantage of certain optimization flags:<\/p>\n<pre><code>sudo apt-get install gcc-4.8 g++-4.8\r\nsudo update-alternatives --install \/usr\/bin\/gcc gcc \/usr\/bin\/gcc-4.8 100\r\nsudo update-alternatives --install \/usr\/bin\/g++ g++ \/usr\/bin\/g++-4.8 100\r\n<\/code><\/pre>\n<p>Finally, for cleanliness, make a directory that will hold the Protobuf, Bazel, and TensorFlow repositories.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>mkdir tf\r\n<span class=\"pl-c1\">cd<\/span> tf<\/pre>\n<\/div>\n<h3><a id=\"user-content-2-build-protobuf\" class=\"anchor\" href=\"https:\/\/github.com\/samjabrahams\/tensorflow-on-raspberry-pi\/blob\/master\/GUIDE.md#2-build-protobuf\"><\/a>2. Build Protobuf<\/h3>\n<p>Clone the Protobuf repository.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>git clone https:\/\/github.com\/google\/protobuf.git<\/pre>\n<\/div>\n<p>Now move into the new <code>protobuf<\/code> directory, configure it, and <code>make<\/code> it. <em>Note: this takes a little while.<\/em><\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre><span class=\"pl-c1\">cd<\/span> protobuf\r\ngit checkout v3.0.0-beta-3.3\r\n.\/autogen.sh\r\n.\/configure --prefix=\/usr\r\nmake -j 4\r\nsudo make install<\/pre>\n<\/div>\n<p>Once it&#8217;s made, we can move into the <code>java<\/code> directory and use Maven to build the project.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre><span class=\"pl-c1\">cd<\/span> java\r\nmvn package<\/pre>\n<\/div>\n<p>After following these steps, you&#8217;ll have two spiffy new files: <code>\/usr\/bin\/protoc<\/code> and <code>protobuf\/java\/core\/target\/protobuf-java-3.0.0-beta3.jar<\/code><\/p>\n<h3><a id=\"user-content-3-build-grpc\" class=\"anchor\" href=\"https:\/\/github.com\/samjabrahams\/tensorflow-on-raspberry-pi\/blob\/master\/GUIDE.md#3-build-grpc\"><\/a>3. Build gRPC<\/h3>\n<p>Next, we need to build <a href=\"https:\/\/github.com\/grpc\/grpc-java\">gRPC-Java<\/a>, the Java implementation of <a href=\"http:\/\/www.grpc.io\/\">gRPC<\/a>. Move out of the <code>protobuf\/java<\/code> directory and clone gRPC&#8217;s repository.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre><span class=\"pl-c1\">cd<\/span> ..\/..\r\ngit clone https:\/\/github.com\/grpc\/grpc-java.git<\/pre>\n<\/div>\n<div class=\"highlight highlight-source-shell\">\n<pre><span class=\"pl-c1\">cd<\/span> grpc-java\r\ngit checkout v0.14.1<\/pre>\n<\/div>\n<div class=\"highlight highlight-source-shell\">\n<pre><span class=\"pl-c1\">cd<\/span> compiler\r\nnano build.gradle<\/pre>\n<\/div>\n<p>Around line 47:<\/p>\n<pre><code>gcc(Gcc) {\r\n    target(\"linux_arm-v7\") {\r\n        cppCompiler.executable = \"\/usr\/bin\/gcc\"\r\n    }\r\n}\r\n<\/code><\/pre>\n<p>Around line 60, add section for <code>'linux_arm-v7'<\/code>:<\/p>\n<pre><code>...\r\n    x86_64 {\r\n        architecture \"x86_64\"\r\n    }\r\n    'linux_arm-v7' {\r\n        architecture \"arm32\"\r\n        operatingSystem \"linux\"\r\n    }\r\n<\/code><\/pre>\n<p>Around line 64, add <code>'arm32'<\/code> to list of architectures:<\/p>\n<pre><code>...\r\ncomponents {\r\n    java_plugin(NativeExecutableSpec) {\r\n            if (arch in ['x86_32', 'x86_64', 'arm32'])\r\n...\r\n<\/code><\/pre>\n<p>Around line 148, replace content inside of <code>protoc<\/code> section to hard code path to <code>protoc<\/code> binary:<\/p>\n<pre><code>protoc {\r\n    path = '\/usr\/bin\/protoc'\r\n}\r\n<\/code><\/pre>\n<p>Once all of that is taken care of, run this command to build gRPC:<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>..\/gradlew java_pluginExecutable<\/pre>\n<\/div>\n<h3><a id=\"user-content-4-build-bazel\" class=\"anchor\" href=\"https:\/\/github.com\/samjabrahams\/tensorflow-on-raspberry-pi\/blob\/master\/GUIDE.md#4-build-bazel\"><\/a>4. Build Bazel<\/h3>\n<p>First, move out of the <code>grpc-java\/compiler<\/code> directory and clone Bazel&#8217;s repository.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre><span class=\"pl-c1\">cd<\/span> ..\/..\r\ngit clone https:\/\/github.com\/bazelbuild\/bazel.git<\/pre>\n<\/div>\n<p>Next, go into the new <code>bazel<\/code> directory and immediately checkout version 0.3.1 of Bazel.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre><span class=\"pl-c1\">cd<\/span> bazel\r\ngit checkout 0.3.2<\/pre>\n<\/div>\n<p>After that, copy the generated Protobuf and gRPC files we created earlier into the Bazel project. Note the naming of the files in this step- it must be precise.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>sudo cp \/usr\/bin\/protoc third_party\/protobuf\/protoc-linux-arm32.exe\r\nsudo cp ..\/protobuf\/java\/core\/target\/protobuf-java-3.0.0-beta-3.jar third_party\/protobuf\/protobuf-java-3.0.0-beta-1.jar\r\nsudo cp ..\/grpc-java\/compiler\/build\/exe\/java_plugin\/protoc-gen-grpc-java third_party\/grpc\/protoc-gen-grpc-java-0.15.0-linux-x86_32.exe<\/pre>\n<\/div>\n<p>Before building Bazel, we need to set the <code>javac<\/code> maximum heap size for this job, or else we&#8217;ll get an OutOfMemoryError. To do this, we need to make a small addition to <code>bazel\/scripts\/bootstrap\/compile.sh<\/code>. (Shout-out to @SangManLINUX for <a href=\"https:\/\/github.com\/samjabrahams\/tensorflow-on-raspberry-pi\/issues\/5#issuecomment-210965695\">pointing this out.<\/a>.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>nano scripts\/bootstrap\/compile.sh<\/pre>\n<\/div>\n<p>Around line 46, you&#8217;ll find this code:<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre><span class=\"pl-k\">if<\/span> [ <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span><span class=\"pl-smi\">${MACHINE_IS_64BIT}<\/span><span class=\"pl-pds\">\"<\/span><\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>yes<span class=\"pl-pds\">'<\/span><\/span> ]<span class=\"pl-k\">;<\/span> <span class=\"pl-k\">then<\/span>\r\n    PROTOC=<span class=\"pl-smi\">${PROTOC<span class=\"pl-k\">:-<\/span>third_party<span class=\"pl-k\">\/<\/span>protobuf<span class=\"pl-k\">\/<\/span>protoc-linux-x86_64.exe}<\/span>\r\n    GRPC_JAVA_PLUGIN=<span class=\"pl-smi\">${GRPC_JAVA_PLUGIN<span class=\"pl-k\">:-<\/span>third_party<span class=\"pl-k\">\/<\/span>grpc<span class=\"pl-k\">\/<\/span>protoc-gen-grpc-java-0.15.0-linux-x86_64.exe}<\/span>\r\n<span class=\"pl-k\">else<\/span>\r\n    <span class=\"pl-k\">if<\/span> [ <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span><span class=\"pl-smi\">${MACHINE_IS_ARM}<\/span><span class=\"pl-pds\">\"<\/span><\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>yes<span class=\"pl-pds\">'<\/span><\/span> ]<span class=\"pl-k\">;<\/span> <span class=\"pl-k\">then<\/span>\r\n        PROTOC=<span class=\"pl-smi\">${PROTOC<span class=\"pl-k\">:-<\/span>third_party<span class=\"pl-k\">\/<\/span>protobuf<span class=\"pl-k\">\/<\/span>protoc-linux-arm32.exe}<\/span>\r\n    <span class=\"pl-k\">else<\/span>\r\n        PROTOC=<span class=\"pl-smi\">${PROTOC<span class=\"pl-k\">:-<\/span>third_party<span class=\"pl-k\">\/<\/span>protobuf<span class=\"pl-k\">\/<\/span>protoc-linux-x86_32.exe}<\/span>\r\n        GRPC_JAVA_PLUGIN=<span class=\"pl-smi\">${GRPC_JAVA_PLUGIN<span class=\"pl-k\">:-<\/span>third_party<span class=\"pl-k\">\/<\/span>grpc<span class=\"pl-k\">\/<\/span>protoc-gen-grpc-java-0.15.0-linux-x86_32.exe}<\/span>\r\n    <span class=\"pl-k\">fi<\/span>\r\n<span class=\"pl-k\">fi<\/span><\/pre>\n<\/div>\n<p>Change it to the following:<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre><span class=\"pl-k\">if<\/span> [ <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span><span class=\"pl-smi\">${MACHINE_IS_64BIT}<\/span><span class=\"pl-pds\">\"<\/span><\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>yes<span class=\"pl-pds\">'<\/span><\/span> ]<span class=\"pl-k\">;<\/span> <span class=\"pl-k\">then<\/span>\r\n    PROTOC=<span class=\"pl-smi\">${PROTOC<span class=\"pl-k\">:-<\/span>third_party<span class=\"pl-k\">\/<\/span>protobuf<span class=\"pl-k\">\/<\/span>protoc-linux-x86_64.exe}<\/span>\r\n    GRPC_JAVA_PLUGIN=<span class=\"pl-smi\">${GRPC_JAVA_PLUGIN<span class=\"pl-k\">:-<\/span>third_party<span class=\"pl-k\">\/<\/span>grpc<span class=\"pl-k\">\/<\/span>protoc-gen-grpc-java-0.15.0-linux-x86_64.exe}<\/span>\r\n<span class=\"pl-k\">else<\/span>\r\n    PROTOC=<span class=\"pl-smi\">${PROTOC<span class=\"pl-k\">:-<\/span>third_party<span class=\"pl-k\">\/<\/span>protobuf<span class=\"pl-k\">\/<\/span>protoc-linux-arm32.exe}<\/span>\r\n    GRPC_JAVA_PLUGIN=<span class=\"pl-smi\">${GRPC_JAVA_PLUGIN<span class=\"pl-k\">:-<\/span>third_party<span class=\"pl-k\">\/<\/span>grpc<span class=\"pl-k\">\/<\/span>protoc-gen-grpc-java-0.15.0-linux-linux-arm32.exe}<\/span>\r\n<span class=\"pl-k\">fi<\/span><\/pre>\n<\/div>\n<p>Move down to line 149, where you&#8217;ll see the following block of code:<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>run <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span><span class=\"pl-smi\">${JAVAC}<\/span><span class=\"pl-pds\">\"<\/span><\/span> -classpath <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span><span class=\"pl-smi\">${classpath}<\/span><span class=\"pl-pds\">\"<\/span><\/span> -sourcepath <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span><span class=\"pl-smi\">${sourcepath}<\/span><span class=\"pl-pds\">\"<\/span><\/span> \\\r\n      -d <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span><span class=\"pl-smi\">${output}<\/span>\/classes<span class=\"pl-pds\">\"<\/span><\/span> -source <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span><span class=\"pl-smi\">$JAVA_VERSION<\/span><span class=\"pl-pds\">\"<\/span><\/span> -target <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span><span class=\"pl-smi\">$JAVA_VERSION<\/span><span class=\"pl-pds\">\"<\/span><\/span> \\\r\n      -encoding UTF-8 <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>@<span class=\"pl-smi\">${paramfile}<\/span><span class=\"pl-pds\">\"<\/span><\/span><\/pre>\n<\/div>\n<p>At the end of this block, add in the <code>-J-Xmx500M<\/code> flag, which sets the maximum size of the Java heap to 500 MB:<\/p>\n<pre><code>run \"${JAVAC}\" -classpath \"${classpath}\" -sourcepath \"${sourcepath}\" \\\r\n      -d \"${output}\/classes\" -source \"$JAVA_VERSION\" -target \"$JAVA_VERSION\" \\\r\n      -encoding UTF-8 \"@${paramfile}\" -J-Xmx500M\r\n<\/code><\/pre>\n<p>Next up, we need to adjust <code>third_party\/protobuf\/BUILD<\/code> &#8211; open it up in your text editor.<\/p>\n<pre><code>nano third_party\/protobuf\/BUILD\r\n<\/code><\/pre>\n<p>We need to add this last line around line 29:<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>...\r\n    <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>\/\/third_party:freebsd<span class=\"pl-pds\">\"<\/span><\/span>: [<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>protoc-linux-x86_32.exe<span class=\"pl-pds\">\"<\/span><\/span>],\r\n    <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>\/\/third_party:arm<span class=\"pl-pds\">\"<\/span><\/span>: [<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>protoc-linux-arm32.exe<span class=\"pl-pds\">\"<\/span><\/span>],\r\n}),\r\n...<\/pre>\n<\/div>\n<p>Finally, we have to add one thing to <code>tools\/cpp\/cc_configure.bzl<\/code> &#8211; open it up for editing:<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>nano tools\/cpp\/cc_configure.bzl<\/pre>\n<\/div>\n<p>And place this in around line 141 (at the beginning of the <code>_get_cpu_value<\/code> function):<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>...\r\n<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span><span class=\"pl-pds\">\"<\/span><span class=\"pl-pds\">\"<\/span>Compute the cpu_value based on the OS name.<span class=\"pl-pds\">\"<\/span><span class=\"pl-pds\">\"<\/span><span class=\"pl-pds\">\"<\/span><\/span>\r\n<span class=\"pl-k\">return<\/span> <span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>arm<span class=\"pl-pds\">\"<\/span><\/span>\r\n...<\/pre>\n<\/div>\n<p>Now we can build Bazel! <em>Note: this also takes some time.<\/em><\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>sudo .\/compile.sh<\/pre>\n<\/div>\n<p>When the build finishes, you end up with a new binary, <code>output\/bazel<\/code>. Copy that to your <code>\/usr\/local\/bin<\/code> directory.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>sudo mkdir \/usr\/local\/bin\r\nsudo cp output\/bazel \/usr\/local\/bin\/bazel<\/pre>\n<\/div>\n<p>To make sure it&#8217;s working properly, run <code>bazel<\/code> on the command line and verify it prints help text. Note: this may take 15-30 seconds to run, so be patient!<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>$ bazel\r\n\r\nUsage: bazel <span class=\"pl-k\">&lt;<\/span><span class=\"pl-c1\">command<\/span><span class=\"pl-k\">&gt;<\/span> <span class=\"pl-k\">&lt;<\/span>options<span class=\"pl-k\">&gt;<\/span> ...\r\n\r\nAvailable commands:\r\n  analyze-profile     Analyzes build profile data.\r\n  build               Builds the specified targets.\r\n  canonicalize-flags  Canonicalizes a list of bazel options.\r\n  clean               Removes output files and optionally stops the server.\r\n  dump                Dumps the internal state of the bazel server process.\r\n  fetch               Fetches external repositories that are prerequisites to the targets.\r\n  <span class=\"pl-c1\">help<\/span>                Prints <span class=\"pl-c1\">help<\/span> <span class=\"pl-k\">for<\/span> commands, or the index.\r\n  info                Displays runtime info about the bazel server.\r\n  mobile-install      Installs targets to mobile devices.\r\n  query               Executes a dependency graph query.\r\n  run                 Runs the specified target.\r\n  shutdown            Stops the bazel server.\r\n  <span class=\"pl-c1\">test<\/span>                Builds and runs the specified <span class=\"pl-c1\">test<\/span> targets.\r\n  version             Prints version information <span class=\"pl-k\">for<\/span> bazel.\r\n\r\nGetting more <span class=\"pl-c1\">help<\/span>:\r\n  bazel <span class=\"pl-c1\">help<\/span> <span class=\"pl-k\">&lt;<\/span><span class=\"pl-c1\">command<\/span><span class=\"pl-k\">&gt;<\/span>\r\n                   Prints <span class=\"pl-c1\">help<\/span> and options <span class=\"pl-k\">for<\/span> <span class=\"pl-k\">&lt;<\/span><span class=\"pl-c1\">command<\/span><span class=\"pl-k\">&gt;<\/span>.\r\n  bazel <span class=\"pl-c1\">help<\/span> startup_options\r\n                   Options <span class=\"pl-k\">for<\/span> the JVM hosting bazel.\r\n  bazel <span class=\"pl-c1\">help<\/span> target-syntax\r\n                   Explains the syntax <span class=\"pl-k\">for<\/span> specifying targets.\r\n  bazel <span class=\"pl-c1\">help<\/span> info-keys\r\n                   Displays a list of keys used by the info <span class=\"pl-c1\">command<\/span>.<\/pre>\n<\/div>\n<p>Move out of the <code>bazel<\/code> directory, and we&#8217;ll move onto the next step.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre><span class=\"pl-c1\">cd<\/span> ..<\/pre>\n<\/div>\n<h3><a id=\"user-content-5-install-a-memory-drive-as-swap-for-compiling\" class=\"anchor\" href=\"https:\/\/github.com\/samjabrahams\/tensorflow-on-raspberry-pi\/blob\/master\/GUIDE.md#5-install-a-memory-drive-as-swap-for-compiling\"><\/a>5. Install a Memory Drive as Swap for Compiling<\/h3>\n<p>In order to succesfully build TensorFlow, your Raspberry Pi needs a little bit more memory to fall back on. Fortunately, this process is pretty straightforward. Grab a USB storage drive that has at least 1GB of memory. I used a flash drive I could live without that carried no important data. That said, we&#8217;re only going to be using the drive as swap while we compile, so this process shouldn&#8217;t do too much damage to a relatively new USB drive.<\/p>\n<p>First, put insert your USB drive, and find the <code>\/dev\/XXX<\/code> path for the device.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>sudo blkid<\/pre>\n<\/div>\n<p>As an example, my drive&#8217;s path was <code>\/dev\/sda1<\/code><\/p>\n<p>Once you&#8217;ve found your device, unmount it by using the <code>umount<\/code> command.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>sudo umount \/dev\/XXX<\/pre>\n<\/div>\n<p>Then format your device to be swap:<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>sudo mkswap \/dev\/XXX<\/pre>\n<\/div>\n<p>If the previous command outputted an alphanumeric UUID, copy that now. Otherwise, find the UUID by running <code>blkid<\/code> again. Copy the UUID associated with <code>\/dev\/XXX<\/code><\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>sudo blkid<\/pre>\n<\/div>\n<p>Now edit your <code>\/etc\/fstab<\/code> file to register your swap file. (I&#8217;m a Vim guy, but Nano is installed by default)<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>sudo nano \/etc\/fstab<\/pre>\n<\/div>\n<p>On a separate line, enter the following information. Replace the X&#8217;s with the UUID (without quotes)<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX none swap sw,pri=5 0 0<\/pre>\n<\/div>\n<p>Save <code>\/etc\/fstab<\/code>, exit your text editor, and run the following command:<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>sudo swapon -a<\/pre>\n<\/div>\n<p>If you get an error claiming it can&#8217;t find your UUID, go back and edit <code>\/etc\/fstab<\/code>. Replace the <code>UUID=XXX..<\/code> bit with the original <code>\/dev\/XXX<\/code> information.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>sudo nano \/etc\/fstab<\/pre>\n<\/div>\n<div class=\"highlight highlight-source-shell\">\n<pre><span class=\"pl-c\"># Replace the UUID with \/dev\/XXX<\/span>\r\n\/dev\/XXX none swap sw,pri=5 0 0<\/pre>\n<\/div>\n<p>Alright! You&#8217;ve got swap! Don&#8217;t throw out the <code>\/dev\/XXX<\/code> information yet- you&#8217;ll need it to remove the device safely later on.<\/p>\n<h3><a id=\"user-content-6-compiling-tensorflow\" class=\"anchor\" href=\"https:\/\/github.com\/samjabrahams\/tensorflow-on-raspberry-pi\/blob\/master\/GUIDE.md#6-compiling-tensorflow\"><\/a>6. Compiling TensorFlow<\/h3>\n<p>First things first, clone the TensorFlow repository and move into the newly created directory.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>git clone --recurse-submodules https:\/\/github.com\/tensorflow\/tensorflow\r\n<span class=\"pl-c1\">cd<\/span> tensorflow<\/pre>\n<\/div>\n<p><em>Note: if you&#8217;re looking to build to a specific version or commit of TensorFlow (as opposed to the HEAD at master), you should <code>git checkout<\/code> it now.<\/em><\/p>\n<p>Once in the directory, we have to write a nifty one-liner that is incredibly important. The next line goes through all files and changes references of 64-bit program implementations (which we don&#8217;t have access to) to 32-bit implementations. Neat!<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>grep -Rl <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>lib64<span class=\"pl-pds\">'<\/span><\/span> <span class=\"pl-k\">|<\/span> xargs sed -i <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>s\/lib64\/lib\/g<span class=\"pl-pds\">'<\/span><\/span><\/pre>\n<\/div>\n<p>Next, we need to delete a particular line in <code>tensorflow\/core\/platform\/platform.h<\/code>. Open up the file in your favorite text editor:<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>$ sudo nano tensorflow\/core\/platform\/platform.h<\/pre>\n<\/div>\n<p>Now, scroll down toward the bottom and delete the following line containing <code>#define IS_MOBILE_PLATFORM<\/code>:<\/p>\n<div class=\"highlight highlight-source-c++\">\n<pre>#<span class=\"pl-k\">elif<\/span> defined(__arm__)\r\n#<span class=\"pl-k\">define<\/span> <span class=\"pl-en\">PLATFORM_POSIX<\/span>\r\n...\r\n#<span class=\"pl-k\">define<\/span> <span class=\"pl-en\">IS_MOBILE_PLATFORM<\/span>   &lt;----- DELETE THIS LINE<\/pre>\n<\/div>\n<p>This keeps our Raspberry Pi device (which has an ARM CPU) from being recognized as a mobile device.<\/p>\n<p>Now let&#8217;s configure Bazel:<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>$ .\/configure\r\n\r\nPlease specify the location of python. [Default is \/usr\/bin\/python]: \/usr\/bin\/python\r\nDo you wish to build TensorFlow with Google Cloud Platform support<span class=\"pl-k\">?<\/span> [y\/N] N\r\nDo you wish to build TensorFlow with GPU support<span class=\"pl-k\">?<\/span> [y\/N] N<\/pre>\n<\/div>\n<p><em>Note: if you want to build for Python 3, specify <code>\/usr\/bin\/python3<\/code> for Python&#8217;s location.<\/em><\/p>\n<p>Now we can use it to build TensorFlow! <strong>Warning: This takes a really, really long time. Several hours.<\/strong><\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>bazel build -c opt --copt=<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>-mfpu=neon-vfpv4<span class=\"pl-pds\">\"<\/span><\/span> --copt=<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>-funsafe-math-optimizations<span class=\"pl-pds\">\"<\/span><\/span> --copt=<span class=\"pl-s\"><span class=\"pl-pds\">\"<\/span>-ftree-vectorize<span class=\"pl-pds\">\"<\/span><\/span> --local_resources 1024,1.0,1.0 --verbose_failures tensorflow\/tools\/pip_package:build_pip_package<\/pre>\n<\/div>\n<p><em>Note: I toyed around with telling Bazel to use all four cores in the Raspberry Pi, but that seemed to make compiling more prone to completely locking up. This process takes a long time regardless, so I&#8217;m sticking with the more reliable options here. If you want to be bold, try using <code>--local_resources 1024,2.0,1.0<\/code> or <code>--local_resources 1024,4.0,1.0<\/code><\/em><\/p>\n<p>When you wake up the next morning and it&#8217;s finished compiling, you&#8217;re in the home stretch! Use the built binary file to create a Python wheel.<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>bazel-bin\/tensorflow\/tools\/pip_package\/build_pip_package \/tmp\/tensorflow_pkg<\/pre>\n<\/div>\n<p>And then install it!<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>sudo pip install \/tmp\/tensorflow_pkg\/tensorflow-0.10-cp27-none-linux_armv7l.whl<\/pre>\n<\/div>\n<h3><a id=\"user-content-7-cleaning-up\" class=\"anchor\" href=\"https:\/\/github.com\/samjabrahams\/tensorflow-on-raspberry-pi\/blob\/master\/GUIDE.md#7-cleaning-up\"><\/a>7. Cleaning Up<\/h3>\n<p>There&#8217;s one last bit of house-cleaning we need to do before we&#8217;re done: remove the USB drive that we&#8217;ve been using as swap.<\/p>\n<p>First, turn off your drive as swap:<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>sudo swapoff \/dev\/XXX<\/pre>\n<\/div>\n<p>Finally, remove the line you wrote in <code>\/etc\/fstab<\/code> referencing the device<\/p>\n<pre><code>sudo nano \/etc\/fstab\r\n<\/code><\/pre>\n<p>Then reboot your Raspberry Pi.<\/p>\n<p><strong>And you&#8217;re done!<\/strong> You deserve a break.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>What You Need Raspberry Pi 2 or 3 Model B An SD card running Raspbian with several GB of free space An 8 GB card with a fresh install of Raspbian does not have enough space. A 16 GB SD card minimum is recommended. These instructions may work on Linux distributions other than Raspbian Internet &hellip; <a href=\"https:\/\/www.strongd.net\/?p=1376\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Building TensorFlow for Raspberry Pi: a Step-By-Step Guide<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,11],"tags":[210,211],"class_list":["post-1376","post","type-post","status-publish","format-standard","hentry","category-linux","category-11","tag-pi","tag-tensorflow"],"_links":{"self":[{"href":"https:\/\/www.strongd.net\/index.php?rest_route=\/wp\/v2\/posts\/1376","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.strongd.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.strongd.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.strongd.net\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.strongd.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1376"}],"version-history":[{"count":1,"href":"https:\/\/www.strongd.net\/index.php?rest_route=\/wp\/v2\/posts\/1376\/revisions"}],"predecessor-version":[{"id":1377,"href":"https:\/\/www.strongd.net\/index.php?rest_route=\/wp\/v2\/posts\/1376\/revisions\/1377"}],"wp:attachment":[{"href":"https:\/\/www.strongd.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1376"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.strongd.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1376"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.strongd.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1376"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}