TensorFlow for Goを使ってみた
はじめに
TensorFlowをGo言語で動かしてみました。
環境構築
TensorFlow for GoはWindowsに対応していないため、Ubuntu環境にインストールします。
Go言語のインストール
sudo apt install golang-go
TensorFlow for C のインストール
TensorFlow for Cのライブラリをダウンロードしたものを/usr/localに置いて、以下のコマンドを実行します。 (ファイル名はダウンロードしたファイルによって変わります。)
sudo tar -C /usr/local -xzf /usr/local/libtensorflow-cpu-linux-x86_64-1.13.1.tar.gz
export LIBRARY_PATH=$LIBRARY_PATH:/usr/local/lib
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
以下の動作確認用のサンプルプログラムを「hello_tf.c」という名前で保存します。
#include <stdio.h>
#include <tensorflow/c/c_api.h>
int main() {
printf("Hello from TensorFlow C library version %s\n", TF_Version());
return 0;
}
サンプルプログラムをビルドして、実行します。
gcc hello_tf.c -ltensorflow -o hello_tf
./hello_tf
Hello from TensorFlow C library version 1.13.1
上記のように出力されればTensorFlow for Cのインストールは成功です。
TensorFlow for Go のインストール
パッケージをインストールします。
go get github.com/tensorflow/tensorflow/tensorflow/go
以下のコマンドを入力します。
go test github.com/tensorflow/tensorflow/tensorflow/go
こんな感じの結果が返ってきます。
ok github.com/tensorflow/tensorflow/tensorflow/go 1.166s
以下の動作確認用のサンプルプログラムを「hello_tf.go」という名前で保存します。
package main
import (
tf "github.com/tensorflow/tensorflow/tensorflow/go"
"github.com/tensorflow/tensorflow/tensorflow/go/op"
"fmt"
)
func main() {
// Construct a graph with an operation that produces a string constant.
s := op.NewScope()
c := op.Const(s, "Hello from TensorFlow version " + tf.Version())
graph, err := s.Finalize()
if err != nil {
panic(err)
}
// Execute the graph in a session.
sess, err := tf.NewSession(graph, nil)
if err != nil {
panic(err)
}
output, err := sess.Run(nil, []tf.Output{c}, nil)
if err != nil {
panic(err)
}
fmt.Println(output[0].Value())
}
サンプルプログラムを実行します。
go run hello_tf.go
こんな感じの結果が返ってきたら成功です。
Hello from TensorFlow version 1.13.1
Protocol Buffers形式への変換
Tenforflow for Goの場合、hdf5ではなく、ProtocolBuffersの形式である必要があります。
この記事を公開した時点では、tensorflow 1.15.0で作成したpbファイルはTensorFlow for Goで読み取る事ができませんでした。
そのため1.13.2にバージョンを下げて実行しました。
import tensorflow as tf
from keras import backend as K
from keras.models import load_model
from tensorflow.python.saved_model import builder as saved_model_builder
from tensorflow.python.saved_model.signature_def_utils import predict_signature_def
from tensorflow.python.saved_model import tag_constants
def export_h5_to_pb(path_to_h5, export_path):
sess = tf.Session()
K.set_session(sess)
K.set_learning_phase(0)
keras_model = load_model(path_to_h5)
builder = saved_model_builder.SavedModelBuilder(export_path)
signature = predict_signature_def(inputs={"images": keras_model.input},
outputs={"scores": keras_model.output})
with K.get_session() as sess:
print(sess)
# Save the meta graph and the variables
builder.add_meta_graph_and_variables(sess, tags=[tag_constants.SERVING], signature_def_map={"predict": signature})
builder.save()
path_to_h5 = 'something.h5'
export_path = 'models'
export_h5_to_pb(path_to_h5, export_path)
実行すると、modelsフォルダが作成され、その中に「saved_model.pb」が作成されます。
推定
pb形式に変換したモデルが出力されたら、このモデルを使用して推定してみます。
model, err := tensorflow.LoadSavedModel("models", []string{"serve"}, nil)
まずはモデルを読み込みます。 「models」がフォルダ名で、「serve」が「builder.add_meta_graph_and_variables」の「tags」に渡した値になります。
result, err := model.Session.Run(
map[tensorflow.Output]*tensorflow.Tensor{
model.Graph.Operation("input_1").Output(0): tensor,
},
[]tensorflow.Output{
model.Graph.Operation("dense_2/Softmax").Output(0),
},
nil,
)
推定結果がresultに格納されます。
「model.Graph.Operation」の箇所は上がinputで、下がoutputになります。
このブログの方法でmodelを作成した場合、inputは「input_1」になるみたいです。
outputについては、今回Softmaxを使用したのでこの指定になっており、使用する関数に応じて変更が必要になります。
ディスカッション
コメント一覧
まだ、コメントがありません