c++ - cvSVM 训练对 HOGDescriptor 的结果很差

标签 c++ opencv svm

我的目标是训练 SVM 并获得支持 vector ,我可以将其插入 opencv 的 HOGdescriptor 以进行对象检测。

我收集了 4000~ 个正样本和 15000~ 个负样本,并使用 opencv 提供的 SVM 进行训练。结果给了我太多误报。(每张图片最多 20 个)我会剪掉误报并将它们添加到负片池中以重新训练。有时我会得到更多的误报!我尝试将 hogdescriptor 的 L2HysThreshold 向上调整到 300,但没有明显改善。我的阳性和阴性池是否足够大?

SVM 训练也比预期快得多。我曾尝试使用大小为 2916 和 12996 的特征向量,分别尝试使用灰度图像和彩色图像。 SVM 训练的时间从未超过 20 分钟。我使用 auto_train。我是机器学习的新手,但据我所知,使用像我这样大的数据集进行训练至少需要一天时间,不是吗?

我相信 cvSVM 没有做太多学习,根据 http://opencv-users.1802565.n2.nabble.com/training-a-HOG-descriptor-td6363437.html , 它不适合这个目的。有 cvSVM 经验的人对此有更多意见吗?

我正在考虑使用 SVMLight http://svmlight.joachims.org/但看起来没有办法可视化 SVM 超平面。我有哪些选择?

我使用 opencv2.4.3 并为 hogdescriptor 尝试了以下设置

hog.winSize = cv::Size(100,100);
hog.cellSize = cv::Size(5,5);
hog.blockSize = cv::Size(10,10);
hog.blockStride = cv::Size(5,5); //12996 feature vector

hog.winSize = cv::Size(100,100);
hog.cellSize = cv::Size(10,10);
hog.blockSize = cv::Size(20,20);
hog.blockStride = cv::Size(10,10); //2916 feature vector

最佳答案

  1. 您的第一个描述符维度太大,没有任何用处。要形成任何可靠的 SVM 超平面,您至少需要与描述符维数相同数量的正样本和负样本。这是因为理想情况下,您需要在超平面的每个维度上分离信息。
  2. 除非您为 SVM 训练器提供偏差参数(cvSVM 可能不可用),否则正样本和负样本的数量应该大致相同。
  3. 不能保证 HOG 是适合您要解决的问题类型的描述符。您能否目测确认您尝试检测的物体在所有样本中具有不同的形状和相似的方向?例如,单一类型的花可能具有独特的形状,但许多类型的花在一起并不具有相同的独特形状。竹子具有独特的形状,但可能无法轻易与其他物体区分开来,或者在所有示例图像中可能具有不同的方向。
  4. cvSVM 通常不是用于为 OpenCV HOG 训练 SVM 的工具。使用二进制形式的 SVMLight(不是免费用于商业目的)或 libSVM(可以用于商业目的)。使用您的 C++/OpenCV 代码计算所有样本的 HOG,并以 SVMLight/libSVM 的正确输入格式将其写入文本文件。使用任一程序使用具有最佳 C 的线性核来训练模型。通过在循环中更改 C 的同时搜索最佳精度来找到最佳 C。通过查找所有支持 vector ,将 alpha 值乘以每个相应的支持 vector ,然后为每个维度添加所有支持 vector ,计算检测器 vector (N+1 维 vector ,其中 N 是描述符的维数)生成的 alpha * 值来查找 ND vector 。作为最后一个元素,添加 -b,其中 b 是超平面偏差(您可以在 SVMLight/libSVM 训练的模型文件中找到它)。将此 N+1 维检测器提供给 HOGDescriptor::setSVMDetector() 并使用 HOGDescriptor::detect()HOGDescriptor::detectMultiScale() 用于检测。

关于c++ - cvSVM 训练对 HOGDescriptor 的结果很差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18448842/

相关文章:

c++ - Travis CI 上 Boost 中对 `std::__cxx11::basic_string 的 undefined reference

python - 如何进行稳定的眼角检测?

opencv - 使用 opencv 构建自定义 svm 内核矩阵

python - 我们如何使用 Decision_function(X) One-Class-SVM 计算异常分数

c++ - 了解 OpenGL 中的绑定(bind)?

c++ - 在 read() 之前检查 boost::asio 缓冲区数据是否存在

c++ - 继承运算符 +()

python - 缝合最终尺寸和偏移

javascript - 转换 tfjs 模型以在 C++ 中的 Tensorflow 中使用

r - SVM-RFE算法在R中的实现