Попытка обернуть модель keras в REST-приложении для колб, но получить ValueError - PullRequest
0 голосов
/ 16 сентября 2018

Я могу создать простую модель keras, запустив

python create-flask-model.py

create-flask-model.py

##points in square that are in or out of a quarter circle
import random
import math
import numpy as np
from keras.models import Sequential
from keras.layers import Dense

training_size = 8000
testing_size = 2000
batch_size = 10
epoch_no = 30
modelStructureFileName = 'simple-flask.json'
modelWeightFileName = 'simple-flask.h5'

def get_model():
    model = Sequential()
    model.add(Dense(4, input_dim=2, activation='tanh'))
    model.add(Dense(4, activation='tanh'))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(loss='binary_crossentropy',optimizer='rmsprop')
    return model

def get_data_instances(size):
    result = []
    for i in range(0, size):
        number_1 = random.uniform(0,1)
        number_2 = random.uniform(0,1)
        squares = math.pow(number_1,2) + math.pow(number_2,2)
        target = 0
        if squares < 0.49:
            target = 1
        line = number_1,number_2,target
        result.append(line)
    return np.array(result)

##create data and split in to training and test, features and targets
data_instances = get_data_instances(training_size+testing_size)
train_x, train_y = data_instances[:training_size,0:2], data_instances[:training_size,-1]
test_x, test_y = data_instances[training_size:,0:2], data_instances[training_size:,-1]

##load model and train
model = get_model()
history = model.fit(train_x, train_y, batch_size=batch_size, epochs=epoch_no, validation_data=(test_x, test_y))

##save the model
model_json = model.to_json()
with open(modelStructureFileName, 'w') as json_file:
    json_file.write(model_json)
model.save_weights(modelWeightFileName)

##how to get prediction for an instance
#instance = np.array([0.3, 0.6])
#instance = instance.reshape(1,2)
#yhat = model.predict(instance)
#print(yhat)

Я хочу загрузить полученную модельв приложение колбу и иметь возможность передавать экземпляры как объекты JSON и делать прогнозы и возвращать.Запуск

python flask-app.py

в том же каталоге, что и файлы модели json и h5.

flask-app.py

import json
import numpy as np
from flask import Flask
from keras.models import model_from_yaml

app = Flask(__name__)
model = None
modelStructureFileName = 'simple-flask.json'
modelWeightFileName = 'simple-flask.h5'

def load_model():
    yaml_file = open(modelStructureFileName, 'r')
    loaded_model_yaml = yaml_file.read()
    yaml_file.close()
    global model
    model = model_from_yaml(loaded_model_yaml)
    model.load_weights(modelWeightFileName)

@app.route('/flask/<input>', methods=['GET'])
def predict(input):
    input_array = json.loads(input)
    instance = np.array(input_array)
    instance = instance.reshape(1,2)
    yhat = model.predict(instance)
    return str(yhat)

if __name__ == '__main__':
    load_model()
    app.run(port = 9000, debug = True)

Если яперейдите к http://localhost:9000/flask/[0.3,0.6] Я получаю сообщение об ошибке

builtins.ValueError
ValueError: Tensor Tensor("dense_3/Sigmoid:0", shape=(?, 1), dtype=float32) is not an element of this graph.

Я думаю, что это как-то связано с масштабом модели в приложении, но не могу понять это.Если я загружаю модель в методе запроса, он работает один раз, но затем завершается с ошибкой.Я хочу загрузить модель только один раз.Как я могу заставить приложение для работы с колбой работать так, как ожидалось?

РЕДАКТИРОВАТЬ: в итоге я использовал бутылку вместо колбы, и это не сработало.

bottle-app.py

from bottle import route, run
import json
import numpy as np
from keras.models import model_from_yaml

modelStructureFileName = 'simple-flask.json'
modelWeightFileName = 'simple-flask.h5'

yaml_file = open(modelStructureFileName, 'r')
loaded_model_yaml = yaml_file.read()
yaml_file.close()
model = model_from_yaml(loaded_model_yaml)
model.load_weights(modelWeightFileName)
print('model loaded')

@route('/bottle/<input>')
def predict(input):
    input_array = json.loads(input)
    instance = np.array(input_array)
    instance = instance.reshape(1,2)
    yhat = model.predict(instance)
    print(input_array, yhat)
    return str(yhat[0][0])

run(host='localhost', port=9000, debug=True)

1 Ответ

0 голосов
/ 17 сентября 2018

Это происходит потому, что в колбе по умолчанию включено несколько потоков. Модели Tensorflow плохо работают с несколькими потоками. Подробнее об этом вы можете прочитать по ссылкам ниже

У меня сработал следующий обходной путь

global graph
graph = tf.get_default_graph()

with graph.as_default():
   model.compile()
   model.fit()

with graph.as_default():
   model.predict()
...