2014-10-20 114 views
3

我一直在這一段時間卡住了。 OpenCV的SVM實現似乎不適用於線性內核。我相當肯定代碼中沒有錯誤:當我將kernel_type更改爲RBF或POLY時,保持其他所有內容都是正常的,它可以工作。OpenCV線性SVM不訓練

我說它不起作用的原因是,我保存生成的模型並檢查出來。它顯示支持向量計數爲1.在RBF或多項式內核中不是這種情況。

代碼本身沒有什麼特別之處,我之前使用過OpenCV的SVM實現,但從來沒有線性內核。我嘗試在POLY內核中將degree設置爲1,並且它導致相同的模型。這讓我相信這裏有些東西是錯誤的。

的代碼結構,如果需要的話:

Mat trainingdata; //acquire from files. done and correct. 
Mat testingdata;  //acquire from files. done and correct again. 
Mat labels;   //corresponding labels. checked and correct. 

SVM my_svm; 
SVMParams my_params; 
my_params.svm_type = SVM::C_SVC; 
my_params.kernel_type = SVM::LINEAR; //or poly, with my_params.degree = 1. 
my_param.C = 0.02; //doesn't matter if I set it to 20000, makes no difference. 

my_svm.train(trainingdata, labels, Mat(), Mat(), my_params); 
//train_auto(..) function with 10-fold cross-validation takes the same time as above (~2sec)! 
Mat responses; 
my_svm.predict(testingdata, responses); 
//responses matrix is all wrong. 

我有從其它類中的一個類和600 500個樣本進行測試,和正確的分類我得到有:1/500和600分之597。

最瘋狂的部分: 我已經做了相同的實驗與libSVM的MATLAB包裝相同的數據,它的工作原理。只是試圖做一個OpenCV版本。

+0

你確定數據是線性可分的嗎?它與更好的內核一起工作的事實強烈地暗示了非線性可分的數據......您是否正在使用線性內核來訓練libSVM? – 2014-10-20 06:16:25

+0

你知道SVM的公式嗎?將C設置爲0.02或20000時應該有所不同。請確保正確設置。所有參數不能相同。你也應該設置epsilon參數爲0.001,默認值是別的AFAIK。最後一件事,當你運行'train_auto()'而不是'train()'時會發生什麼? – guneykayim 2014-10-20 06:51:08

+1

嘗試適應標準示例示例/ cpp/points_classifier.cpp還有svm分類器。我檢查過它,它工作。 – 2014-10-20 12:49:55

回答

2

這不是一個錯誤,你總是隻能得到一個支持向量與線性CvSVM

OpenCV將線性SVM優化到一個支持向量。
這裏的想法是支持向量定義了分類邊界,並且做實際的分類只需要分離超平面並且它可以僅由一個向量定義。

參數C並不重要,如果您的訓練數據是線性可分的。也許這是你的情況。

+0

我不明白如何分離超平面_needs_只有一個支持向量。此外,我之前使用過線性支持向量機,並且獲得了許多支持向量(這與支配和泛化的思想很相符)。 – 2015-04-28 14:27:14

+0

而'C'則適用於噪音會影響分類的情況;噪音的存在並不是一個巨大的假設(至少在這種情況下)。 – 2015-04-28 14:29:35

+0

當svm正在訓練時,它會使用一定數量的支持向量,位於邊緣或內部(如果我們使用「軟」邊距)。但是當opencv存儲訓練好的分類器時 - 它所需要的唯一信息只有一個向量(垂直於超平面),它定義了分辨超平面。 http://www.songho.ca/math/plane/plane。html – Temak 2015-04-28 14:37:36