Это в основном дубликат этого вопроса, но я все равно его спрашиваю, потому что оригинальный плакат либо решил проблему, либо потерял интерес.
Я хочу автоподготовку регрессии 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: утверждение не выполнено (sv_count! = 0) в do_train, файл /home/.../opencv-2.4.9/modules/ml/src/svm.cpp, строка 1346
Когда я запускаю одиночную регрессию с параметрами, выбранными вручную, она отлично работает. И когда я переключаюсь на проблему классификации (и меняю соответствующие параметры и тип SVM), он также работает. В этом случае для одиночного обучения, а также для авто-обучения.
Может кто-нибудь указать, в чем проблема?
РЕДАКТИРОВАТЬ:
Код, как он выше, также приводит к другой ошибке:
Ошибка OpenCV: одно из значений аргументов вне диапазона (параметр p должен быть положительным) в CvSVM :: set_params
А для CvSVM :: NU_SVR это будет то же самое с параметром nu. Проблема исчезает, когда я устанавливаю эти параметры, но я не понимаю, почему эта ошибка возникает в первую очередь. Когда я смотрю на документацию 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;
}
Возможно, вам следует назначить начальные значения этим параметрам.
param.C = 1; //initialize parameter
param.p = 5e-3; //initialize parameter
param.gamma = 0.01; //initialize parameter