decision_functions.cpp 3.18 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

#include <boost/python.hpp>
#include <boost/shared_ptr.hpp>
#include "serialize_pickle.h"
#include <dlib/svm.h>

using namespace dlib;
using namespace std;
using namespace boost::python;

typedef matrix<double,0,1> sample_type; 
typedef std::vector<std::pair<unsigned long,double> > sparse_vect;


template <typename decision_function>
double predict (
    const decision_function& df,
    const typename decision_function::kernel_type::sample_type& samp
)
{
    if (df.basis_vectors.size() == 0)
    {
        return 0;
    }
    else if (df.basis_vectors(0).size() != samp.size())
    {
        std::ostringstream sout;
Davis King's avatar
Davis King committed
28
29
30
        sout << "Input vector should have " << df.basis_vectors(0).size() 
             << " dimensions, not " << samp.size() << ".";
        PyErr_SetString( PyExc_ValueError, sout.str().c_str() );                                            
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
        boost::python::throw_error_already_set();   
    }
    return df(samp);
}

template <typename kernel_type>
void add_df (
    const std::string name
)
{
    typedef decision_function<kernel_type> df_type;
    class_<df_type>(name.c_str())
        .def("predict", &predict<df_type>)
        .def_pickle(serialize_pickle<df_type>());
}

Davis King's avatar
Davis King committed
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
template <typename df_type>
typename df_type::sample_type get_weights(
    const df_type& df
)
{
    if (df.basis_vectors.size() == 0)
    {
        PyErr_SetString( PyExc_ValueError, "Decision function is empty." );                                            
        boost::python::throw_error_already_set();   
    }
    df_type temp = simplify_linear_decision_function(df);
    return temp.basis_vectors(0);
}

template <typename df_type>
typename df_type::scalar_type get_bias(
    const df_type& df
)
{
    if (df.basis_vectors.size() == 0)
    {
        PyErr_SetString( PyExc_ValueError, "Decision function is empty." );                                            
        boost::python::throw_error_already_set();   
    }
    return df.b;
}

template <typename kernel_type>
void add_linear_df (
    const std::string name
)
{
    typedef decision_function<kernel_type> df_type;
    class_<df_type>(name.c_str())
        .def("predict", predict<df_type>)
        .def("get_weights", get_weights<df_type>)
        .def("get_bias", get_bias<df_type>)
        .def_pickle(serialize_pickle<df_type>());
}

87
88
void bind_decision_functions()
{
Davis King's avatar
Davis King committed
89
90
91
92
93
94
95
96
97
    add_linear_df<linear_kernel<sample_type> >("_decision_function_linear");
    add_linear_df<sparse_linear_kernel<sparse_vect> >("_decision_function_sparse_linear");

    add_df<histogram_intersection_kernel<sample_type> >("_decision_function_histogram_intersection");
    add_df<sparse_histogram_intersection_kernel<sparse_vect> >("_decision_function_sparse_histogram_intersection");

    add_df<polynomial_kernel<sample_type> >("_decision_function_polynomial");
    add_df<sparse_polynomial_kernel<sparse_vect> >("_decision_function_sparse_polynomial");

98
99
    add_df<radial_basis_kernel<sample_type> >("_decision_function_radial_basis");
    add_df<sparse_radial_basis_kernel<sparse_vect> >("_decision_function_sparse_radial_basis");
Davis King's avatar
Davis King committed
100
101
102

    add_df<sigmoid_kernel<sample_type> >("_decision_function_sigmoid");
    add_df<sparse_sigmoid_kernel<sparse_vect> >("_decision_function_sparse_sigmoid");
103
104
105
106
}