将LibSVM输出转换为浮点数向量

时间:2013-09-30 08:05:00

标签: c++ opencv machine-learning computer-vision libsvm

我需要输入HOGDescriptor::setSVMDetector()输入。

我使用openCV计算描述符,然后使用libSVM获取模型文件。 为了形成输入,我知道我需要获得支持向量的值,并使用alphas元素化它们(然后在末尾添加-rho),但是我无法获得这些alphas 。< / p>

我有一个SV列表,如:

1 1:-0.0434783 2:0.153846 3:0.194444 4:-0.353712 5:-0.45054
1 1:-0.2173916 2:-0.38461 3:0.222262 4:-0.676686 5:-0.78062

但在哪里获得alphas?

2 个答案:

答案 0 :(得分:0)

但你为什么要“手工”分类呢? OpenCv has a classification routine名为predict,使用找到的SV和'alphas'

float response = SVM.predict(sampleMat);

如果你真的想自己做,你不仅需要SV和alphas,还需要用于训练和计算机的核函数

SUM alpha_i K( support_vector_i , data_point ) - rho

我不确定是否可以在不扩展SVM类的情况下“手动”提取alphas,正如sources中所见 - alphas存储在CvSVMDecisionFunc结构中:

struct CvSVMDecisionFunc
{
    double rho;
    int sv_count;
    double* alpha;
    int* sv_index;
};

虽然对此结构的唯一引用位于protected部分:

protected:

    (...)

    CvSVMDecisionFunc* decision_func;

从我们可以找到的svm.cpp源代码中,它只能通过save例程公开访问。因此,一些“黑客”将是保存模型并从那里提取alphas(它将位于“决策函数”部分,以人类可读的格式编写)。

最简单的提取技术似乎扩展了CvSVM类并包含类似

的方法
public:

    CvSVMDecisionFunc* get_decision_function() { return decision_func; }

更新

澄清之后,OP实际上是尝试在opencv中使用externaly训练模型 - 最简单的方法是将其他方法(libsvm,linearsvm等)创建的libsvm模型转换为opencv兼容格式并使用{{1方法

read

see source for more details

答案 1 :(得分:0)

好吧,现在看来情况很清楚。 在我的案例中, Alphas是第一列。 由于我的测试模型中所有这些都等于-1或1(dunno why),我认为这些是标签。

无论如何,这是我的解析器(但你只需要在文件中保留SV):

std::ifstream ifs("cars_model.model");

    const int nsv = 90;
    const int nfeatures = 144;

    float rho = 12.5459;

    char ts[4000] = ""; // !

    std::vector<float> res(nfeatures,0);

    std::vector<float> alphas;

    Mat_<float> temp(nsv, nfeatures);

    int c = 0;

    std::cout << "Loading model file...\n";

    for (int i=0; i<nsv; i++) {

        float al = 0;
        ifs >> al;
        alphas.push_back(al);

        for (int j=0; j<nfeatures; j++) {

            float ind, s;
            char junk;

            ifs >> ind >> junk >> s;

            temp.at<float>(c, j) = s;

            //std::cout << f << ' ' << s << '\n';

        }

        c++;

    }

    ifs.close();

    std::cout << "Computing primal form...\n";

    for (int i=0; i<nsv; i++) {

        float alpha = alphas[i];

        for (int j=0; j<nfeatures; j++) {
            res[j] += (temp.at<float>(i,j) * alpha);
        }

    }

    //res.push_back(-rho);

    std::ofstream ofs("primal.txt");

    for (int i=0; i<res.size(); i++)
        ofs << res[i] << ' ';

    ofs.close();

你知道,它有效。您可以将rho设置为检测器的阈值。