Edited at

TensorFlow Lite実行時の"pure virtual method called"の解消

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 \を削除してコンパイルしなおしたところ、正常に動作しました!


tensorflow/lite/tools/make/targets/rpi_makefile.inc

...

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