Я уже давно застрял в этом. Реализация SVM OpenCV, похоже, не работает для линейного ядра. Я уверен, что в коде нет ошибки: когда я изменяю kernel_type
на RBF или POLY, сохраняя все остальное как есть, он работает.OpenCV Linear SVM не тренируется
Причина, по которой я говорю, что она не работает, я сохраняю сгенерированную модель и проверяю ее. Он показывает количество векторов поддержки как 1. Что не имеет места в RBF или полиномиальных ядрах.
В коде нет ничего особенного, я использовал ранее реализацию SVM OpenCV, но никогда не линейное ядро. Я попытался установить degree
на 1 в ядре POLY, и это приводит к той же модели. Это заставляет меня думать, что здесь что-то не так.
Код структуры, если это необходимо:
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.
У меня есть 500 образцов из одного класса и 600 из другого класса, чтобы проверить, и правильные классификации я получаю: 1/500 и 597/600.
Самая сухая часть: Я сделал тот же эксперимент с теми же данными об обертке libSVM MATLAB, и он работает. Просто пытался сделать версию OpenCV.
Вы уверены, что данные линейно разделены? Тот факт, что он работает с ядрами fancier, настоятельно предлагает нелинейно разделяемые данные ... Вы тренируете libSVM с использованием линейных ядер? –
Вы знаете формулировку SVM? При установке C на 0,02 или 20000 должна быть разница. Убедитесь, что вы правильно установили его. Он не может быть одинаковым для всех параметров. Также вы должны установить параметр epsilon равным 0,001, по умолчанию это еще что-то AFAIK. Последнее, что происходит, когда вы запускаете 'train_auto()' вместо 'train()'? – guneykayim
Попробуйте адаптировать примеры стандартных примеров/cpp/points_classifier.cpp, также существует svm-классификатор. Я проверил его, и это сработало. –