【问题标题】:How to speed up svm.predict?如何加速 svm.predict?
【发布时间】:2013-04-17 23:54:44
【问题描述】:

我正在编写一个滑动窗口来提取特征并将其输入 CvSVM 的预测函数。 但是,我偶然发现的是 svm.predict 函数相对较慢。

基本上,窗口以固定的步长滑动穿过图像,在图像比例数上。

  • 遍历图像的速度加上每个特征的提取速度 窗口大约需要 1000 毫秒(1 秒)。
  • 包含由 adaboost 训练的弱分类器导致大约 1200 毫秒(1.2 秒)
  • 但是,当我通过功能时(已标记为正面 由弱分类器)到 svm.predict 函数,整体速度 减慢到大约 16000 毫秒(16 秒)
  • 先尝试收集所有“正面”特征,然后再传递给 svm.predict 利用 TBB 的线程导致 19000 毫秒(19 秒),可能是由于创建线程所需的开销等原因。

我的 OpenCV 构建被编译为包含 TBB(线程)和 OpenCL (GPU) 功能。

有没有人设法加速 OpenCV 的 SVM.predict 函数?

我已经被这个问题困扰了很长一段时间,因为通过我的测试数据运行这个检测算法来进行统计和阈值调整是令人沮丧的。

非常感谢您阅读本文!

【问题讨论】:

  • SVM 的决策函数需要 O(nSV * f) 时间,其中 nSV 是支持向量的数量,f 是特征的数量。你能检查一下 SVM 模型,看看它有多少个支持向量吗?
  • 我查了一下,有4417个支持向量,特征大小是3780。
  • 这是一个相当大的 SVM。如果您使用更强的正则化进行训练,SV 的数量可能会减少。
  • 只是从你的头顶,使用 RandomForest 比 SVM 更快吗? (不考虑精度损失)
  • 抱歉,我实际上并不熟悉 OpenCV。我只是碰巧对 SVM 进行了一些攻击。

标签: opencv machine-learning computer-vision svm object-detection


【解决方案1】:

我不确定您要提取什么特征,但从特征的大小 (3780) 我会说您正在提取 HOG。 cv::HOGDescriptor 类中有一种非常健壮、优化和快速的 HOG“预测”方式。你需要做的就是

  1. 提取您的 HOG 进行训练
  2. 将它们放入 svmLight 格式
  3. 使用 svmLight 线性核训练模型
  4. 计算预测所需的 3780 + 1 维向量
  5. 将向量提供给cv::HOGDescriptor对象的setSvmDetector()方法
  6. 使用detect()detectMultiScale() 方法进行检测

以下文档有关于如何实现你想要做的事情的非常好的信息:http://opencv.willowgarage.com/wiki/trainHOG 虽然我必须警告你原始程序中存在一个小问题,但它教你如何正确处理这个问题.

【讨论】:

  • 啊,我不使用 HOGDescriptor 是有原因的,因为我正在扩展它以使用其他特征(例如表面法线等)在深度图像上使用它。我需要训练自己的 HoG 并收集统计数据作为与其他方法的基线比较。
  • 那么使用HOGDescriptor 正在使用的技术来加快速度。 HOGDescriptor 预先计算每个 cell 的 HOG 并将它们存储在缓存映射中,然后滑动窗口使用预先计算的数字来加快速度。唯一的问题是滑动窗口必须移动一个单元格大小才能使此方法有效。你不能有一个移动单个像素的滑动窗口。
  • 嗯,问题不在于预先计算 HoG 描述符,减速在于 svm.predict。所有这些使用积分直方图对整个窗口和比例空间进行的特征计算对于我的需要来说都非常快(~1 秒)。但是 svm.predict 大大减慢了整个过程。
  • 使用线性内核,计算代表 SVM 模型超平面的加权向量(上述文档描述的方式),忘记SVM.predict() 并通过做加权的点积来进行自己的预测向量和任何给定的候选向量。
【解决方案2】:

(上面发布的答案是为了正式化我的 cmets:)

SVM 的预测算法需要 O(nSV * f) 时间,其中 nSV 是支持向量的数量,f 是特征的数量。支持向量的数量可以通过更强的正则化训练来减少,即通过增加超参数C(可能以预测准确性为代价)。

【讨论】:

    【解决方案3】:

    正如 Fred Foo 已经提到的,您必须减少支持向量的数量。根据我的经验,5-10% 的训练基数就足以具有良好的预测水平。

    另一种让它工作得更快的方法:

    1. 减小特征的大小。 3780太贵了。我不确定在您的情况下这种特征大小可以描述什么,但根据我的经验,例如,对汽车标志等图像的描述可以有效地打包成 150-200 大小:
      • PCA 可用于减小特征的大小并降低其“噪音”。有一些示例说明如何将其与 SVM 一起使用;
      • 如果没有帮助,请尝试其他图像描述原则,例如 LBP 和/或 LBP 直方图
    2. 也可以使用 LDA(单独或与 SVM 一起使用)。
    3. 首先尝试线性 SVM。如果您的集合原则上是线性可分的,那么它的速度要快得多,并且您的特征大小 3780(3780 维)足以在更高维度上具有良好的分离“空间”。如果不够好 - 尝试使用一些非常标准的设置(如 C = 1 和 gamma = 0.1)的 RBF 内核。只有在那之后——POLY——最慢的一个。

    【讨论】:

      猜你喜欢
      • 2015-06-05
      • 2011-06-22
      • 2013-01-04
      • 2015-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-03
      • 2010-10-31
      相关资源
      最近更新 更多