问题叙述
Keras模型部署在云上,
按照正常方法是把model实例化在类初始化之处,这样可以避免如下错误:
ValueError: Tensor Tensor(“xxx:0”, shape=(), dtype=float32) is not an element of this graph.
正常写法如下:
from keras.models import load_model
class Pikachu():
def __init__(self, path):
# load model to memory
self.model = load_model(path)
def inference(self, input):
# run model
return self.model.predict(x=input)
pikachu = Pikachu('your model path.h5')
pikachu.inference('your image')
这样写的好处是只需要一次把model文件载入到keras并带入后端Tensorflow的静态图中,
直到程序结束前都可以直接访问静态图无需别的操作了。
但是这样会报如下错误:
Tensor(“Placeholder:0”, shape=(x), dtype=int32) must be from the same graph as Tensor(“Variable:0”, shape=(x), dtype=float32).
分析原因,Tensorflow和Django存在冲突,Django会把一开始我们声明的Keras后端静态图的内存清理,
所以后来输入静态图时Keras会临时声明一个空静态图,与之前类初始化时创建好的静态图不同。
解决方法,我们不使用Keras默认声明静态图,而是自己主动声明静态图通道,
这样Keras会把模型图创建在我们声明的静态图中,Django此时不会更改主动声明的静态图内存。
代码如下:
from keras.models import load_model
import tensorflow as tf
class Pikachu():
def __init__(self, path):
# init backend graph
self._GRAPH_ = tf.get_default_graph()
# load model to memory
self.model = load_model(path)
def inference(self, input):
# run model
with self._GRAPH_.as_default():
output = self.model.predict(x=input)
return output
pikachu = Pikachu('your model path.h5')
pikachu.inference('your image')