Commit ef7897a4477721b6abba31363c156391be8071d5
1 parent
e76f4ef8
Initial work with liblinear
Showing
3 changed files
with
167 additions
and
0 deletions
openbr/plugins/liblinear.cmake
0 โ 100644
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, ¶m); | ||
| 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) |