LihO / SVMLightClassifier

Simple static library based on SVMLight and SVMLightLib meant for classification using HOG features.
Other
22 stars 11 forks source link

Index of resulting single detector vector probably being incorrect #3

Open jpjodoin opened 10 years ago

jpjodoin commented 10 years ago

As found here: https://github.com/DaHoC/trainHOG/issues/2

"The first value (Index 0) of the vector being generated in function getSingleDetectingVector() being always 0 due to the way SVMlight handles indices, as well as the last value (Index 3780) being overwritten by -b. An indexshift does not fix this issue because the positions/indices of the detecting vector components do matter for HOG."

I think I've found the solution to solve this issue if you want to try. You have to shift the indice by -1, remove the last line with the -model->b, and rescale the output to 3780.

We then use -model->b as the detection threshold.

Example: void getSingleDetectingVector(std::vector& singleDetectorVector, std::vector& singleDetectorVectorIndices) { // Now we use the trained svm to retrieve the single detector vector DOC* supveclist = model->supvec; printf("Calculating single descriptor vector out of support vectors (may take some time)\n"); // Retrieve single detecting vector (v1 | b) from returned ones by calculating vec1 = sum_1_n (alpha_yx_i). (vec1 is a n x1 column vector. n = feature vector length ) singleDetectorVector.clear(); singleDetectorVector.resize(model->totwords, 0.); printf("Resulting vector size %lu\n", singleDetectorVector.size());

        // Walk over every support vector
        for (long ssv = 1; ssv < model->sv_num; ++ssv) { // Don't know what's inside model->supvec[0] ?!
            // Get a single support vector
            DOC* singleSupportVector = supveclist[ssv]; // Get next support vector
            SVECTOR* singleSupportVectorValues = singleSupportVector->fvec;
            WORD singleSupportVectorComponent;
            // Walk through components of the support vector and populate our detector vector
            for (long singleFeature = 0; singleFeature < model->totwords; ++singleFeature) {
                singleSupportVectorComponent = singleSupportVectorValues->words[singleFeature];
                singleDetectorVector.at(singleSupportVectorComponent.wnum-1) += (singleSupportVectorComponent.weight * model->alpha[ssv]);
            }
        }
    }

float getThreshold() const { return model->b; }

And when you want to detect, you can use something like this: hogdetector.detect(im, ptList, svm.getThreshold(), cv::Size(8, 8),cv::Size(0, 0));

tengwang commented 10 years ago

How you test the correctness of the classifier with your specific modification?

jpjodoin commented 10 years ago

To test it, I have used my training data as my test data in order to make sure I was getting the correct result for the known case of the classifier. With the previous implementation, I was getting poor results even when using my training data as test data.