Rasbian8(Jessie)でビルドしたTensorflow Liteをリンクしたバイナリーを実行すると「pure virtual method called」や「Segmentation Fault」と出て実行できない状況の修正ポイントです。
前提
下記にRaspberryPiでのTensorFlow Liteのビルド方法が詳しく書かかれています。
Deep Learningアプリケーション開発 (6) TensorFlow Lite with C++ on Raspberry Pi
https://qiita.com/iwatake2222/items/4d198f6203348ef7fd31
※最新ブランチ(19/5/27現在)ではうまくでできなかったので、記事中のbranch指定は重要です。
この通りにやればRasbian9(Strech)上ではうまく動くのですが、Rasbian8(Jessie)では、ビルドは成功するものの実行時に「pure virtual method called」と出て落ちてしまいます。
解消方法
以下に答えがありました。
Tensorflow lite aborts due to "pure virtual method called" on Raspberry Pi #22510
https://github.com/tensorflow/tensorflow/issues/22510
vvigilante commented on 30 Sep 2018
I got it running. Compile flag -march=armv7-a seems to break things.
Just removing that flag worked for me.
I don't know if it is related to gcc version (mine is 4.9.2). I'm doing other tests.
と書いてあり、closeされているのですが、Makeファイルにもarmv7-aなんて書いていないのでどこだろう...と悩むこと数日。Strechでは正常に動くことからOSアップデートで逃げようとしていたところ、見つけました!
targetの下にincludeファイルがあったのですね...。この中のCXXFLAGSとCCFLAGSにある-march=armv7-a \
を削除してコンパイルしなおしたところ、正常に動作しました!
...
ifeq ($(TARGET_ARCH), armv7l)
CXXFLAGS += \
-march=armv7-a \ ←ここを削除
-mfpu=neon-vfpv4 \
-funsafe-math-optimizations \
-ftree-vectorize \
-fPIC
CCFLAGS += \
-march=armv7-a \ ←ここを削除
-mfpu=neon-vfpv4 \
-funsafe-math-optimizations \
-ftree-vectorize \
-fPIC
LDFLAGS := \
-Wl,--no-export-dynamic \
-Wl,--exclude-libs,ALL \
-Wl,--gc-sections \
-Wl,--as-needed
endif
...
たぶんgccが4.9→6.3になっている違いかと思いますが、詳しくは不明です。いまさらJessieが必須なのも少ないかもしれませんが、メモとして残しておきます。
などなど
Raspberry Pi3上で400ms程度で推論できました。この速度だと画像分類でも実用になりそうですし、もっとリアルタイム性が必要であればTPUも使えるかもしれないので夢が広がります。
time 399.459000[ms]
prob of 0: 0.962
prob of 1: 0.000
prob of 2: 0.038