我的目标是使用多类线性SVM(无核函数)对图像进行分类。我希望编写自己的SVM分类器
我使用MATLAB,并使用提供的图像集训练了线性SVM。
我有大约20个类,每个类有5张图像(总共100张图像),我使用的是一对多策略。
每张图像是一个(112,92)的矩阵。这意味着112*92=10304个值。
我使用quadprog(H,f,A,C)
来求解SVM中的二次方程(y=w’x+b)。一次quadprog
调用会返回一个大小为10304的w
向量,用于一张图像。这意味着我需要调用quadprog
100次。
问题是每次quadprog
调用需要35秒才能执行完毕。这意味着对于100张图像将需要3500秒。这可能是由于所涉及的向量和矩阵尺寸过大所致。
我想减少quadprog
的执行时间。有没有办法做到这一点?
回答:
首先,当你使用SVM进行分类时,通常会提取图像的特征(如HOG),这样SVM需要操作的空间维度就会减少。你使用的是原始像素值,这会生成一个10304维的向量。这不好。使用一些标准特征吧。
其次,你不需要调用quadprog
100次。你只需调用一次。优化背后的概念是,你希望找到一个权重向量w
和偏置b
,使得它满足w'x_i+b=y_i
,适用于所有图像(即所有x_i)。请注意,i
将从1遍历到训练集中例子的数量,但w
和b
保持不变。如果你只想找到一个(w,b)
来满足一个x
,你不需要任何复杂的优化。因此,将你的x
堆叠在一个维度为NxD
的大矩阵中,y
将是一个Nx1
的向量,然后调用quadprog
。这将比35秒花费更长时间,但你只需做一次。这被称为训练SVM
。在测试一个新图像时,你只需提取其特征,然后执行w*x+b
来获取其类别。
第三,除非你作为练习来理解SVM,否则quadprog
并不是解决这个问题的理想方法。你需要使用一些其他技术,这些技术在大数据上表现良好,例如,顺序最小优化。
一个线性超平面如何分类超过2个类别:对于多类分类,SVM通常使用两种流行方法:
- 一对一 SVM:对于一个
C
类问题,你训练C(C-1)/2
个分类器,在测试时,你测试那么多的分类器,并选择获得最多投票的类别。 - 一对多 SVM:顾名思义,你为每个类训练一个分类器,正样本来自该类,负样本来自所有其他类。
来自LIBSVM常见问题解答:
它是一对一。我们在进行以下比较后选择了它:C.-W. Hsu和C.-J. Lin。一对多支持向量机方法的比较,IEEE神经网络交易,13(2002),415-425。
“一对其余”是一种表现与“一对一”相当的好方法。我们选择后者仅仅因为它的训练时间更短。
然而,也请注意,一对一的 naive 实现可能不适合大规模问题。LIBSVM网站也列出了这一缺点,并提供了一个扩展。
LIBLINEAR不支持一对一多类分类,因此我们在这里提供了一个扩展。如果k是类别的数量,我们生成k(k-1)/2个模型,每个模型只涉及两个类别的训练数据。根据Yuan等人(2012)的说法,一对一对于大规模线性分类不实用,因为需要存储k(k-1)/2个模型所需的巨大空间。然而,如果模型向量(即权重向量)非常稀疏,这种方法可能仍然可行。我们的实现以稀疏形式存储模型,并且可以有效处理一些大规模数据。