将sklearn.svm的SVC分类器转换为Keras实现

19

我正在尝试将一些旧代码从使用sklearn转换为Keras实现。由于保持相同的操作方式至关重要,我想知道我是否做得正确。

我已经转换了大部分代码,但是我在将sklearn.svm SVC分类器转换时遇到了问题。以下是当前的代码:

from sklearn.svm import SVC
model = SVC(kernel='linear', probability=True)
model.fit(X, Y_labels)

非常简单,对吧。但是,我在Keras中找不到SVC分类器的类比。因此,我尝试了这个:

from keras.models import Sequential
from keras.layers import Dense

model = Sequential()
model.add(Dense(64, activation='relu'))
model.add(Dense(1, activation='softmax'))
model.compile(loss='squared_hinge',
              optimizer='adadelta',
              metrics=['accuracy'])
model.fit(X, Y_labels)

但是,我认为这绝不是正确的。你能帮我在Keras中找到一个替代sklearn中的SVC分类器吗?

谢谢。


你所说的“alternative”具体指什么?Keras是一个专门的神经网络框架,它不包括SVM功能... - desertnaut
1
是的,它不是开箱即用的,但是您可以组合一个模型,该模型将成为sklearn-kit中找到的SVM损失函数的替代品。这种模型在答案中提出。 - none32
好的,对于“替代”意义我不是很清楚,但既然你得到了有意义的答案就好了(当你看到每月大约有2个问题抱怨,在回归设置中低准确性的时候,假设提问者完全理解自己在说什么的假设开始感觉不那么牢固了... :) - desertnaut
3个回答

19
如果你正在制作分类器,你需要squared_hingeregularizer,才能获得完整的SVM损失函数,可以在这里看到: here. 因此,在执行激活之前,您还需要将最后一层分解以添加正则化参数。我已经在这里添加了代码。

这些更改应该会给你输出结果。

from keras.regularizers import l2
from keras.models import Sequential
from keras.layers import Dense

model = Sequential()
model.add(Dense(64, activation='relu'))
model.add(Dense(1), kernel_regularizer=l2(0.01))
model.add(activation('softmax'))
model.compile(loss='squared_hinge',
              optimizer='adadelta',
              metrics=['accuracy'])
model.fit(X, Y_labels)

另外,keras中实现了hinge用于二分类,因此如果您正在开发二分类模型,请使用以下代码。

from keras.regularizers import l2
from keras.models import Sequential
from keras.layers import Dense

model = Sequential()
model.add(Dense(64, activation='relu'))
model.add(Dense(1), kernel_regularizer=l2(0.01))
model.add(activation('linear'))
model.compile(loss='hinge',
              optimizer='adadelta',
              metrics=['accuracy'])
model.fit(X, Y_labels)

如果您无法理解文章或对代码有疑问,请随意评论。 我之前也遇到了同样的问题,而这个 GitHub 线程帮助了我理解。也许您可以浏览一下,这里的一些想法直接来自于这里:https://github.com/keras-team/keras/issues/2588

非常感谢,特别是参考资料,它们不仅帮助我获得了现成的解决方案,还帮助我理解了底层发生了什么。在我的情况下,这是一个多类分类器,所以我正在使用平方hinge损失函数。据我所知,我代码和你提供的代码之间唯一的区别是正则化器的使用,顺便说一句,这是我现在无法理解的唯一部分。我会自己更深入地挖掘,因为我完全不熟悉L2正则化器。 - none32
你能解释一下为什么最后一个密集层只有一个节点吗? - Chhaganlaal
1
同时,请解释一下W_regularizer,因为我在使用它时出现了错误。 - Chhaganlaal
当我在mnist数据集上尝试类似的代码时,结果非常糟糕,如10-11%的准确率。 - Nitin1901
@Chhaganlaal 没有这样的参数。您可以使用kernel_regularizer或bias_。 - Nitin1901
@NitinSai 我大约1.5年前写了这个答案,现在已经有一年多没有做机器学习了,从评论中看来,这个答案已经过时了。如果我要重新学习ML并修复它,需要花费相当长的时间。如果你能建议一个编辑来更新答案,请这样做,我会在验证后更新答案。 - anand_v.singh

2
如果您正在使用Keras 2.0,则需要更改anand v sing的答案中以下行:

W_regularizer -> kernel_regularizer

Github链接

model.add(Dense(nb_classes, kernel_regularizer=regularizers.l2(0.0001)))
model.add(Activation('linear'))
model.compile(loss='squared_hinge',
                      optimizer='adadelta', metrics=['accuracy'])

或者您可以使用以下方法。
top_model = bottom_model.output
  top_model = Flatten()(top_model)
  top_model = Dropout(0.5)(top_model)
  top_model = Dense(64, activation='relu')(top_model)
  top_model = Dense(2, kernel_regularizer=l2(0.0001))(top_model)
  top_model = Activation('linear')(top_model)
  
  model = Model(bottom_model.input, top_model)
  model.compile(loss='squared_hinge',
                      optimizer='adadelta', metrics=['accuracy'])
  


你知道获取置信度值或输出概率的方法吗?我在这里详细描述了这个问题:https://stackoverflow.com/questions/67559912/svc-classifier-to-keras-cnn-with-probabilities-or-confidence-to-distinguish-untr - Apidcloud

0

您可以使用scikeras实现的Keras SVM。它是Keras的Scikit-Learn API包装器。它于2020年5月首次发布。以下是官方文档链接。希望您能在那里找到答案。

https://pypi.org/project/scikeras/#description


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接