OpenCV图像分类预测概率远低于教程结果问题求助
问题根因
你运行结果概率偏低的核心原因是缺少了Softmax归一化步骤:
你调用model.forward()得到的outputs是DenseNet输出的原始logits值,不是归一化后的分类概率,你参考的Python教程里用NumPy对logits做了Softmax计算,把输出映射到了0-1的概率区间,你的C++代码直接取了原始logits的最大值,自然得到的数值远低于预期。
另外你现有代码还存在未声明classIdPoint变量的疏漏,运行时会编译报错。
修复方案
补充Softmax计算逻辑,同时补全缺失的变量声明即可,修正后的完整代码如下:
#include <iostream> #include <fstream> #include <cmath> #include <opencv2/opencv.hpp> #include <opencv2/dnn.hpp> #include <opencv2/dnn/all_layers.hpp> using namespace std; using namespace cv; using namespace dnn; // Softmax实现,将logits转为0-1的概率 void softmax(Mat& input, Mat& output) { exp(input, output); double sum = cv::sum(output)[0]; output /= sum; } int main(int, char**) { vector<string> class_names; ifstream ifs(string("../data/classification_classes_ILSVRC2012.txt").c_str()); string line; while (getline(ifs, line)){ class_names.push_back(line); } auto model = readNet("../data/DenseNet_121.prototxt", "../data/DenseNet_121.caffemodel", "Caffe"); Mat image = imread("../data/tiger.jpg"); Mat blob = blobFromImage(image, 0.01, Size(224, 224), Scalar(104, 117, 123)); model.setInput(blob); Mat outputs = model.forward(); // 补充变量声明 Point classIdPoint; double final_logit; minMaxLoc(outputs.reshape(1, 1), nullptr, &final_logit, nullptr, &classIdPoint); // 对输出做Softmax得到概率 Mat prob; softmax(outputs.reshape(1, 1), prob); double final_prob = prob.at<float>(0, classIdPoint.x); cout << "分类类别:" << class_names[classIdPoint.x] << endl; cout << "匹配概率:" << final_prob * 100 << "%" << endl; return 0; }
额外排查点
如果修复后概率仍有偏差,可以依次检查:
- 模型权重文件
DenseNet_121.caffemodel是否为官方发布的完整权重,避免下载到损坏或不完整的文件 - 输入的
tiger.jpg与教程用图是否完全一致,没有被二次压缩裁剪 - 分类标签文件
classification_classes_ILSVRC2012.txt的索引顺序与模型输出顺序匹配,没有错行漏行
内容的提问来源于stack exchange,提问作者Markus
相关产品推荐
相关产品推荐

