Tensorflowが公式にRaspberry Piでサポートされた
https://www.tensorflow.org/install/install_raspbian
のはいいけれど、この公式のものはRaspbianでしかそのままでは動作しない。
Raspberry Pi 3 model BボードにUbuntu mate https://ubuntu-mate.org/ をインストールして 動作させていたので、少し困る。というのもraspbianはUbuntu 14.04ベースであり、 mateは16.04ベースのため、pythonのバージョンが異なる(python3.4 vs. python 3.5)。
仕方ないのでソースからコンパイルをした。今現在のTensorflowのバージョンは1.9であるが、 githubからソースコードをチェックアウトすると、HEADのrevisionは1.10.0rc1となる。
https://www.tensorflow.org/install/install_raspbian の説明に従い、 x86_64のUbuntu 16.04LTSにてクロスコンパイルした。なお、ECCメモリのついたXeonでやる方が無難な模様。
説明にあるとおりのコマンドを実行すると、かなり時間がたってから、
tensorflow-1.10.0rc1-cp34-none-linux_armv7l.whl
というファイルができる。これをpipでインストールすればよい。 ただし、Ubuntu 16.04ではpython3のバージョンがpython3.5系のため、 別途Python 3.4.8をsourceコードからインストールして、
pip3.4 install tensorflow-1.10.0rc1-cp34-none-linux_armv7l.whl
でOKのはず。16.04ベースのためか、kerasもpip3.4でインストールができた。ただh5pyの部分で異常に時間がかかる。
Zybo-Z7 20 (Zynq-7000 XC7Z020)
このFPGA SoCでは、FPGA Regionを使いつつTensorflowも使うために、まずブートイメージとして https://qiita.com/ikwzm/items/7e90f0ca2165dbb9a577 にあるカーネルをSDカードにセットアップした。
シリアルコンソールでブートして、ethernetにTCP/IPの設定をしssh serverが起動するように設定すると、 普通のLinux鯖と同様に使うことができる。
まずは、Ubuntu mate用にコンパイルしたwheelファイルを持ってきてインストールしようとした。 このブートイメージはDebian 9ベースのため、Ubuntuとはパッケージ名が異なる。 また、python3のバージョンはpython3.5であり、そのままではうまくいかない。 結局、ソースからPython 3.4.9をインストールしようとしたら、 sslのパッケージが3.4.9の想定と異なっており、うまくいかない。 色々と試行錯誤した結果、パッケージのopensslは一切インストールせずに、 openssl-1.0.2(古い)をソースコードからインストールして、 python3.4.9のbuild時のオプションで必要なパスを指定する必要があった。 その上で、tensorflow-1.10.0rc1-cp34-none-linux_armv7l.whl がやっとインストールができた。
kerasから利用するため、kerasをpip3.4からインストールしようとすると、 h5py(HDF5ライブラリのラッパー)のパッケージでどうしてもこける。 まず、Debian 9公式のものはバージョンがあわず、名前も"_serial"というpostfixが追加されていて、 pipのkerasの想定とは異なっており、全然だめ。
結局、hdf5-1.8.4をソースからインストールした上で、まずはh5pyをソースからインストールし、 その上でkerasもソースからインストールすることで、ようやくkerasが動作した。
これでテストが出来ると思っていたら、先にインストールしたTensorflowの部分を実行すると、 illegal hardware instructionとでて動かない。調べたところ、Tensorflowのクロスコンパイルスクリプトは、 デフォルトでRaspberry Pi 3を想定しており、それ用に演算器の最適化オプションがついていた。 具体的にはgccのオプションとして”-mfpu=neon-vfpv4”が指定されていた
Zynq-7000へログインして/proc/cpuinfoを見てみると、vfpv4がサポートされていない(下記参照)。 これが怪しいので、スクリプトの該当部分、 具体的にはgithubからチェックアウトしたTensorflowのソースコード “tensorflow/tensorflow/tools/ci_build/pi/build_raspberry_pi.sh” 88行目の最後の部分を “-mfpu=neon"と変えた。これで一応NEON命令は使ってくれるはずなので、ひどくは遅くないはずである。 その上で、dockerを利用したクロスコンパイルをもう一度おこない、同じファイル名のwheelファイルができた。
先にインストールしたtensorflowをpip3.4でunistallしてから、新しいwheelファイルをinstallしたところ、 kerasからx86_64上でGPUを使って学習したモデルファイルを読み込んで、 Zynq-7000でもtensorflowによる画像分類の推論を実行できた。
2つのプラットフォームでの実行結果比較
Hardware : BCM2709 (Raspberry Pi 3 model B)
/proc/cpuinfo
processor : 0
model name : ARMv7 Processor rev 4 (v7l)
BogoMIPS : 38.40
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xd03
CPU revision : 4
Tensorflow実行結果(推論)
1/1 [==============================] - 0s 403ms/step
[[0. 0. 1.]]
1/1 [==============================] - 0s 61ms/step
[[0. 0. 1.]]
1/1 [==============================] - 0s 63ms/step
[[0. 0. 1.]]
1/1 [==============================] - 0s 70ms/step
[[0. 1. 0.]]
1/1 [==============================] - 0s 62ms/step
[[0. 1. 0.]]
1/1 [==============================] - 0s 61ms/step
[[0. 1. 0.]]
Hardware : Xilinx Zynq Platform (Zybo Z7-20)
/proc/cpuinfo
processor : 0
model name : ARMv7 Processor rev 0 (v7l)
BogoMIPS : 666.66
Features : half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpd32
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x3
CPU part : 0xc09
CPU revision : 0
Tensorflow実行結果(推論)
1/1 [==============================] - 1s 813ms/step
[[0. 0. 1.]]
1/1 [==============================] - 0s 151ms/step
[[0. 0. 1.]]
1/1 [==============================] - 0s 151ms/step
[[0. 0. 1.]]
1/1 [==============================] - 0s 156ms/step
[[0. 1. 0.]]
1/1 [==============================] - 0s 151ms/step
[[0. 1. 0.]]
1/1 [==============================] - 0s 150ms/step
[[0. 1. 0.]]