为啥使用 SVM 线性内核的代码不能使用 RBF
Posted
技术标签:
【中文标题】为啥使用 SVM 线性内核的代码不能使用 RBF【英文标题】:Why working code with SVM Linear Kernel not working with RBF为什么使用 SVM 线性内核的代码不能使用 RBF 【发布时间】:2019-12-19 10:05:18 【问题描述】:当我使用 SVM 的 trainAuto 方法时,我得到 getKernelType()
的值 2,但是当我在代码中使用 RBF
时,它会训练我的文件并输出 XML 文件。
svm = cv2.ml.SVM_create()
svm.setType(cv2.ml.SVM_C_SVC)
svm.setKernel(cv2.ml.SVM_RBF)
svm.setGamma(0.0025)
svm.setC(0.5)
svm.train(samples, cv2.ml.ROW_SAMPLE, labels)
svm.save('svm_data.xml')
以上代码对我有用。但是当我用下面的代码移动到预测部分时
hog = cv2.HOGDescriptor((100,200), (16,16), (8,8), (8,8), 9)
svm = cv2.ml.SVM_load('svm_data.xml')
sv = svm.getSupportVectors()
rho, alpha, svidx = svm.getDecisionFunction(0)
svm_new = np.append(sv, -rho)
hog.setSVMDetector(svm_new)
显示低于错误
error: (-215:Assertion failed) checkDetectorSize() in function 'cv::HOGDescriptor::setSVMDetector'
但是当我用 LINEAR 更改 RBF 时它在预测部分对我有用。
当我检查时
print (hog.checkDetectorSize())
print (hog.getDescriptorSize())
它返回 True
用于 DetectorSize 和 26676
用于 DescriptorSize
【问题讨论】:
【参考方案1】:OpenCV 无法接受线性内核以外的 SVM。
首先,official documentation 说:
setSVMDetector()
virtual void cv::HOGDescriptor::setSVMDetector (InputArray _svmdetector)
参数
线性 SVM 分类器的_svmdetector 系数。
很明显,您只将 SVM 的系数(作为单个数组)传递给 HOGDescriptor
,而不是 种类(最常见的是线性、RBF 和多项式)和/或特定于它的参数(多项式的次数或 RBF 的伽马)。所以底层的 OpenCV 检测器无法确定内核的种类。而且它不必这样做,因为唯一实现的就是线性的。
此外,请阅读this 和this 问题。
【讨论】:
但是线性给出的结果并不好用 HOG 虽然它应该是 这意味着我必须将svm.setType(cv2.ml.SVM_C_SVC)
更改为Regression with Linear SVM? SVM.C_SVR_EPS
?
我不认为回归/分类模式对这里的结果有一些影响。这是结果解释的问题:在一种情况下,您与决策线保持距离,在另一种情况下,您只对它的符号感兴趣。在这两种情况下,阿尔法都是相同的。你可以尝试改变它,但我怀疑它会改变什么。至于性能低下,请确保您在 HOG 描述符上进行训练,而不是在原始图像上进行训练 see example
This 是我使用 HOG 进行训练的方式,这是最***的代码以上是关于为啥使用 SVM 线性内核的代码不能使用 RBF的主要内容,如果未能解决你的问题,请参考以下文章