flask apiを使用して、kerasモデルを展開し、テストデータをモデルに送信します。
最初:My Flask App:
# Let's startup the Flask application
app = Flask(__name__)
# Model reload from jSON:
print('Load model...')
json_file = open('models/model_temp.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
keras_model_loaded = model_from_json(loaded_model_json)
print('Model loaded...')
# Weights reloaded from .h5 inside the model
print('Load weights...')
keras_model_loaded.load_weights("models/Model_temp.h5")
print('Weights loaded...')
# URL that we'll use to make predictions using get and post
@app.route('/predict',methods=['GET','POST'])
def predict():
data = request.get_json(force=True)
predict_request = [data["month"],data["day"],data["hour"]]
predict_request = np.array(predict_request)
predict_request = predict_request.reshape(1,-1)
y_hat = keras_model_loaded.predict(predict_request, batch_size=1, verbose=1)
return jsonify({'prediction': str(y_hat)})
if __name__ == "__main__":
# Choose the port
port = int(os.environ.get('PORT', 9000))
# Run locally
app.run(Host='127.0.0.1', port=port)
2番目:APIエンドポイントに送信するJSONデータの送信に使用するファイルIm:
response = rq.get('api url has been removed')
data=response.json()
currentDT = datetime.datetime.now()
Month = currentDT.month
Day = currentDT.day
Hour = currentDT.hour
url= "http://127.0.0.1:9000/predict"
post_data = json.dumps({'month': month, 'day': day, 'hour': hour,})
r = rq.post(url,post_data)
Tensorflowに関するFlaskからこの応答を取得しています:
ValueError:Tensor Tensor( "dense_6/BiasAdd:0"、shape =(?, 1)、dtype = float32)はこのグラフの要素ではありません。
私のkerasモデルは単純な6密層モデルであり、エラーなしでトレーニングします。
何か案は?
Flaskは複数のスレッドを使用します。実行中の問題は、テンソルフローモデルが同じスレッドで読み込まれ使用されないためです。 1つの回避策は、テンソルフローにgloablのデフォルトグラフを使用させることです。
モデルをロードした後にこれを追加します
global graph
graph = tf.get_default_graph()
そして、あなたの予測の内側
with graph.as_default():
y_hat = keras_model_loaded.predict(predict_request, batch_size=1, verbose=1)
ケラスモデルをクラスにラップする方がはるかに簡単で、そのクラスは独自のグラフとセッションを追跡できます。これにより、複数のスレッド/プロセス/モデルが原因で発生する可能性のある問題が回避されます。これは、ほぼ確実に問題の原因です。他のソリューションでも機能しますが、これが最も一般的で、スケーラブルであり、すべてをキャッチします。これを使用してください:
import os
from keras.models import model_from_json
from keras import backend as K
import tensorflow as tf
import logging
logger = logging.getLogger('root')
class NeuralNetwork:
def __init__(self):
self.session = tf.Session()
self.graph = tf.get_default_graph()
# the folder in which the model and weights are stored
self.model_folder = os.path.join(os.path.abspath("src"), "static")
self.model = None
# for some reason in a flask app the graph/session needs to be used in the init else it hangs on other threads
with self.graph.as_default():
with self.session.as_default():
logging.info("neural network initialised")
def load(self, file_name=None):
"""
:param file_name: [model_file_name, weights_file_name]
:return:
"""
with self.graph.as_default():
with self.session.as_default():
try:
model_name = file_name[0]
weights_name = file_name[1]
if model_name is not None:
# load the model
json_file_path = os.path.join(self.model_folder, model_name)
json_file = open(json_file_path, 'r')
loaded_model_json = json_file.read()
json_file.close()
self.model = model_from_json(loaded_model_json)
if weights_name is not None:
# load the weights
weights_path = os.path.join(self.model_folder, weights_name)
self.model.load_weights(weights_path)
logging.info("Neural Network loaded: ")
logging.info('\t' + "Neural Network model: " + model_name)
logging.info('\t' + "Neural Network weights: " + weights_name)
return True
except Exception as e:
logging.exception(e)
return False
def predict(self, x):
with self.graph.as_default():
with self.session.as_default():
y = self.model.predict(x)
return y
この方法はclear_session呼び出しを必要とせず、同時に設定されたセッションsession = tf.Session(config=_config); self.graph = session.graph
からのグラフオブジェクトとデフォルトとして作成されたグラフによる予測with self.graph.as_default():
を使用する設定フレンドリーですきれいなアプローチを提供します
from keras.backend.tensorflow_backend import set_session
...
def __init__(self):
config = self.keras_resource()
self.init_model(config)
def init_model(self, _config, *args):
session = tf.Session(config=_config)
self.graph = session.graph
#set configured session
set_session(session)
self.model = load_model(file_path)
def keras_resource(self):
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
return config
def predict_target(self, to_predict):
with self.graph.as_default():
predict = self.model.predict(to_predict)
return predict
モデルをロードした直後にmodel._make_predict_function()
`を追加します
# Model reload from jSON:
print('Load model...')
json_file = open('models/model_temp.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
keras_model_loaded = model_from_json(loaded_model_json)
print('Model loaded...')
# Weights reloaded from .h5 inside the model
print('Load weights...')
keras_model_loaded.load_weights("models/Model_temp.h5")
print('Weights loaded...')
keras_model_loaded._make_predict_function()
Ya彼らは、kerasを使用してモデルから予測するときのバグです。 Kerasは何らかのエラーのためにグラフを作成できません。テンソルフローを使用して、モデルから画像を予測してください。このコード行を置き換えるだけです
ケラスコード:
_features = model_places.predict( img )
_
テンソルフローコード:
_import tensorflow as tf
graph = tf.get_default_graph()
_
このライブラリをコードにインポートして置き換えます。
_ with graph.as_default():
features = model_places.predict( img ).tolist()
_
問題が解決しない場合:
それでも問題が解決しない場合は、グラフを更新してください。
コードは問題ないので、クリーンな環境で実行すると解決するはずです。
〜/ .keras /でkerasキャッシュをクリアします
適切なパッケージを使用して、新しい環境で実行します(anacondaで簡単に実行できます)
新しいセッションにいることを確認してください。keras.backend.clear_session()
は既存のtfグラフをすべて削除する必要があります。
ケラスコード:
_keras.backend.clear_session()
features = model_places.predict( img )
_
TensorFlowコード:
_import tensorflow as tf
with tf.Session() as sess:
tf.reset_default_graph()
_