使用C++ ONNX Runtime调用ML.NET导出模型时遇访问冲突求助
问题分析与解决方案
你的核心问题是错误地将两个独立输入合并为单个张量传入模型,同时session.Run()的参数与模型输入输出数量不匹配。以下是针对你的ONNX模型输入输出规格的正确实现流程:
关键错误点
- 模型要求两个独立输入:
Features(1x7 float)和code_point(1x1 float),你将其合并为1x8张量,违背了模型的输入定义。 session.Run()调用时,输入张量数量传递为1,但实际需要传递2个输入张量;输出节点数量需与你指定的输出节点列表长度一致(即4)。- 注意
code_point实际为uint32_t类型,需要转换为float后再传入模型。
正确实现代码
// 1. 准备两个输入的数据 constexpr size_t features_size = 7; constexpr size_t code_point_size = 1; std::vector<float> features_values(features_size); // 初始化Features数据(示例:填充测试值) for (size_t i = 0; i < features_size; ++i) { features_values[i] = static_cast<float>(i); } uint32_t actual_code_point = 1234; // 实际的uint32_t数据 std::vector<float> code_point_values(code_point_size); code_point_values[0] = static_cast<float>(actual_code_point); // 转换为float // 2. 定义输入节点名称和各自的维度 std::vector<const char*> input_node_names = {"Features", "code_point"}; std::vector<std::vector<int64_t>> input_node_dims = {{1, 7}, {1, 1}}; // 对应两个输入的形状 // 3. 创建两个输入张量 auto memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault); auto features_tensor = Ort::Value::CreateTensor<float>( memory_info, features_values.data(), features_size, input_node_dims[0].data(), input_node_dims[0].size()); auto code_point_tensor = Ort::Value::CreateTensor<float>( memory_info, code_point_values.data(), code_point_size, input_node_dims[1].data(), input_node_dims[1].size()); // 将两个张量放入数组中 std::vector<Ort::Value> input_tensors; input_tensors.push_back(std::move(features_tensor)); input_tensors.push_back(std::move(code_point_tensor)); // 4. 定义输出节点名称 std::vector<const char*> output_node_names = { "Features.output", "code_point.output", "PredictedLabel.output", "Score.output" }; // 5. 执行推理:输入数量为2,输出数量为4 auto output_tensors = session.Run( Ort::RunOptions{nullptr}, input_node_names.data(), input_tensors.data(), input_tensors.size(), // 传入2个输入张量 output_node_names.data(), output_node_names.size()); // 输出数量为4 // 6. 解析输出结果(示例) // 解析PredictedLabel.output float* predicted_label = output_tensors[2].GetTensorMutableData<float>(); std::cout << "Predicted Label: " << predicted_label[0] << std::endl; // 解析Score.output(1x94的结果) float* score = output_tensors[3].GetTensorMutableData<float>(); for (size_t i = 0; i < 94; ++i) { std::cout << "Score " << i << ": " << score[i] << std::endl; }
额外注意事项
- 确保你使用的ONNX Runtime版本与导出模型时的ML.NET版本兼容,避免因版本不匹配导致的异常。
- 如果运行时仍有访问冲突,可检查
session的初始化是否正确(如模型路径是否正确、是否指定了x64环境)。 - 若
code_point在模型中实际需要整数类型,可在导出ONNX模型时指定正确的数据类型,避免类型转换带来的潜在问题。
内容的提问来源于stack exchange,提问作者vvg
相关产品推荐
相关产品推荐

