• トップ
  • ブログ一覧
  • TFServe運用にSavedModelを使ってみた!
  • TFServe運用にSavedModelを使ってみた!

    メディアチームメディアチーム
    2020.07.13

    IT技術

    学習済みモデルを活用するなら TFServe

    モデルを活用する機会がない?

    皆さんは、モデルを開発した後、どのように活用していますか?

    ニューラルネットワークにおいて、モデルの活用シーンはあまり議論されていないように思います。

    推論をする場合、大多数の人が学習スクリプトを「そのまま」使っているはずです。

    学習スクリプトを活かす機会は身近にある

    学習スクリプトは、一般ユーザーにとってはそれほど馴染みがあるものではありません。

    仮に、「画像を使って製品出荷数のログを取りたい」というニーズがあるとします。

    学習スクリプトと縁がない一般ユーザーは、「スマホで撮影した写真をアップロードして、後はAIでなんとかしよう」という発想になってしまうわけです。

    しかし、この記事を読んでいるあなたのように、学習スクリプトに知見のある方ならばどうでしょう?

    せっかくだから、学習済みモデルを活用してみたくなりませんか?

    学習済みモデルを運用するならTFServe

    そういう時に活躍するのが、「TFServe(Tensorflor-model-server )です。

    今回は、「TFServe」のポイントである「SavedModel」について解説します。

    TFServe とは

    TFServe」は、Tensorflow で構築した学習済みモデルを、実際に運用するためのシステムです。

    【公式サイト】
    https://www.tensorflow.org/tfx/guide/serving

    今回は「SavedModel」の解説がメインのため、TFServe のインストールなどの前準備は省きます。

    TFServe の主な特徴は、以下の通りです。

    1. C++ で書かれているため、サーバー機能のパフォーマンスが高い
    2. gRPC で通信するため、言語を問わず使える
    3. 複数のモデル運用やバージョン管理が簡単に行える

    keras モデルを TFServe で動かしてみる

    今回は、Keras で作ったカスタム認識プログラムを、TFServe で動かしてみようと思います。

    使用するプログラム

    認識プログラムは、何でも構いません。

    ただし、ディレクトリからカスタムラベルを認識するものを使いましょう。

    また、今回は、「Cifar10」を使います。

    実装例

    以下が、Keras プログラムです。

    1import keras
    2from keras.preprocessing.image import ImageDataGenerator
    3from keras.models import Sequential
    4from keras.layers import Dense, Dropout, Activation, Flatten
    5from keras.layers import Conv2D, MaxPooling2D
    6import tensorflow as tf
    7from keras import backend as K
    8import os
    9
    10batch_size = 32
    11num_classes = 7
    12epochs = 2
    13
    14train_data_dir = 'XXXXXXXX' #ここには実際の学習セットを置くディレクトリ名をいれる
    15validation_data_dir ='XXXXXXXX' #ここには実際の評価セットを置くディレクトリ名をいれる。
    16train_datagen = ImageDataGenerator(
    17rescale=1. / 255,
    18shear_range=0.2,
    19zoom_range=0.2,
    20horizontal_flip=True)
    21test_datagen = ImageDataGenerator(rescale=1. / 255)
    22
    23train_generator = train_datagen.flow_from_directory(
    24train_data_dir,
    25target_size=(32, 32),
    26batch_size=batch_size,
    27class_mode='categorical')
    28validation_generator = test_datagen.flow_from_directory(
    29validation_data_dir,
    30target_size=(32, 32),
    31batch_size=8,
    32class_mode='categorical')
    33
    34model = Sequential()
    35model.add(Conv2D(32, (3, 3), padding='same',
    36input_shape=(32,32,3)))
    37model.add(Activation('relu'))
    38model.add(Conv2D(32, (3, 3)))
    39model.add(Activation('relu'))
    40model.add(MaxPooling2D(pool_size=(2, 2)))
    41model.add(Dropout(0.25))
    42
    43model.add(Flatten())
    44model.add(Dense(512))
    45model.add(Activation('relu'))
    46model.add(Dropout(0.5))
    47model.add(Dense(num_classes))
    48model.add(Activation('softmax'))
    49
    50opt = keras.optimizers.RMSprop(lr=0.0001, decay=1e-6)
    51
    52model.compile(loss='categorical_crossentropy',
    53optimizer=opt,
    54metrics=['accuracy'])
    55
    56model.summary()
    57
    58model.fit_generator(train_generator,
    59steps_per_epoch=batch_size,
    60epochs=epochs,
    61validation_data=validation_generator,
    62validation_steps = batch_size,
    63shuffle=True)
    64
    65model_dir='models' #ここは任意のディレクトリ名でよい。
    66builder = tf.saved_model.builder.SavedModelBuilder(model_dir + '/0') #バージョン番号も任意でよい
    67signature = tf.saved_model.predict_signature_def(inputs={'input': model.input}, outputs={'output': model.output})
    68sess = K.get_session()
    69builder.add_meta_graph_and_variables(sess=sess,
    70tags=[tf.saved_model.tag_constants.SERVING],
    71signature_def_map={'serving_default': signature}) #この文字列は固定
    72builder.save()

    必ず SavedModel 形式で保存してください

    SavedModel とは? SavedModel 保存の方法は?

    「SavedModel」形式は、TensorFlowのみならず、GCP や AWS も対応している保存形式です。

    SavedModel 形式は、CheckPoint 形式と異なり、言語に依存しません。

    CheckPoint 形式だと、実際に学習モデルを運用する際、不都合なケースが多いのです。

    本番環境の推論プログラムを用意しなければならなかったり、そもそもシステムが Python ではなかったりするからです。

    しかし、SavedModel 形式はこのようなリスクがないため、いろいろなサービスで利用できます。

    シグネチャー

    SavedModel 形式のポイントは、「シグネチャー」です。

    シグネチャーの中には、モデルのインターフェースが記述されています。

    GCP や AWS は、このシグネチャー情報に基づき、ホスティングを行ってくれるのです。

    以下が、このプログラムで作成されるシグネチャーの実際の j 表示です。

    1MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs:
    2
    3signature_def['serving_default']:
    4  The given SavedModel SignatureDef contains the following input(s):
    5    inputs['input'] tensor_info:
    6        dtype: DT_FLOAT
    7        shape: (-1, 32, 32, 3)
    8        name: conv2d_1_input:0
    9  The given SavedModel SignatureDef contains the following output(s):
    10    outputs['output'] tensor_info:
    11        dtype: DT_FLOAT
    12        shape: (-1, 7)
    13        name: activation_4/Softmax:0
    14  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  ディレクトリ名  となります。

    ホスティングの確認

    ホスティングは、とても楽です。

    次のコマンドで確認することができます。

    nohup tensorflow_model_server \
      --rest_api_port=8501 \
      --model_name=あなたのモデル名 \
      --model_base_path="ワークディレクトリ名" >server.log 2>&1

    確認するには、postman などの RestAPI ツールを使うと簡単に確認できます。

    さいごに

    SavedModel は、API に関わらず、SavedModelBuilder を使えば上手く行きます。

    SavedModelBuilder 以外ではエラーが頻発して動かないので、注意が必要です。

    AWS SageMaker では、tensorflow コンテナで、この機能を用いたスケーラビリティのあるホスティングを実現しています。

    皆さんもぜひ、AI の活用に、SavedModel を使ってみてください!

    こちらの記事もオススメ!

    featureImg2020.07.28機械学習 特集知識編人工知能・機械学習でよく使われるワード徹底まとめ!機械学習の元祖「パーセプトロン」とは?【人工知能】ニューラルネ...

    featureImg2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...

    ライトコードでは、エンジニアを積極採用中!

    ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。

    採用情報へ

    メディアチーム
    メディアチーム
    Show more...

    おすすめ記事

    エンジニア大募集中!

    ライトコードでは、エンジニアを積極採用中です。

    特に、WEBエンジニアとモバイルエンジニアは是非ご応募お待ちしております!

    また、フリーランスエンジニア様も大募集中です。

    background