web-dev-qa-db-ja.com

テンソルはこのグラフの要素ではありません。 Kerasモデルの展開

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密層モデルであり、エラーなしでトレーニングします。

何か案は?

20
DataGuy

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)
27
Satyajit

ケラスモデルをクラスにラップする方がはるかに簡単で、そのクラスは独自のグラフとセッションを追跡できます。これにより、複数のスレッド/プロセス/モデルが原因で発生する可能性のある問題が回避されます。これは、ほぼ確実に問題の原因です。他のソリューションでも機能しますが、これが最も一般的で、スケーラブルであり、すべてをキャッチします。これを使用してください:

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
9
Andrew Louw

この方法は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
1
Ari Gold

モデルをロードした直後に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()
1
Prateek Gulati

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()
_
0
Sohaib Anwaar