如何让 Opencv SVM 更快?

Posted

技术标签:

【中文标题】如何让 Opencv SVM 更快?【英文标题】:How to make Opencv SVM faster? 【发布时间】:2015-04-09 23:39:49 【问题描述】:

我正在使用 Opencv 2.4.8 来实现图像分类解决方案。

没有。类数 = 29

没有。测试图像 = 大约 4000

特点:SURF 描述符,在将每张图像放入 3x6 网格之后。这给出了 18 个不同的 SURF 描述符列表。

分类器:CvSVM (NU_SVC/C_SVC) C=32, gamma=8

有 18 个分类器,每个网格块 1 个。

最终输出基于对所有 SURF 描述符的所有 18 个分类器的输出的重要性投票。

问题在于 SVM 分类需要大量时间(每张图像大约需要 600 毫秒)。提出这种技术的 IEEE 论文报告了 21fps 的速度。我实现的程序的速度慢了 8-10 倍。

我会在哪里犯错?

有什么建议可以加快我的测试/分类速度吗?

【问题讨论】:

你能在并行线程中运行每个分类器吗? 是的,这是可能的。但是我有 Core i5(4 核),最大预期加速是多少? 很抱歉我不能给你一个确切的统计数据,但是如果你写得足够好,3-4x 是可以预期的。 【参考方案1】:

您的实现和作者实现之间可能有很多不同之处,但我会将它们分为三个主要类别:

-数据: 您使用与论文作者相同的数据吗? 你们的功能完全一样吗? 也许您的数据包含更多类,或者更难分类,从而导致更多支持向量? 如果您不使用相同的数据并且他们使用的数据是公开可用的,那么您可能需要在这些数据上测试您的实施。 如果他们在论文中指定了 SV 的数量,请检查您得到的数字是否大致相同。

-算法: 您是否使用相同的内核和训练参数? OpenCV 实现使用 1-vs-1 算法进行多类分类,您的论文中是否相同? 请注意,对于 29 个类,这将导致对 18 个分类器中的每一个评估 406 个二元分类器,这可能是您的问题的一个原因。

编辑:快速浏览一下 opencv 代码后,它肯定使用 1vs1。 这可能是(其中一个)问题,即使在我看到的关于该主题的几篇论文中通常报告 1-vs-1 比 1-vs-all 快(更多的分类器,但总体上更少的 SV)。 考虑到您的 cmets,这些特征可能是更可能的原因,但没有更多细节或参考论文,很难说更多。

-实现: 也许他们的实现只是更好地优化/多线程。我不确定 OpenCV 实现的优化程度。它基于一个相当旧的 libSVM 版本,但此后可能已被修改/优化。如果确实是问题,您可能还需要考虑 GPGPU:http://mklab.iti.gr/project/GPU-LIBSVM

【讨论】:

感谢阿德里安的详细回复! - 数据:我使用与论文发表的数据集相同的数据集他们没有报告 SV 的数量。另一件事是,特征向量 r 基本上是 SURF 描述符。他们不报告 SURF 参数 --> 影响产生的特征数量。 -算法:本文使用RBF内核,Gamma=0.0825,svm_type为NU_SVC。他们不报告“nu”值。您确定 OpenCV 使用 1-vs-1 进行多类吗?我以为我在 opencv 文档上读到它使用 1-vs-all? 关于实现:他们没有报告使用多线程。但我非常怀疑他们可能使用了多线程。他们也没有提到任何关于 GPU 的内容。 从您的评论来看,SURF 可能是其中的区别之一。 nu 值也是如此。 我不确定您是如何使用 SURF 功能的。您是否使用 SURF 描述符向量作为 SVM 的输入特征。如果是,你如何选择向量的长度?也许参考这篇论文会有所帮助。

以上是关于如何让 Opencv SVM 更快?的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV:如何将 HOGDescriptor::detectMultiScale() 与自定义 SVM 一起使用?

如何使用具有面部特征的 openCV 训练支持向量机(svm)分类器?

如何使用基于一组图像的 opencv 训练 SVM?

OpenCV支持向量机(SVM)介绍

如何用opencv在一周内实现人物行为语义识别

如何在 Python 中使用 OpenCV 3.0 中的 HOG 功能训练 SVM 分类器?