前提
Keras+Tensorflowで画像のカテゴリ分類を行なうモデルを作成しました。
これをPythonのFlaskライブラリを使って公開したAPIで読み込み、APIにPOSTされた画像のカテゴリを判定する、というプログラムを作り、AzureのWebAppsに配置します。
発生している問題
モデルが1つの時はデプロイ後正しいURLを叩くことでWEBアプリが起動できていたんですが、モデルが多くなるにつれてタイムアウトエラーが発生してしまうようになりました。
HTTP Error 500.0 - Internal Server Error D:\home\python364x64\python.exe - The FastCGI process exceeded configured activity timeout
これを解決する案、設定、そのほか何かお知恵はありませんでしょうか?
サンプルコード(main.py)
Python
1import base64 2import io 3import json 4import time 5from datetime import datetime 6from platform import python_version 7 8import keras 9import numpy as np 10from flask import Flask, jsonify, make_response, request 11from keras import metrics 12from keras.layers import Conv2D, Dense, Dropout, Flatten, MaxPooling2D 13from keras.models import Sequential, load_model 14from keras.preprocessing.image import array_to_img, img_to_array, load_img 15from keras.utils import np_utils 16from PIL import Image 17 18start = time.time() 19print(time.strftime("%H:%M:%S", time.gmtime(time.time()-start)) + ":App start.") 20 21 22app = Flask(__name__) 23app.config['JSON_AS_ASCII'] = False 24 25print(time.strftime("%H:%M:%S", time.gmtime(time.time()-start)) + ":1st model load start.") 26s1model = load_model("./models/category1.hdf5") 27print(time.strftime("%H:%M:%S", time.gmtime(time.time()-start)) + ":1st model loaded. Next 2.") 28s2model = load_model("./models/category2.hdf5") 29print(time.strftime("%H:%M:%S", time.gmtime(time.time()-start)) + ":2nd model loaded. Next 3.") 30s3model = load_model("./models/category3.hdf5") 31print(time.strftime("%H:%M:%S", time.gmtime(time.time()-start)) + ":3rd model loaded. Next 4.") 32s4model = load_model("./models/category4.hdf5") 33print(time.strftime("%H:%M:%S", time.gmtime(time.time()-start)) + ":4th model loaded. Next 5.") 34s5_P1model = load_model("./models/category5_P1.hdf5") 35print(time.strftime("%H:%M:%S", time.gmtime(time.time()-start)) + ":5th model loaded. Next 6.") 36s6_P1model = load_model("./models/category6_P1.hdf5") 37print(time.strftime("%H:%M:%S", time.gmtime(time.time()-start)) + ":6th model loaded. Next 7.") 38s7_P1model = load_model("./models/category7_P1.hdf5") 39print(time.strftime("%H:%M:%S", time.gmtime(time.time()-start)) + ":7th model loaded. Next 8.") 40s5_P2model = load_model("./models/category5_P2.hdf5") 41print(time.strftime("%H:%M:%S", time.gmtime(time.time()-start)) + ":8th model loaded. Next 9.") 42s6_P2model = load_model("./models/category6_P2.hdf5") 43print(time.strftime("%H:%M:%S", time.gmtime(time.time()-start)) + ":9th model loaded. Next 10.") 44s7_P2model = load_model("./models/category7_P2.hdf5") 45print(time.strftime("%H:%M:%S", time.gmtime(time.time()-start)) + ":10th model loaded. Next 11.") 46s5_P3model = load_model("./models/category5_P3.hdf5") 47print(time.strftime("%H:%M:%S", time.gmtime(time.time()-start)) + ":11th model loaded. Next 12.") 48s6_P3model = load_model("./models/category6_P3.hdf5") 49print(time.strftime("%H:%M:%S", time.gmtime(time.time()-start)) + ":12th model loaded. Next 13.") 50s7_P3model = load_model("./models/category7_P3.hdf5") 51print(time.strftime("%H:%M:%S", time.gmtime(time.time()-start)) + ":13th model loaded. Next 14.") 52s5_P4model = load_model("./models/category5_P4.hdf5") 53print(time.strftime("%H:%M:%S", time.gmtime(time.time()-start)) + ":14th model loaded. Next 15.") 54s6_P4model = load_model("./models/category6_P4.hdf5") 55print(time.strftime("%H:%M:%S", time.gmtime(time.time()-start)) + ":15th model loaded. Next 16.") 56s7_P4model = load_model("./models/category7_P4.hdf5") 57print(time.strftime("%H:%M:%S", time.gmtime(time.time()-start)) + ":16th model loaded. All model are loaded.") 58 59@app.route('/api/judge', methods=['POST']) 60def scoring(): 61 try: 62 if request.method == "POST": 63 content_type = request.headers["Content-Type"] 64 if content_type == None or \ 65 not content_type.startswith("application/json") or \ 66 "img" not in request.json or \ 67 "pattern" not in request.json: 68 return make_response(jsonify({'status': 'failure'}), 405) 69 70 base64str = request.json["img"] 71 # POSTで渡ってきたbase64文字列は「+」が「 」(スペース)に変換されてしまっているため、元に戻してやってからDecode。 72 dec_image = base64.b64decode(base64str.replace(" ", "+")) 73 img = Image.open(io.BytesIO(dec_image)) 74 img = img.convert("RGB") 75 img = img.resize((100, 100)) 76 data = np.asarray(img) 77 data = data.astype("float") / 255 78 79 img = data 80 81 pred1 = s1model.predict(np.array([img])) 82 pred2 = s2model.predict(np.array([img])) 83 pred3 = s3model.predict(np.array([img])) 84 pred4 = s4model.predict(np.array([img])) 85 pred5 = "" 86 pred6 = "" 87 pred7 = "" 88 pattern = request.json["pattern"] 89 if pattern == "P1": 90 pred5 = s5_P1model.predict(np.array([img])) 91 pred6 = s6_P1model.predict(np.array([img])) 92 pred7 = s7_P1model.predict(np.array([img])) 93 elif pattern == "P2": 94 pred5 = s5_P2model.predict(np.array([img])) 95 pred6 = s6_P2model.predict(np.array([img])) 96 pred7 = s7_P2model.predict(np.array([img])) 97 elif pattern == "P3": 98 pred5 = s5_P3model.predict(np.array([img])) 99 pred6 = s6_P3model.predict(np.array([img])) 100 pred7 = s7_P3model.predict(np.array([img])) 101 elif pattern == "P4": 102 pred5 = s5_P4model.predict(np.array([img])) 103 pred6 = s6_P4model.predict(np.array([img])) 104 pred7 = s7_P4model.predict(np.array([img])) 105 106 category = { 107 "1": {"category": np.argmax(pred1, axis=1).item(), "pred": pred1.tolist()[0]}, 108 "2": {"category": np.argmax(pred2, axis=1).item(), "pred": pred2.tolist()[0]}, 109 "3": {"category": np.argmax(pred3, axis=1).item(), "pred": pred3.tolist()[0]}, 110 "4": {"category": np.argmax(pred4, axis=1).item(), "pred": pred4.tolist()[0]}, 111 "5": {"category": np.argmax(pred5, axis=1).item(), "pred": pred5.tolist()[0]}, 112 "6": {"category": np.argmax(pred6, axis=1).item(), "pred": pred6.tolist()[0]}, 113 "7": {"category": np.argmax(pred7, axis=1).item(), "pred": pred7.tolist()[0]} 114 } 115 116 result = jsonify({ 117 "status": "OK", 118 "category": category 119 }) 120 121 return make_response(result, 200) 122 else: 123 return make_response(jsonify({'status': 'failure'}), 405) 124 except: 125 import traceback 126 traceback.print_exc() 127 return make_response(jsonify({"status": "failure", "message": "Internal server error"}), 500) 128 129 130if __name__ == '__main__': 131 app.run()
開発環境:ローカル
- Python 3.6.4 :: Anaconda
- Windows 10
- keras 2.1.4
- tensorflow 1.2.1
※ちなみにローカルマシン(SurfacePro4)で上記コードを実行すると読み込み完了までおおよそ7分前後かかります
実行環境:Azure Web Apps
- 拡張機能により
Python 3.6.4
をインストール - その他はAzurePortalから作成したまま

回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/03/13 11:00
2018/03/13 11:07
2018/03/13 11:10
2018/03/13 13:09