我正在尝试针对大量项目和类训练SVM分类器,这变得非常非常慢。
首先,我从数据中提取了一个功能集,以整体上确定为512个特定功能并将其放入numpy数组中。此数组中有13k项。看起来像这样:
>>print(type(X_train))
<class 'numpy.ndarray'>
>>print(X_train)
[[ 0.01988654 -0.02607637 0.04691431 ... 0.11521499 0.03433102
0.01791015]
[-0.00058317 0.05720023 0.03854145 ... 0.07057668 0.09192026
0.01479562]
[ 0.01506544 0.05616265 0.01514515 ... 0.04981219 0.05810429
0.00232013]
...
另外,大约有4000种不同的类别:
>> print(type(labels))
<class 'list'>
>> print(labels)
[0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, ... ]
这是分类器:
import pickle
from thundersvmScikit import SVC
FILENAME = 'dataset.pickle'
with open(FILENAME, 'rb') as infile:
(X_train, labels) = pickle.load(infile)
clf = SVC(kernel='linear', probability=True)
clf.fit(X_train, labels)
经过约90个小时后(并且我正在以thundersvm的形式使用sci-learn工具包的GPU实现)拟合操作仍在运行。考虑到在我的情况下这是一个很小的数据集,我当然需要更高效的东西,但是我似乎并没有取得任何成功。例如,我尝试过这种Keras模型:
model = Sequential()
model.add(Dense(input_dim=512, units=100, activation='tanh'))
model.add(Dropout(0.2))
model.add(Dense(units=n_classes, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adadelta', metrics=['accuracy'])
model.fit(X_train, labels, epochs=500, batch_size=64, validation_split=0.1, shuffle=True)
在训练阶段,我最终获得了很好的准确性:
Epoch 500/500
11988/11988 [==============================] - 1s 111us/step - loss: 2.1398 - acc: 0.8972 - val_loss: 9.5077 - val_acc: 0.0000e+00
但是,在实际测试中,即使对训练数据集中存在的数据,我的准确性也非常低,基本上可以预测随机类别:
Predictions (best probabilities):
0 class710015: 0.008
1 class715573: 0.007
2 class726619: 0.006
3 class726619: 0.010
4 class720439: 0.007
Accuracy: 0.000
能否请您为此指出正确的方向?我应该以某种方式调整SVM方法还是应该针对此类问题切换到自定义Keras模型?如果是,我的模型可能有什么问题?
非常感谢。
答案 0 :(得分:2)
如果该SVC实现依赖于多类SVC的scikit-learn实现,则不应使用该SVC实现。在documentation中,其声明“多类支持是根据一对一方案处理的。”这意味着您需要为每对类别训练一个分类器,即正在训练约2 ^ 4k个分类器。您可以使用“固有多重类”下的here中列出的任何内容
此外,您的Keras实现可能还需要另一层。我假设输出层的每个类都有1个神经元,在这种情况下,您将要使用分类交叉熵和softmax激活,以及一种热编码。
我现在假设您的所有示例都只有一个类标签。
答案 1 :(得分:2)
SVM对于二进制分类是最自然的。对于多类,scikit-learn使用一对多来组合O(K ^ 2)个二进制分类器(https://scikit-learn.org/stable/modules/svm.html),其中K个是分类数。因此,运行时间与K ^ 2成正比,在您的情况下为1600万。这就是为什么它这么慢的原因。
您应该减少类的数量,或者切换到其他模型,例如神经网络或决策树。
P.S:scikit-learn对于SVM(https://scikit-learn.org/stable/modules/multiclass.html)也有一种“一对多”的方法,即O(K)。您也可以尝试这个。