如何让 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 一起使用?