
TFServe運用にSavedModelを使ってみた!
2020.08.14
目次
学習済みモデルを活用するなら TFServe
モデルを活用する機会がない?
皆さんは、モデルを開発した後、どのように活用していますか?
ニューラルネットワークにおいて、モデルの活用シーンはあまり議論されていないように思います。
推論をする場合、大多数の人が学習スクリプトを「そのまま」使っているはずです。
学習スクリプトを活かす機会は身近にある
学習スクリプトは、一般ユーザーにとってはそれほど馴染みがあるものではありません。
仮に、「画像を使って製品出荷数のログを取りたい」というニーズがあるとします。
学習スクリプトと縁がない一般ユーザーは、「スマホで撮影した写真をアップロードして、後はAIでなんとかしよう」という発想になってしまうわけです。
しかし、この記事を読んでいるあなたのように、学習スクリプトに知見のある方ならばどうでしょう?
せっかくだから、学習済みモデルを活用してみたくなりませんか?
学習済みモデルを運用するならTFServe
そういう時に活躍するのが、「TFServe(Tensorflor-model-server )です。
今回は、「TFServe」のポイントである「SavedModel」について解説します。
こちらの記事もオススメ!
TFServe とは
「TFServe」は、Tensorflow で構築した学習済みモデルを、実際に運用するためのシステムです。
【公式サイト】
https://www.tensorflow.org/tfx/guide/serving
今回は「SavedModel」の解説がメインのため、TFServe のインストールなどの前準備は省きます。
TFServe の主な特徴は、以下の通りです。
- C++ で書かれているため、サーバー機能のパフォーマンスが高い
- gRPC で通信するため、言語を問わず使える
- 複数のモデル運用やバージョン管理が簡単に行える
keras モデルを TFServe で動かしてみる
今回は、Keras で作ったカスタム認識プログラムを、TFServe で動かしてみようと思います。
使用するプログラム
認識プログラムは、何でも構いません。
ただし、ディレクトリからカスタムラベルを認識するものを使いましょう。
また、今回は、「Cifar10」を使います。
実装例
以下が、Keras プログラムです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | import keras from keras.preprocessing.image import ImageDataGenerator from keras.models import Sequential from keras.layers import Dense, Dropout, Activation, Flatten from keras.layers import Conv2D, MaxPooling2D import tensorflow as tf from keras import backend as K import os batch_size = 32 num_classes = 7 epochs = 2 train_data_dir = 'XXXXXXXX' #ここには実際の学習セットを置くディレクトリ名をいれる validation_data_dir ='XXXXXXXX' #ここには実際の評価セットを置くディレクトリ名をいれる。 train_datagen = ImageDataGenerator( rescale=1. / 255, shear_range=0.2, zoom_range=0.2, horizontal_flip=True) test_datagen = ImageDataGenerator(rescale=1. / 255) train_generator = train_datagen.flow_from_directory( train_data_dir, target_size=(32, 32), batch_size=batch_size, class_mode='categorical') validation_generator = test_datagen.flow_from_directory( validation_data_dir, target_size=(32, 32), batch_size=8, class_mode='categorical') model = Sequential() model.add(Conv2D(32, (3, 3), padding='same', input_shape=(32,32,3))) model.add(Activation('relu')) model.add(Conv2D(32, (3, 3))) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(512)) model.add(Activation('relu')) model.add(Dropout(0.5)) model.add(Dense(num_classes)) model.add(Activation('softmax')) opt = keras.optimizers.RMSprop(lr=0.0001, decay=1e-6) model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy']) model.summary() model.fit_generator(train_generator, steps_per_epoch=batch_size, epochs=epochs, validation_data=validation_generator, validation_steps = batch_size, shuffle=True) model_dir='models' #ここは任意のディレクトリ名でよい。 builder = tf.saved_model.builder.SavedModelBuilder(model_dir + '/0') #バージョン番号も任意でよい signature = tf.saved_model.predict_signature_def(inputs={'input': model.input}, outputs={'output': model.output}) sess = K.get_session() builder.add_meta_graph_and_variables(sess=sess, tags=[tf.saved_model.tag_constants.SERVING], signature_def_map={'serving_default': signature}) #この文字列は固定 builder.save() |
必ず SavedModel 形式で保存してください。
SavedModel とは? SavedModel 保存の方法は?
「SavedModel」形式は、TensorFlowのみならず、GCP や AWS も対応している保存形式です。
SavedModel 形式は、CheckPoint 形式と異なり、言語に依存しません。
CheckPoint 形式だと、実際に学習モデルを運用する際、不都合なケースが多いのです。
本番環境の推論プログラムを用意しなければならなかったり、そもそもシステムが Python ではなかったりするからです。
しかし、SavedModel 形式はこのようなリスクがないため、いろいろなサービスで利用できます。
シグネチャー
SavedModel 形式のポイントは、「シグネチャー」です。
シグネチャーの中には、モデルのインターフェースが記述されています。
GCP や AWS は、このシグネチャー情報に基づき、ホスティングを行ってくれるのです。
以下が、このプログラムで作成されるシグネチャーの実際の j 表示です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs: signature_def['serving_default']: The given SavedModel SignatureDef contains the following input(s): inputs['input'] tensor_info: dtype: DT_FLOAT shape: (-1, 32, 32, 3) name: conv2d_1_input:0 The given SavedModel SignatureDef contains the following output(s): outputs['output'] tensor_info: dtype: DT_FLOAT shape: (-1, 7) name: activation_4/Softmax:0 Method name is: tensorflow/serving/predict |
SavedModel 保存には SavedModelBuilder が必要
SavedModel で保存するためには、「SavedModelBuilder」 を使う必要があります。
ただし、SavedModelBuilder が対応しているのは TF1( tensorflow 1系)のみです。
また、SavedModelBuilder を使うタイミングは、学習直後が一番楽です。
sess を渡すことで、自動的にモデルのグラフの Input パラメータと、Output パラメータをシグネチャーに書き込めます。
SavedModelBuilder なしで SavedModel 保存したいなら
SavedModelBuilder を使わずに、SavedModel 保存するやり方もあります。
一度、CheckPoint 形式などで保存されたものを読み込んで、SavedModel に変換するのです。
ただし、モデルのグラフの Input パラメータと Output パラメータは、プログラム中から記述する必要があります。
実装例の解説
それでは、プログラムの要所部分を解説していきます。
ディレクトリにバージョン番号を入れる
builder = tf.saved_model.builder.SavedModelBuilder(model_dir + '/0')
これで、保存するディレクトリ名を決めています。
重要なのは、バージョン番号を入れることです。(ここでは0を入れています。)
model_dir の下の、0というサブディレクトリの下に実際のモデルが保存されます。
バージョン番号を入れない場合、エラーが発生することがあるので注意して下さい。
セッションを指定
sess = K.get_session()
ここで、実際にトレーニングをしたセッションを指定します。
シグネチャーを指定
signature_def_map={'serving_default': signature})
サーバはこのシグネチャーを見て、ホストできるかどうかを決めます。
任意の文字列でも構いませんが、TFServe もしくは AWS や GCPなどを使う場合は、 'serviing_default' と指定しなければいけません。
注意事項
TF2 系には、Keras 自身が SavedModel を書き出すという機能が実装されています。
しかし、これを使っても実際のパラメータシグネチャが入らないので、ホスティングサービスによっては使えません。
よって、TF1 系を使うことを強くオススメします。
なお、サンプルプログラムでは、行数の関係で、トレーニングの層の数を減らしてあります。
実際には4層程度にすることで、より精度の高い推論が可能となります。
モデルを保存してシグネチャーを確認
プログラムを動かして、モデルを作成したら、実際にコマンドラインツールからシグネチャーを確認してみてください。
シグネチャーは、「saved_model_cli」というコマンドラインツールで見ることができます。
saved_model_cli は、tensorflow と同時にインストールされます。
プログラムの実行ディレクトリで、 saved_model_cli show --all --dir ./models/0 と入力すると、実際に表示してくれます。
シンタックスは、 saved_model_cli show --all --dir ディレクトリ名 となります。
ホスティングの確認
ホスティングは、とても楽です。
次のコマンドで確認することができます。
1 2 3 4 | <span class="pln">nohup tensorflow_model_server </span><span class="pun">\</span><span class="pln"> </span><span class="pun">--</span><span class="pln">rest_api_port</span><span class="pun">=</span><span class="lit">8501</span> <span class="pun">\</span><span class="pln"> </span><span class="pun">--</span><span class="pln">model_name</span><span class="pun">=あなたのモデル名</span> <span class="pun">\</span><span class="pln"> </span><span class="pun">--</span><span class="pln">model_base_path</span><span class="pun">=</span><span class="str">"ワークディレクトリ名"</span> <span class="pun">></span><span class="pln">server</span><span class="pun">.</span><span class="pln">log </span><span class="lit">2</span><span class="pun">>&</span><span class="lit">1</span> |
確認するには、postman などの RestAPI ツールを使うと簡単に確認できます。
さいごに
SavedModel は、API に関わらず、SavedModelBuilder を使えば上手く行きます。
SavedModelBuilder 以外ではエラーが頻発して動かないので、注意が必要です。
AWS SageMaker では、tensorflow コンテナで、この機能を用いたスケーラビリティのあるホスティングを実現しています。
皆さんもぜひ、AI の活用に、SavedModel を使ってみてください!
(株)ライトコードは、WEB・アプリ・ゲーム開発に強い、「好きを仕事にするエンジニア集団」です。
機械学習でのシステム開発依頼・お見積もりはこちらまでお願いします。
また、機械学習系エンジニアを積極採用中です!詳しくはこちらをご覧ください。
※現在、多数のお問合せを頂いており、返信に、多少お時間を頂く場合がございます。
こちらの記事もオススメ!
ライトコードよりお知らせ






一緒に働いてくれる仲間を募集しております!
ライトコードでは、仲間を募集しております!
当社のモットーは「好きなことを仕事にするエンジニア集団」「エンジニアによるエンジニアのための会社」。エンジニアであるあなたの「やってみたいこと」を全力で応援する会社です。
また、ライトコードは現在、急成長中!だからこそ、あなたにお任せしたいやりがいのあるお仕事は沢山あります。「コアメンバー」として活躍してくれる、あなたからのご応募をお待ちしております!
なお、ご応募の前に、「話しだけ聞いてみたい」「社内の雰囲気を知りたい」という方はこちらをご覧ください。
ライトコードでは一緒に働いていただける方を募集しております!
採用情報はこちら書いた人はこんな人

ITエンタメ2021.01.12【スティーブ・ウォズニアック】アップルコンピューターのもう一人の創業者!
IT技術2021.01.11React Hooks登場でコンポーネントはどう変わった?
IT技術2021.01.05【Unity】Rigidbodyの基本
IT技術2021.01.04【Unity】ARkit3を使ったARアプリを開発する方法を解説(AR foundation,iOS)