问题描述
我正在使用以下脚本 predictor.py 以从 GCP AI Platform 中托管的 Keras 模型中获取预测。
import os
import pickle
import tensorflow as tf
import numpy as np
import logging
class MyPredictor(object):
def __init__(self,model,bow_model):
self._model = model
self._bow_model = bow_model
def predict(self,instances,**kwargs):
vectors = self.embedding([instances])
vectors = vectors.tolist()
output = self._model.predict(vectors)
return output
def embedding(self,statement):
vector = self._bow_model.transform(statement).toarray()
#vector = vector.to_list()
return vector
@classmethod
def from_path(cls,model_dir):
model_path = os.path.join(model_dir,'model.h5')
model = tf.keras.models.load_model(model_path,compile = False)
preprocessor_path = os.path.join(model_dir,'bow.pkl')
with open(preprocessor_path,'rb') as f:
bow_model = pickle.load(f)
return cls(model,bow_model)
但是我明白
Prediction Failed: Error when checking input: expected dense_input to have shape (2898,) but got array with shape (1,)
问题似乎是由于我在尝试进行实际预测时输入数据的维度,行输出 = self._model.predict([vectors])。模型期望形状为 (2898,)
我觉得这很奇怪...因为当我打印矢量的形状和尺寸时,我得到以下内容
This is the shape
(1,2898)
This is the dim number
2
This is the vector
[[0 0 0 ... 0 0 0]]
所以尺寸和形状都很好,它应该真的可以工作......
此外,我做了一个测试来获取本地存储的模型的预测,并且运行良好。这是测试文件:
import os
import pickle
import tensorflow as tf
import numpy as np
class MyPredictor(object):
def __init__(self,**kwargs):
print("These are the instances ",instances)
vector = self.embedding([instances])
output = self._model.predict(vector)
return output
def embedding(self,statement):
vector = self._bow_model.transform(statement).toarray()
#vector = vector.to_list()
return vector
model_path = 'model.h5'
model = tf.keras.models.load_model(model_path,compile = False)
preprocessor_path = 'bow.pkl'
with open(preprocessor_path,'rb') as f:
bow_model = pickle.load(f)
instances = 'test'
predictor = MyPredictor(model,bow_model)
outputs = predictor.predict(instances)
print(outputs)
解决方法
解决了!
在这行 output = self._model.predict([vectors])
在那之后,我遇到了另一个错误,即预测的输出不是 json 可序列化的。我只是通过将 .tolist() 添加到返回 return output.to_list()
import os
import pickle
import tensorflow as tf
import numpy as np
import logging
class MyPredictor(object):
def __init__(self,model,bow_model):
self._model = model
self._bow_model = bow_model
def predict(self,instances,**kwargs):
vectors = self.embedding([instances])
vectors = vectors.tolist()
output = self._model.predict([vectors])
return output.to_list()
def embedding(self,statement):
vector = self._bow_model.transform(statement).toarray()
#vector = vector.to_list()
return vector
@classmethod
def from_path(cls,model_dir):
model_path = os.path.join(model_dir,'model.h5')
model = tf.keras.models.load_model(model_path,compile = False)
preprocessor_path = os.path.join(model_dir,'bow.pkl')
with open(preprocessor_path,'rb') as f:
bow_model = pickle.load(f)
return cls(model,bow_model)