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

ONNXRuntime C++如何获取动态输出Tensor的真实形状?

问题描述

我正在使用ONNXRuntime C++运行YOLOX模型,代码如下:

std::vector<Ort::Value> ort_inputs;
for (int i = 0; i < inputNames.size(); ++i) {
  ort_inputs.emplace_back(Ort::Value::CreateTensor<float>(
      memoryInfo, static_cast<float *>(inputs[i].data), inputs[i].get_size(),
      inputShapes[i].data(), inputShapes[i].size()));
}

std::vector<Ort::Value> outputTensors =
    session.Run(Ort::RunOptions{nullptr}, inputNames.data(),
                ort_inputs.data(), 1, outputNames.data(), outputNames.size());

模型为yolox_tiny_cpunms.onnx,输入输出详情如下:

NameShapeInput/OutputDtype
input[1, 3, 416, 416]Inputfloat32
boxes[1, -1, -1]Outputfloat32
scores[1, -1]Outputfloat32
labels[1, -1]Outputint64

模型输出为动态形状,但当前代码得到的输出Tensor形状为[1, 0, 4]、[1, 0]、[1,0],请问如何在C++中获取正确的输出形状?


解决方法

出现[1,0,...]的形状通常说明模型推理后未检测到目标,或是输入预处理存在问题。若确认输入图像包含目标,可按以下步骤处理:

  1. 检查输入预处理是否符合YOLOX要求

    • 输入图像需转为RGB格式,再按模型训练时的逻辑做归一化(如除以255,或(img - mean)/std)
    • 输入尺寸必须为416x416,需保持图像原始宽高比,建议用letterbox填充方式避免拉伸变形
    • 确保输入数据内存布局为NCHW(批量、通道、高度、宽度),这是ONNX模型的标准输入格式
  2. 正确获取动态输出的实际形状
    推理完成后,通过ONNXRuntime的API直接读取输出Tensor的实际形状:

// 遍历所有输出Tensor
for (size_t i = 0; i < outputTensors.size(); ++i) {
  // 获取Tensor的类型与形状信息
  auto tensor_info = outputTensors[i].GetTensorTypeAndShapeInfo();
  // 提取实际形状
  std::vector<int64_t> actual_output_shape = tensor_info.GetShape();

  // 打印验证形状
  std::cout << "Output " << outputNames[i] << " shape: ";
  for (auto dim : actual_output_shape) {
    std::cout << dim << " ";
  }
  std::cout << std::endl;

  // 按需获取输出数据指针
  if (outputNames[i] == "boxes") {
    float* boxes_data = outputTensors[i].GetTensorMutableData<float>();
    // 根据actual_output_shape处理检测框数据
  } else if (outputNames[i] == "scores") {
    float* scores_data = outputTensors[i].GetTensorMutableData<float>();
  } else if (outputNames[i] == "labels") {
    int64_t* labels_data = outputTensors[i].GetTensorMutableData<int64_t>();
  }
}
  1. 验证ONNXRuntime会话配置
    • 创建Session时不要手动固定输出形状,默认配置已支持动态形状:
      Ort::SessionOptions session_options;
      // 无需额外设置固定形状,保持默认即可
      Ort::Session session(env, model_path.c_str(), session_options);
      
    • 若模型是带NMS的YOLOX导出版本,需确认导出时的置信度、NMS阈值参数是否合理,避免过滤掉所有目标

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 06:30:55