You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TensorFlow Serving部署目标检测模型请求维度报错问题咨询

TensorFlow Serving目标检测请求张量维度不匹配问题

问题现象

完成TensorFlow Serving目标检测实例搭建后,发起预测请求触发张量维度不匹配报错。使用tolist()将图像numpy数组转为JSON兼容格式后,TensorFlow Serving解析得到形状为[339450,3]的张量,与模型预期输入形状不符。

报错信息

Data: {"signature_name": "serving_default", "instances": ... 58, 63], [35, 59, 63], [37, 58, 63], [43, 67, 71]]]}
{'error': 'Specified a list with shape [?,?,3] from a tensor with shape [339450,3]\n\t [[{{function_node __inference_call_func_9686}}{{node map/TensorArrayUnstack/TensorListFromTensor}}]]'}

原始请求代码

import requests
import json
from PIL import Image
import numpy

# Load image
img = Image.open("Hilarious-Car-License-Plates-1.jpg")
img_np = numpy.array(img.getdata())
img_np.resize(tuple([1] + list(img_np.shape)))
data = json.dumps({"signature_name": "serving_default", "instances": img_np.tolist()})
print('Data: {} ... {}'.format(data[:50], data[len(data)-52:]))

headers = {"content-type": "application/json"}
json_response = requests.post('http://localhost:8501/v1/models/plate_detect:predict', data=data, headers=headers)
response = json.loads(json_response.text)

print(response)

模型输入要求

从模型元数据可以看到,serving_default签名的输入张量input_tensor要求形状为[1, -1, -1, 3],即batch大小为1、通道数为3的任意尺寸RGB图像,数据类型为DT_UINT8。
完整元数据如下:

{
"model_spec":{
 "name": "plate_detect",
 "signature_name": "",
 "version": "1"
}
,
"metadata": {"signature_def": {
 "signature_def": {
  "serving_default": {
   "inputs": {
    "input_tensor": {
     "dtype": "DT_UINT8",
     "tensor_shape": {
      "dim": [
       {
        "size": "1",
        "name": ""
       },
       {
        "size": "-1",
        "name": ""
       },
       {
        "size": "-1",
        "name": ""
       },
       {
        "size": "3",
        "name": ""
       }
      ],
      "unknown_rank": false
     },
     "name": "serving_default_input_tensor:0"
    }
   },
   "outputs": {
    "detection_boxes": {
     "dtype": "DT_FLOAT",
     "tensor_shape": {
      "dim": [
       {
        "size": "1",
        "name": ""
       },
       {
        "size": "100",
        "name": ""
       },
       {
        "size": "4",
        "name": ""
       }
      ],
      "unknown_rank": false
     },
     "name": "StatefulPartitionedCall:1"
    },
    "raw_detection_boxes": {
     "dtype": "DT_FLOAT",
     "tensor_shape": {
      "dim": [
       {
        "size": "1",
        "name": ""
       },
       {
        "size": "1917",
        "name": ""
       },
       {
        "size": "4",
        "name": ""
       }
      ],
      "unknown_rank": false
     },
     "name": "StatefulPartitionedCall:6"
    },
    "detection_scores": {
     "dtype": "DT_FLOAT",
     "tensor_shape": {
      "dim": [
       {
        "size": "1",
        "name": ""
       },
       {
        "size": "100",
        "name": ""
       }
      ],
      "unknown_rank": false
     },
     "name": "StatefulPartitionedCall:4"
    },
    "raw_detection_scores": {
     "dtype": "DT_FLOAT",
     "tensor_shape": {
      "dim": [
       {
        "size": "1",
        "name": ""
       },
       {
        "size": "1917",
        "name": ""
       },
       {
        "size": "2",
        "name": ""
       }
      ],
      "unknown_rank": false
     },
     "name": "StatefulPartitionedCall:7"
    },
    "detection_anchor_indices": {
     "dtype": "DT_FLOAT",
     "tensor_shape": {
      "dim": [
       {
        "size": "1",
        "name": ""
       },
       {
        "size": "100",
        "name": ""
       }
      ],
      "unknown_rank": false
     },
     "name": "StatefulPartitionedCall:0"
    },
    "detection_multiclass_scores": {
     "dtype": "DT_FLOAT",
     "tensor_shape": {
      "dim": [
       {
        "size": "1",
        "name": ""
       },
       {
        "size": "100",
        "name": ""
       },
       {
        "size": "2",
        "name": ""
       }
      ],
      "unknown_rank": false
     },
     "name": "StatefulPartitionedCall:3"
    },
    "detection_classes": {
     "dtype": "DT_FLOAT",
     "tensor_shape": {
      "dim": [
       {
        "size": "1",
        "name": ""
       },
       {
        "size": "100",
        "name": ""
       }
      ],
      "unknown_rank": false
     },
     "name": "StatefulPartitionedCall:2"
    },
    "num_detections": {
     "dtype": "DT_FLOAT",
     "tensor_shape": {
      "dim": [
       {
        "size": "1",
        "name": ""
       }
      ],
      "unknown_rank": false
     },
     "name": "StatefulPartitionedCall:5"
    }
   },
   "method_name": "tensorflow/serving/predict"
  },
  "__saved_model_init_op": {
   "inputs": {},
   "outputs": {
    "__saved_model_init_op": {
     "dtype": "DT_INVALID",
     "tensor_shape": {
      "dim": [],
      "unknown_rank": true
     },
     "name": "NoOp"
    }
   },
   "method_name": ""
  }
 }
}
}
}

