TensorFlow Serving输入格式适配求助:列表与模型所需numpy数组的矛盾
我来帮你分析下问题所在,其实核心就是请求体的嵌套层数不对,导致输入形状不符合模型预期。
问题根源
你现在的请求体写的是"instances": [[value]],其中value是[1,2,3,4,5],这就相当于传递了一个三层嵌套的列表[[[1,2,3,4,5]]],TensorFlow Serving解析后得到的输入形状是[1,1,5](3维张量),但你的模型期望的是一个2维矩阵(比如[1,5],对应批量大小为1的5维样本),所以才会报"In[0] is not a matrix"的错误。
而你本地调用model.predict([[value]])能运行,大概率是Keras做了自动维度适配,但TensorFlow Serving对输入格式的要求更严格,不会自动调整维度。
解决方案
只需要调整请求体中instances字段的嵌套层数,去掉多余的一层即可:
import requests import json value = [1, 2, 3, 4, 5] # 把[[value]]改成[value],减少一层嵌套 body = {"signature_name": "serving_default", "instances": [value]} res = requests.post(url=url, data=json.dumps(body))
这样传递的instances是[[1,2,3,4,5]],对应输入形状为[1,5],正好符合模型对2维矩阵的要求。
额外验证(可选)
如果想确认模型的输入形状要求,可以用TensorFlow的官方工具查看SavedModel的签名信息:
saved_model_cli show --dir /path/to/your/savedmodel --all
在输出中找到serving_default签名的输入部分,你会看到类似这样的信息:
inputs['input_1'] tensor_info: dtype: DT_FLOAT shape: (-1, 5) name: serving_default_input_1:0
其中shape: (-1,5)就表示模型接受批量大小任意、每个样本为5维的输入,和我们调整后的请求格式完全匹配。
另外,你本地的调用其实也可以简化成model.predict([value]),这样和TensorFlow Serving的输入逻辑保持一致,避免混淆。
内容的提问来源于stack exchange,提问作者Juan José Pardo Sierra

