8

我已经在 Python 中使用 scikits.learn 训练了一堆 RBF SVM,然后对结果进行了腌制。这些是用于图像处理任务的,我想做的一件事是在一些测试图像的每个像素上运行每个分类器。也就是说,从以像素 (i,j) 为中心的窗口中提取特征向量,在该特征向量上运行每个分类器,然后移动到下一个像素并重复。这对于 Python 来说太慢了。

澄清:当我说“这太慢了......”时,我的意思是即使 scikits.learn 使用的 Libsvm 底层代码也太慢了。我实际上正在为 GPU 编写一个手动决策函数,因此每个像素的分类是并行发生的。

我是否可以使用 Pickle 加载分类器,然后获取某种描述如何从特征向量计算决策的属性,然后将该信息传递给我自己的 C 代码?在线性 SVM 的情况下,我可以只提取权重向量和偏置向量,并将它们作为输入添加到 C 函数中。但是对于 RBF 分类器来说,等效的事情是什么,我如何从 scikits.learn 对象中获取这些信息?

补充:第一次尝试解决方案。

看起来分类器对象具有support_vectors_包含支持向量作为数组的每一行的属性。还有一个属性dual_coef_是 1 bylen(support_vectors_)系数数组。从关于非线性 SVM 的标准教程中,看来应该执行以下操作:

  • v从被测数据点计算特征向量。这将是一个与 的行长度相同的向量support_vectors_
  • 对于 中的每一行isupport_vectors_计算该d[i]支持向量与 之间的平方欧几里得距离v
  • 计算哪里t[i]是RBF 参数。gamma * exp{-d[i]}gamma
  • 总结dual_coef_[i] * t[i]一下iintercept_将 scikits.learn 分类器的属性值添加到该总和中。
  • 如果总和为正,则归为 1。否则,归为 0。

补充:在此文档链接的第 9 页上,它提到intercept_分类器的属性确实包含偏差项。我已更新上述步骤以反映这一点。

4

1 回答 1

9

是的,您的解决方案看起来不错。要将 numpy 数组的原始内存直接传递给 C 程序,您可以使用numpy 中的 ctypes 助手或使用 cython 包装 C 程序并通过传递 numpy 数组直接调用它(请参阅http://cython.org上的文档更多细节)。

但是,我不确定尝试加速 GPU 上的预测是最简单的方法:众所周知,内核支持向量机在预测时间很慢,因为它们的复杂性直接取决于支持向量的数量,对于高度非-线性(多模式)问题。

在预测时间更快的替代方法包括神经网络(可能比只有 2 个超参数 C 和 gamma 的 SVM 更复杂或更慢地正确训练)或基于到原型的距离 + 阈值处理 + 使用非线性变换来变换数据图像区域的最大池化(仅用于图像分类)。

Finally you can also try to use NuSVC models whose regularization parameter nu has a direct impact on the number of support vectors in the fitted model: less support vectors mean faster prediction times (check the accuracy though, it will be a trade-off between prediction speed and accuracy in the end).

于 2011-12-03T10:53:10.117 回答