问题根因

  • 图像预处理逻辑错误:img.getdata()返回的是所有像素值的平铺迭代器,直接转numpy数组得到的形状是(总像素数, 3),也就是报错里的[339450,3],完全丢失了图像原有的高度、宽度二维结构。
  • 维度变换API使用错误:numpy.ndarray.resize()是原地修改数组的方法,当目标形状的元素总数和原数组不匹配时,会自动截断/重复填充元素,不会按语义增加维度,无法得到预期的四维输入结构。
  • 发起请求时不需要显式指定输入图像形状,只要传入的嵌套列表结构和模型要求的张量维度对齐即可,当前报错完全是输入数组维度预处理错误导致的。

修复方案

修正图像加载和维度处理逻辑,不要用img.getdata()读取像素,直接对PIL Image对象转numpy数组即可保留(高度, 宽度, 3)的原始图像结构,再通过np.expand_dims增加batch维度,得到符合模型要求的四维数组。
修正后的代码如下:

import requests
import json
from PIL import Image
import numpy as np

# 加载图像
img = Image.open("Hilarious-Car-License-Plates-1.jpg")
# 直接转numpy数组,保留(高, 宽, 3)的原始图像结构,指定类型为uint8匹配模型输入要求
img_np = np.array(img, dtype=np.uint8)
# 增加batch维度,得到形状为(1, 高, 宽, 3)的输入,完全匹配模型输入要求
img_np = np.expand_dims(img_np, axis=0)
# 建议打印形状确认,避免维度错误
print(f"输入张量形状: {img_np.shape}")

data = json.dumps({"signature_name": "serving_default", "instances": img_np.tolist()})
headers = {"content-type": "application/json"}
json_response = requests.post('http://localhost:8501/v1/models/plate_detect:predict', data=data, headers=headers)
response = json.loads(json_response.text)
print(response)

注意事项

  • 不要使用原地操作的ndarray.resize()做维度变换,这类API会按内存平铺顺序重排元素,不适合做语义层面的维度增删,维度调整优先使用np.expand_dims、np.reshape等不会打乱元素顺序的API。
  • 数组转列表发请求前,一定要打印shape属性确认维度符合模型输入要求,再做序列化操作。

内容的提问来源于stack exchange,提问作者agm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 04:33:26