ONNX C++ API中如何实现类似scikit-learn predict_proba的概率输出?
在ONNX Runtime C++中获取分类概率(等价于Scikit-learn的predict_proba)
ONNX Runtime C++ API没有直接对应predict_proba的方法,能否获取类别概率完全取决于你导出的ONNX模型是否包含概率输出分支,以下是具体解决步骤:
1. 确认ONNX模型的输出类型
用Netron可视化工具打开你的ONNX模型,查看输出节点:
- 如果输出是维度为
[N, C](N为样本数,C为类别数)的浮点型张量,且代表类别概率,可直接读取。 - 如果输出是未经过归一化的logits(原始得分),则需要手动计算Softmax转换为概率。
2. 修改C++代码获取概率
场景1:模型直接输出概率
将原代码中获取结果的类型从int改为float,直接读取概率值:
// 创建输入张量(与原代码一致) auto inputOnnxTensor = Ort::Value::CreateTensor<float>(memoryInfo, inputValues.data(), inputValues.size(), inputDims.data(), inputDims.size()); // 运行会话获取输出 auto outputValues = session.Run(Ort::RunOptions{ nullptr }, inputNames.data(), &inputOnnxTensor, 1, outputNames.data(), 1); // 获取概率数据(浮点型) float* probabilities = outputValues[0].GetTensorMutableData<float>(); // 示例:遍历单样本的所有类别概率 int numClasses = ...; // 根据模型输出维度确定类别数 for (int idx = 0; idx < numClasses; ++idx) { std::cout << "类别" << idx << "概率:" << probabilities[idx] << std::endl; }
场景2:模型输出logits,需手动计算Softmax
如果模型输出的是logits,实现Softmax函数将其转换为概率:
// 获取logits数据 float* logits = outputValues[0].GetTensorMutableData<float>(); int numClasses = ...; // 类别数 // 实现Softmax归一化 std::vector<float> softmax(float* logits, int classCount) { std::vector<float> expVals(classCount); float sumExp = 0.0f; // 计算各logits的指数值 for (int i = 0; i < classCount; ++i) { expVals[i] = std::exp(logits[i]); sumExp += expVals[i]; } // 归一化得到概率 std::vector<float> probs(classCount); for (int i = 0; i < classCount; ++i) { probs[i] = expVals[i] / sumExp; } return probs; } // 使用示例 std::vector<float> probabilities = softmax(logits, numClasses);
3. 导出ONNX模型的注意事项
如果原模型是Scikit-learn分类器,用skl2onnx导出时,需确保配置正确以输出概率:
- 大部分分类器默认导出概率输出,但部分模型需显式设置
options={'raw_scores': False}来禁用logits输出,强制导出概率。
内容的提问来源于stack exchange,提问作者Pedram Hooshangitabrizi
相关产品推荐
相关产品推荐

