Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
3
Help us understand the problem. What is going on with this article?

More than 1 year has passed since last update.

@shinkoizumi0033

GoogleAppEngine(GAE)フレキシブル環境でディープラーニングの予測タスクを動かしてみた(CNN,画像分類,keras/TensorFlow)

はじめに

GoogleAppEngine(FlexibleEnv)でKeras/TensorFlowを利用し画像分類(CNN)の予測タスクを実行してみました。

本当はStandard環境で動かしたかったのですが、TensorFlowが、Python3.7非対応なので、Python3.6のFlexible環境で動作させています。
そもそもCloud ML Engineを使えば、という声が聞こえますが、GAEで完結できれば、よりお手軽なのではと思い、やってみました。

色々勉強をしながらなので、何かあればご指摘いただけると嬉しいです。

こんなユーザが対象です。

  • GoogleAppEngineでKeras/TensorFlowを動かしてみたい
  • MLEを利用することなくGAEで予測タスクも完結させたい(お手軽さや、コスト低減も期待

環境

  • GoogleAppEngine(FlexibleEnbironment,Python3.6)
  • モデルはGCSに保存

簡易構成図と簡単な流れは、以下です。

  1. 事前準備(予測するためのモデルを作成して、GCSへ保存しておく)
  2. GAEに予測画像のアップロード用のindex.htmlを作る
  3. アップロード画像を予測できるデータに変換
  4. GCSからモデルをロード
  5. 予測実行

構成図

1. 事前準備(予測するためのモデルを作成して、GCSへ保存しておく)

事前にCNNで画像分類モデルを作って、GCSに置いてください。色々サイトで手順やコードがあるので、ここで詳細は触れません。
今回私は、CNNで二つの種類の画像分類モデル(蒙古タンメン中本と、ラーメン二郎w)を作っておきました。
CNNで2つの画像分類モデルを作ったコードはgithubに公開しました。
上記のコードでは、Cloud Datalab上で、Keras/TensorFlowを利用して、モデル(HDF5ファイル)を生成、GCSへアップロードしています。

GoogleAppEngineの環境の準備もしておく

app.yamlとrequirements.txtを以下のようにしておきます。
TensorFlowはPython3.7非対応なので、Flexible環境で構築。

app.yaml
runtime: python
env: flex
entrypoint: gunicorn -b :$PORT main:app

runtime_config:
  python_version: 3
requirements.txt
Flask==1.0.2
google-cloud-storage==1.7.0
gunicorn==19.8.1
WTForms-Appengine==0.1
numpy==1.15.2
keras==2.2.4
Pillow==5.3.0
tensorflow==1.12.0

2. GAEに予測画像のアップロード用のindex.htmlを作る

アップロード用と、結果レスポンス用のhtmlの準備をしておきます。

index.html(抜粋)
<form method="post" action="post_image" enctype="multipart/form-data">
    <input type="file" name="file_predict">
    <p><input type="submit" value="送信する"></p>
</form>
predict_kekka.html(抜粋)
<p><h3>予測結果</h3></p>
予測値:{{ predict_kekka }}

3. アップロード画像を予測できるデータに変換

ここから、コードに入ります。
まずは、予測したい画像がPOSTされたら、予測できる形式にデータを変換します。
Pillowを利用して、ファイルをopenし、RGB変換、リサイズをしたうえで、numpyでarray変換しています。

main.py
        DOWNLOAD_FOLDER = '/tmp/'
        file = request.files['file_predict']
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)

        file.save(os.path.join(DOWNLOAD_FOLDER , filename))
        filepath = os.path.join(DOWNLOAD_FOLDER , filename)

        image = Image.open(filepath)
        image = image.convert('RGB')
        image = image.resize((image_size, image_size))
        data = np.asarray(image)
        X = []
        X.append(data)
        X = np.array(X)

4. GCSからモデルをロード

予測をするために事前に作っておいたモデル(HDF5ファイル=nakamoto_jiro_cnn.h5)をGCSから取得し、loadします。

main.py
        model_name = 'nakamoto_jiro_cnn.h5'
        modelpath = os.path.join(DOWNLOAD_FOLDER , model_name)

        storage_client = storage.Client()
        bucket = storage_client.get_bucket(CLOUD_STORAGE_BUCKET)
        blob = bucket.get_blob(model_name)
        blob.download_to_filename(modelpath)
        model = load_model(modelpath)

5. 予測実行

最後に、予測実行し、結果を取得します。

main.py
        result = model.predict([X])[0]
        predicted = result.argmax()
        percentage = int(result[predicted] * 100)

        predict_kekka = "ラベル: " + classes[predicted] + ", 確率:"+ str(percentage) + " %"

コードはここまでが主要なところで、あとは、GAEをデプロイして、トップページにアクセスし、2で作成したhtml(FORM)から画像をアップロードすることで、予測結果が返ってきます。

おわりに

GoogleAppEngineで画像分類の予測タスクを完結できますし、GCSからモデルをロードするだけで簡単に使えるので、MLEにモデルをホストして使うよりお手軽ではと思いました。
今回作成したGAEのコードは、githubにアップロードしています。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
3
Help us understand the problem. What is going on with this article?