Тензор не является элементом этого графика; развертывание модели Keras
Im развертывание модели keras и отправка тестовых данных в модель через флягу api. У меня два файла:
Во-первых: My Flask App:
# Let 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)
Второй: файл Im, используемый для отправки данных json, отправляемых в конечную точку api:
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)
Я получаю этот ответ от Flask относительно Tensorflow:
ValueError: Тензорный тензор ("dense_6/BiasAdd: 0", shape = (?, 1), dtype = float32) не является элементом этого графика.
Моя модель keras - это простая модель с 6 плотными слоями и поезда без ошибок.
Есть идеи?
Ответы
Ответ 1
Flask использует несколько потоков. Проблема, с которой вы сталкиваетесь, заключается в том, что модель tenorflow не загружается и не используется в одном потоке. Один из обходных путей - заставить тензорный поток использовать график по умолчанию.
Добавьте это после загрузки вашей модели
global graph
graph = tf.get_default_graph()
И внутри вашего прогноза
with graph.as_default():
y_hat = keras_model_loaded.predict(predict_request, batch_size=1, verbose=1)
Ответ 2
Намного проще обернуть вашу модель keras в класс, и этот класс может отслеживать свой собственный график и сеанс. Это предотвращает проблемы, которые могут быть вызваны несколькими потоками/процессами/моделями, что почти наверняка является причиной вашей проблемы. В то время как другие решения будут работать, это, безусловно, самый общий, масштабируемый и охватывающий все. Используйте это:
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
Ответ 3
Сразу после загрузки модели добавьте 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()
Ответ 4
Оказывается, этот способ не требует вызова clear_session и в то же время удобен для конфигурации, используя объект графа из настроенного сеанса session = tf.Session(config=_config); self.graph = session.graph
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
Ответ 5
Я. Это их ошибка, когда вы прогнозируете по модели с керасом. Керас не сможет построить график из-за какой-то ошибки. Попробуйте предсказать изображения из модели с помощью тензорного потока. Просто замените эту строку кода
Код 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/
Запустите в новой среде с правильными пакетами (это легко сделать с помощью anaconda)
Убедитесь, что вы находитесь на новом сеансе, keras.backend.clear_session()
должен удалить все существующие графики tf.
Код Keras:
keras.backend.clear_session()
features = model_places.predict( img )
Код ТензорФлоу:
import tensorflow as tf
with tf.Session() as sess:
tf.reset_default_graph()