2014-10-22 1 views
0

Это в основном дубликат this question, но я все равно его спрашиваю, потому что исходный плакат либо решил проблему, либо потерял интерес.OpenCV: SVM train_auto assertion sv_count! = 0 не удалось

Я хочу авто поезда регрессии SVM с OpenCV, используя следующий код:

CvSVMParams params; 
params.svm_type = CvSVM::EPS_SVR; 
params.kernel_type = CvSVM::RBF; 
params.term_crit = TermCriteria(CV_TERMCRIT_ITER, (int)1e7, 1e-6); 

CvSVM svm; 
svm.train_auto(_data, _resp, _var_idx, _train_idx, params); 

Здесь _data и _resp являются Маты держащих векторов функций и ответы, _var_idx содержащих активные функции и _train_idx активных образцов. Для параметрических сеток используются значения по умолчанию. К сожалению, код выдает следующее сообщение об ошибке:

OpenCV Error: Assertion failed (sv_count != 0) in do_train, file /home/.../opencv-2.4.9/modules/ml/src/svm.cpp, line 1346

Когда я бегу один регрессии с параметрами, заданными вручную он работает отлично. И когда я переключаюсь на проблему классификации (и меняю соответствующие параметры и тип SVM), он также работает. В этом случае для одиночного обучения, а также для авто-обучения.

Может ли кто-нибудь указать, в чем проблема?

EDIT:

код, как это выше, также приводит к другой ошибке:

OpenCV Error: One of arguments' values is out of range (The parameter p must be positive) in CvSVM::set_params

И для CvSVM :: NU_SVR это было бы то же самое с параметром ню. Проблема исчезает, когда я устанавливаю эти параметры, но я не понимаю, почему эта ошибка возникает в первую очередь. Когда я смотрю на документацию train_auto, он говорит, что p (и nu) оцениваются с использованием соответствующих сеток по умолчанию. Так почему я должен их устанавливать?

Заранее спасибо.

EDIT 2:

Я сделал небольшой пример, который страдает от этой проблемы. Только в случае, если кто-то хочет попробовать и воспроизвести проблему:

#include <iostream> 
#include <opencv2/core/core.hpp> 
#include <opencv2/ml/ml.hpp> 

using namespace cv; 
using namespace std; 

int main() { 

    Mat X(1000, 2, CV_32FC1); 
    Mat Y(1000, 1, CV_32FC1); 

    randu(X, -2, 2); 

    for(int i = 0; i < 1000; i++){ 
     Y.at<float>(i,0) = pow(X.at<float>(i,0),2) + pow(X.at<float>(i,1),2) - 1; 
    } 

    CvSVMParams params; 
    params.svm_type = CvSVM::EPS_SVR; 
    params.kernel_type = CvSVM::RBF; 
    params.term_crit = TermCriteria(CV_TERMCRIT_ITER, (int)1e7, 1e-6); 
    params.p = 0.1; 

    CvSVM svm; 
    svm.train_auto(X, Y, Mat::ones(1,2, CV_8U), Mat::ones(1,1000, CV_8U), params); 

    return 0; 
} 
+0

Выполняется ли svm_type = CvSVM :: NU_SVR? Для одиночной регрессии, вы имеете в виду одноклассный SVM? – greeness

+0

@greeness Да, NU_SVR работает. Нет, с «единственной регрессией» я имею в виду одну регрессию по тем же данным с фиксированным набором параметров. – thomas

+0

Вы пробовали 'train_auto (X, Y, Mat(), Mat(), params);'? –

ответ

-1

Может быть, вы должны присвоить начальные значения этих параметров.

param.C = 1; //initialize parameter 
param.p = 5e-3; //initialize parameter 
param.gamma = 0.01; //initialize parameter