1

I extract positive and negative descriptor vectors in the cv::Mat objects posSamples and negSamples of type CV_32FC1. Every row corresponds to a vector.

I construct "samples" and "labels" cv::Mat objects to train an SVM. (2 class classificaiton)

vconcat(posSamples, negSamples, samples);

cv::Mat posLabels = cv::Mat::ones(posSamples.rows, 1, CV_32SC1);
cv::Mat negLabels = cv::Mat::-ones(negSamples.rows, 1, CV_32SC1);
vconcat(posLabels, negLabels, labels);

I construct the data using "samples" and "labels":

auto data = cv::ml::TrainData::create(samples, cv::ml::ROW_SAMPLE, labels, cv::noArray(), cv::noArray(), cv::noArray(), cv::noArray());

Then I create and train an SVM using "data":

auto svm = cv::ml::SVM::create();
svm->train(data);

Then I call the predict function for a query.

auto score = svm->predict(newVector, cv::noArray(), cv::ml::StatModel::RAW_OUTPUT);

Setting the flag as RAW_OUTPUT "makes the method return the raw results (the sum), not the class label". http://docs.opencv.org/3.1.0/dd/ded/group__ml.html#ggaf1ea864e1c19796e6264ebb3950c0b9aa639a8ea2b61c2bf03f87cf4c4a5bd824

I assume this means the return value is the signed distance from the seperating hyperplane.

Here, I expect the score value to be positive for samples from positive class, and negative for samples from negative class. In some runs, this is the case. Positive descriptor vectors yields high score (positive scores) and negative descriptor vectors yield low scores (negative scores). SVM classifies the new data with high performance. However in some runs, the score value signs are inverse. (negative for positive class and positive for negative class).

If it was always inverse, I'd simply handle it by multiplying the score with "-1" (or inverse labeling). However it is not deterministic. Sometimes the score signs are inverse and sometimes not.

I tried to change concatenation order and it did not work.

What do I do wrong?

1 Answers1

0

I fed my training samples back in the svm and looked at the decision values for them. If the average decision value for negative samples is greater than the average decision value for positive samples I inverted the decision values. That solved the problem for now.

The decision values can be obtained like this:

svm->predict(samples, resultsScore, true);