Commit ef7897a4477721b6abba31363c156391be8071d5

Authored by Scott Klum
1 parent e76f4ef8

Initial work with liblinear

openbr/plugins/liblinear.cmake 0 โ†’ 100644
  1 +set(BR_WITH_LIBLINEAR OFF CACHE BOOL "Build with LibLinear")
  2 +
  3 +if(${BR_WITH_LIBLINEAR})
  4 + find_package(LibLinear REQUIRED)
  5 + set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} ${LibLinear_SRC})
  6 + set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/liblinear.cpp)
  7 +endif()
... ...
openbr/plugins/liblinear.cpp 0 โ†’ 100644
  1 +#include <QTemporaryFile>
  2 +#include <opencv2/core/core.hpp>
  3 +#include <opencv2/ml/ml.hpp>
  4 +
  5 +#include "openbr_internal.h"
  6 +#include "openbr/core/opencvutils.h"
  7 +
  8 +#include <linear.h>
  9 +#define Malloc(type,n) (type *)malloc((n)*sizeof(type))
  10 +
  11 +using namespace cv;
  12 +
  13 +namespace br
  14 +{
  15 +
  16 +class LinearSVM : public Transform
  17 +{
  18 + Q_OBJECT
  19 + Q_ENUMS(Kernel)
  20 + Q_ENUMS(Type)
  21 + Q_PROPERTY(Kernel kernel READ get_kernel WRITE set_kernel RESET reset_kernel STORED false)
  22 + Q_PROPERTY(Type type READ get_type WRITE set_type RESET reset_type STORED false)
  23 + Q_PROPERTY(float C READ get_C WRITE set_C RESET reset_C STORED false)
  24 + Q_PROPERTY(float gamma READ get_gamma WRITE set_gamma RESET reset_gamma STORED false)
  25 + Q_PROPERTY(QString inputVariable READ get_inputVariable WRITE set_inputVariable RESET reset_inputVariable STORED false)
  26 + Q_PROPERTY(QString outputVariable READ get_outputVariable WRITE set_outputVariable RESET reset_outputVariable STORED false)
  27 + Q_PROPERTY(bool returnDFVal READ get_returnDFVal WRITE set_returnDFVal RESET reset_returnDFVal STORED false)
  28 + Q_PROPERTY(int termCriteria READ get_termCriteria WRITE set_termCriteria RESET reset_termCriteria STORED false)
  29 + Q_PROPERTY(int folds READ get_folds WRITE set_folds RESET reset_folds STORED false)
  30 + Q_PROPERTY(bool balanceFolds READ get_balanceFolds WRITE set_balanceFolds RESET reset_balanceFolds STORED false)
  31 +
  32 +public:
  33 + enum Kernel { Linear = CvSVM::LINEAR,
  34 + Poly = CvSVM::POLY,
  35 + RBF = CvSVM::RBF,
  36 + Sigmoid = CvSVM::SIGMOID };
  37 +
  38 + enum Type { C_SVC = CvSVM::C_SVC,
  39 + NU_SVC = CvSVM::NU_SVC,
  40 + ONE_CLASS = CvSVM::ONE_CLASS,
  41 + EPS_SVR = CvSVM::EPS_SVR,
  42 + NU_SVR = CvSVM::NU_SVR};
  43 +
  44 +private:
  45 + BR_PROPERTY(Kernel, kernel, Linear)
  46 + BR_PROPERTY(Type, type, C_SVC)
  47 + BR_PROPERTY(float, C, -1)
  48 + BR_PROPERTY(float, gamma, -1)
  49 + BR_PROPERTY(QString, inputVariable, "Label")
  50 + BR_PROPERTY(QString, outputVariable, "")
  51 + BR_PROPERTY(bool, returnDFVal, false)
  52 + BR_PROPERTY(int, termCriteria, 1000)
  53 + BR_PROPERTY(int, folds, 5)
  54 + BR_PROPERTY(bool, balanceFolds, false)
  55 +
  56 + model *m;
  57 +
  58 + void train(const TemplateList &data)
  59 + {
  60 + Mat samples = OpenCVUtils::toMat(data.data());
  61 + Mat labels = OpenCVUtils::toMat(File::get<float>(data, inputVariable));
  62 +
  63 + // Number of features = n
  64 + // Number of instances = l
  65 +
  66 + problem prob;
  67 + prob.n = samples.cols;
  68 + prob.l = samples.rows;
  69 + prob.bias = -1;
  70 + prob.y = new double[prob.l];
  71 +
  72 + for (int i=0; i<prob.l; i++)
  73 + prob.y[i] = labels.at<float>(i,0);
  74 +
  75 + // Allocate enough memory for l feature_nodes pointers
  76 + prob.x = new feature_node*[prob.l];
  77 + feature_node *x_space = new feature_node[(prob.n+1)*prob.l];
  78 +
  79 + int k = 0;
  80 + for (int i=0; i<prob.l; i++) {
  81 + prob.x[i] = &x_space[k];
  82 + for (int j=0; j<prob.n; j++) {
  83 + x_space[k].index = j+1;
  84 + x_space[k].value = samples.at<float>(i,j);
  85 + k++;
  86 + }
  87 + x_space[k++].index = -1;
  88 + }
  89 +
  90 + parameter param;
  91 + param.C = 1;
  92 + param.eps = FLT_EPSILON;
  93 + param.solver_type = L2R_L2LOSS_SVC_DUAL;
  94 + param.nr_weight = 0;
  95 + param.p = 1;
  96 + param.weight_label = NULL;
  97 + param.weight = NULL;
  98 +
  99 + m = train_svm(&prob, &param);
  100 +
  101 + delete x_space;
  102 + delete prob.x;
  103 + delete prob.y;
  104 + }
  105 +
  106 + void project(const Template &src, Template &dst) const
  107 + {
  108 + dst = src;
  109 +
  110 + Mat sample = src.m().reshape(1,1);
  111 + feature_node *x_space = new feature_node[sample.cols];
  112 +
  113 + // Assign the address of the ith instance to be the address of the jth feature
  114 + for (int j=0; j<sample.cols; j++) {
  115 + x_space[j].index = j+1;
  116 + x_space[j].value = sample.at<float>(0,j);
  117 + }
  118 + x_space[sample.cols].index = -1;
  119 +
  120 + double prob_estimates[1];
  121 + float prediction = predict_values(m,x_space,prob_estimates);
  122 +
  123 + delete x_space;
  124 + dst.m() = Mat(1, 1, CV_32F);
  125 + dst.m().at<float>(0, 0) = prob_estimates[0];
  126 + }
  127 +
  128 + void store(QDataStream &stream) const
  129 + {
  130 + QString filename = QString::number(qrand());
  131 + stream << filename;
  132 + save_model(filename.toStdString().c_str(),m);
  133 + }
  134 +
  135 + void load(QDataStream &stream)
  136 + {
  137 + QString filename;
  138 + stream >> filename;
  139 + m = load_model(filename.toStdString().c_str());
  140 + }
  141 +};
  142 +
  143 +BR_REGISTER(Transform, LinearSVM)
  144 +
  145 +} // namespace br
  146 +
  147 +#include "liblinear.moc"
... ...
share/openbr/cmake/FindLibLinear.cmake 0 โ†’ 100644
  1 +find_path(LibLinear_DIR linear.h ${CMAKE_SOURCE_DIR}/3rdparty/*)
  2 +
  3 +message(${LibLinear_DIR})
  4 +mark_as_advanced(LibLinear_DIR)
  5 +include_directories(${LibLinear_DIR})
  6 +include_directories(${LibLinear_DIR}/blas)
  7 +
  8 +set(LibLinear_SRC ${LibLinear_DIR}/linear.cpp
  9 + ${LibLinear_DIR}/tron.cpp
  10 + ${LibLinear_DIR}/blas/daxpy.c
  11 + ${LibLinear_DIR}/blas/ddot.c
  12 + ${LibLinear_DIR}/blas/dnrm2.c
  13 + ${LibLinear_DIR}/blas/dscal.c)
... ...