如何从 scikits.learn 分类器中提取信息然后在 C 代码中使用

Posted

技术标签:

【中文标题】如何从 scikits.learn 分类器中提取信息然后在 C 代码中使用【英文标题】:How to extract info from scikits.learn classifier to then use in C code 【发布时间】:2012-01-11 17:08:18 【问题描述】:

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

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

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

补充:首次尝试解决方案。

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

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

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

【问题讨论】:

文档链接已损坏 【参考方案1】:

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

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

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

对于第一种方法,您可以在 deep learning tutorial 上找到很好的文档

第二次阅读 Adam Coates 最近的论文,并在 kmeans feature extraction 上查看此页面

最后,您还可以尝试使用 NuSVC 模型,其正则化参数nu 对拟合模型中支持向量的数量有直接影响:支持向量越少意味着预测时间越快(不过请检查准确性,这将是最终在预测速度和准确性之间进行权衡)。

【讨论】:

感谢周到的回复。这个建议在以后会非常有用,但是对于当前的项目,由于其他限制,我很遗憾地无法使用 SVM。 那你应该看看sklearn.svm.NuSVC,先试着权衡一下SV的数量。 据我所见,sklearn 0.9 NuSVC() 中的 nu 参数仅给出了支持向量数量的下限。当我训练时,我不断地为我的数据获得同样多的支持向量,除非我将 nu 做得很大以至于我实际上得到了更多。我不知道如何使它提供更少的支持向量。 好的。我自己没有试过。我刚刚阅读了 libsvm 文档,并认为它可能会有所帮助。

以上是关于如何从 scikits.learn 分类器中提取信息然后在 C 代码中使用的主要内容,如果未能解决你的问题,请参考以下文章

scikits.learn 曲线拟合参数的聚类方法

Scikits Learn:线性核 SVM 中的特征权重

将 scikits.learn.hmm.GaussianHMM 拟合到可变长度的训练序列

机器学习包Scikit-learn

在 CNN 提取特征之上使用 SVM - 如何进行多类分类?

在 MATLAB 分类学习器中,导出模型后是不是可以提取该模型的参数?