Attention! This forum will be made read-only by Dec-20. Please migrate to Most of existing active users should've received invitation by e-mail.
Ask Your Question

How can I get weights from the trained SVM (regression)?

asked 2019-01-31 17:30:18 -0500

AlexB gravatar image

How can I get bias and array of weights from the trained SVM::Types::NU_SVR to perform prediction by myself?

For example, I trained SVM for regression with linear kernel function and I want to get the trained weights, to perform this part of code by myself:

I want to get double sv_coef[] and double bias from trained Ptr<SVM> svr:

double train::trainSVR(Mat data, vector<int> labels, Mat unlabled_data)
    Ptr<TrainData> trainData = TrainData::create(data, ml::ROW_SAMPLE, labels);
    Ptr<SVM> svr = SVM::create();
    svr->setType(SVM::Types::NU_SVR);  //For regression, to predict value
    svr->setKernel(SVM::LINEAR);  // linear kernel function
    svr->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));

    cout << "Training Support Vector Regressor..." << endl;
    bool trained = svr->isTrained();
    double sum = 0;
    if (trained)
        //svr->save(".\\Trained Models\\SVR Model.xml");

        // how to get: double sv_coef[] ?
        // how to get: double bias (rho) ?

        // custom prediction
        for(int i=0; i<unlabled_data.cols; i++) {
                sum += sv_coef[i] *<double>(0,i);
        sum -= bias;
    return sum;
edit retag flag offensive close merge delete


imho, your for-loop is wrong. it should iterate over the support vectors, not over the query data

berak gravatar imageberak ( 2019-02-01 02:41:25 -0500 )edit

1 answer

Sort by ยป oldest newest most voted

answered 2019-02-01 02:25:05 -0500

berak gravatar image

updated 2019-02-01 02:51:03 -0500

hmmm, there are differences between libsvm and opencv's SVM.

e.g. coef0 is a single constant, and it's not even used in the case of a linear SVM

while you can get at the data, you would be doing something else in the prediction pass, than in the training pass.

it's probably a better idea, to implement a custom kernel:

struct XKernel : public ml::SVM::Kernel
    virtual ~XKernel() {}

    //! your distance metric between one of the support vecs(sample)
    //   and your query(another) goes here
    float per_elem(int var_count, const float* sample, const float* another) {}

    //! post-process results array (if nessecary, e.g. apply bias)
    virtual void post(int vcount, float* results) {}

    void calc(int vcount, int var_count, const float* vecs, const float* another, float* results)
        for (int j=0; j<vcount; j++)
            const float* sample = &vecs[j*var_count];
            results[j] = per_elem(var_count, sample, another);
        post(vcount, result);

    int getType(void) const
        return -1; // we're special.


Ptr<ml::SVM> svm = ml::SVM::create();
Ptr<XKernel> kern = makePtr<XKernel>();
edit flag offensive delete link more
Login/Signup to Answer

Question Tools

1 follower


Asked: 2019-01-31 17:30:18 -0500

Seen: 191 times

Last updated: Feb 01 '19