Posted at

Macでgo-tfliteを動かしてみる


はじめに

mattn/go-tfliteというものが出て動かそうとしていたのですが、動くまでに詰まることがとても多かったのでメモ代わりに残します。


環境

バージョンとかの違いで、変わってしまうかもしれないので

go-tfliteやtensorflowのビルドのバージョンも載せておきます。


1. tensorflow liteのビルド

このビルドに関してはmruby + TensorFlow Liteで画像分類するという記事を参考にしました。

おそらくUbuntuの方は、この記事通りにビルドしてもらったらいいと思います。

まずは $GOPATH/src/github.com/tensorflow/tensorflowこのリポジトリをcloneします。

なぜ、$GOPATH以下に置くのかというとgo-tflitetflite.goでライブラリを取得する際に相対パスでライブラリへのパスを指定しているみたいだからです。

次に、ld: library not found for -lrtというエラーが出ないように、tensorflow/lite/tools/make/Makefileから -lrtオプションを消します。(このエラーについてはあまり良くわからなかったので詳しい方がいれば教えて下さい。)


tensorflow/lite/tools/make/Makefile

        CORE_CC_ALL_SRCS += tensorflow/lite/delegates/nnapi/quant_lstm_sup.cc

CORE_CC_ALL_SRCS += tensorflow/lite/nnapi/nnapi_implementation.cc
- LIBS += -lrt

次に以下のコマンドを実行します。

$ ./tensorflow/lite/tools/make/download_dependencies.sh

$ make -f tensorflow/lite/tools/make/Makefile


2. C experimental APIライブラリのビルド

こちらも上述の記事を参考にさせてもらって以下のように、Makefileを書きました。

tensorflow/lite/experimental/c以下でmakeを実行すると、libtensorflowlite_c.soというファイルが出来上がります。


tensorflow/lite/experimental/c/Makefile

CXX = clang++

SRCS = c_api.cc c_api_experimental.cc
OBJS = $(subst .cc,.o,$(subst .cxx,.o,$(subst .cpp,.o,$(SRCS))))
TENSORFLOW_ROOT = ../../../../
CXXFLAGS = -DTF_COMPILE_LIBRARY -I$(TENSORFLOW_ROOT) -I$(TENSORFLOW_ROOT)/tensorflow/lite/tools/make/downloads/flatbuffers/include -fPIC
TARGET = libtensorflowlite_c
OS_ARCH = osx_x86_64
TARGET_SHARED := $(TARGET).so
LDFLAGS += -L$(TENSORFLOW_ROOT)/tensorflow/lite/tools/make/gen/$(OS_ARCH)/lib
LIBS = -ltensorflow-lite

.SUFFIXES: .cpp .cxx .o

all : $(TARGET_SHARED)

$(TARGET_SHARED) : $(OBJS)
$(CXX) -shared -o $@ $(OBJS) $(LDFLAGS) $(LIBS)
.cxx.o :
$(CXX) -std=c++14 -c $(CXXFLAGS) -I. $< -o $@
.cpp.o :
$(CXX) -std=c++14 -c $(CXXFLAGS) -I. $< -o $@
clean :
rm -f *.o $(TARGET_SHARED)


上のmakeで出来たlibtensorflowlite_c.so/usr/local/lib以下にコピーすると準備完了です。


go-tfliteをクローンする

$GOPATH/src/github.com/mattn/go-tflitemattn/go-tfliteをクローンしてください。

_exampleで何個か遊んでみましょう。


$GOPATH/src/github.com/mattn/go-tflite/_example/mnist

$ go run main.go 0.png

# github.com/mattn/go-tflite
./tflite_experimental.go:35:12: warning: expression result unused [-Wunused-value]
0

無事mnistの画像認識に成功しています。


$GOPATH/src/github.com/mattn/go-tflite/_example/fizzbuzz

$ go run main.go

# github.com/mattn/go-tflite
./tflite_experimental.go:35:12: warning: expression result unused [-Wunused-value]
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz
31
32
Fizz
34
Buzz
Fizz
37
38
Fizz
Buzz
41
Fizz
43
44
FizzBuzz
46
47
Fizz
49
Buzz
Fizz
52
53
Fizz
Buzz
56
Fizz
58
59
FizzBuzz
61
62
Fizz
64
Buzz
Fizz
67
68
Fizz
Buzz
71
Fizz
73
74
FizzBuzz
76
77
Fizz
79
Buzz
Fizz
82
83
Fizz
Buzz
86
Fizz
88
89
FizzBuzz
91
92
Fizz
94
Buzz
Fizz
97
98
Fizz
Buzz

fizzbuzzも成功しました。


まとめ

tensorflowのようなツールをGoでも使えるのはすごく嬉しいですね。

こういうツールはPythonが使われることが多いのですが、僕個人としてはGolangでも機械学習する人が増えればいいなあと思います。

go-tfliteは推論にしか使えないようで、まだpythonのように学習から推論までというふうには行きませんが、今後Golangでも学習が出来たらうれしいなあと思います。