File: assignment_function_abstract.h

package info (click to toggle)
mldemos 0.5.1-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 32,224 kB
  • ctags: 46,525
  • sloc: cpp: 306,887; ansic: 167,718; ml: 126; sh: 109; makefile: 2
file content (301 lines) | stat: -rw-r--r-- 11,203 bytes parent folder | download | duplicates (4)
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
// Copyright (C) 2011  Davis E. King (davis@dlib.net)
// License: Boost Software License   See LICENSE.txt for the full license.
#undef DLIB_ASSIGNMENT_FuNCTION_ABSTRACT_H__
#ifdef DLIB_ASSIGNMENT_FuNCTION_ABSTRACT_H__

#include <vector>
#include "../optimization/max_cost_assignment_abstract.h"

namespace dlib
{

// ----------------------------------------------------------------------------------------

    class example_feature_extractor
    {
        /*!
            WHAT THIS OBJECT REPRESENTS
                This object defines the interface a feature extractor must implement
                if it is to be used with the assignment_function defined at the bottom
                of this file.  
                
                The model used by assignment_function objects is the following.  
                Given two sets of objects, the Left Hand Set (LHS) and Right Hand Set (RHS),
                find a one-to-one mapping M from LHS into RHS such that:
                    M == argmax_m  sum_{l in LHS} match_score(l,m(l))
                Where match_score() returns a scalar value indicating how good it is
                to say l maps to the RHS element m(l).  Additionally, in this model, 
                m() is allowed to indicate that l doesn't map to anything, and in this 
                case it is excluded from the sum.    

                Finally, match_score() is defined as: 
                    match_score(l,r) == dot(w, PSI(l,r))
                where l is an element of LHS, r is an element of RHS, and
                w is a parameter vector.

                Therefore, a feature extractor defines how the PSI() feature vector 
                is calculated.  In particular, PSI() is defined by the get_features()
                method of this class.

            THREAD SAFETY
                Instances of this object should be thread safe, that is, it should 
                be safe for multiple threads to make concurrent calls to the member 
                functions of this object.

        !*/

    public:

        // This type should be a dlib::matrix capable of storing column vectors
        // or an unsorted sparse vector type as defined in dlib/svm/sparse_vector_abstract.h.
        typedef matrix_or_sparse_vector_type feature_vector_type;

        // These two typedefs define the types used to represent an element in 
        // the left hand and right hand sets.  You can use any copyable types here.
        typedef user_defined_type_1 lhs_element;
        typedef user_defined_type_2 rhs_element;

        unsigned long num_features(
        ) const;
        /*!
            ensures
                - returns the dimensionality of the PSI() feature vector.  
        !*/

        void get_features (
            const lhs_element& left,
            const rhs_element& right,
            feature_vector_type& feats
        ) const;
        /*!
            ensures
                - #feats == PSI(left,right)
                  (i.e. This function computes a feature vector which, in some sense, 
                  captures information useful for deciding if matching left to right 
                  is "good").
        !*/

    };

// ----------------------------------------------------------------------------------------

    void serialize(
        const example_feature_extractor& item,
        std::ostream& out
    );
    /*!
        provides serialization support 
    !*/

    void deserialize(
        example_feature_extractor& item, 
        std::istream& in
    );
    /*!
        provides deserialization support 
    !*/


// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------

    template <
        typename feature_extractor 
        >
    class assignment_function
    {
        /*!
            REQUIREMENTS ON feature_extractor
                It must be an object that implements an interface compatible with 
                the example_feature_extractor discussed above.

            WHAT THIS OBJECT REPRESENTS
                This object is a tool for solving the optimal assignment problem given a 
                user defined method for computing the quality of any particular assignment. 

                To define this precisely, suppose you have two sets of objects, a 
                Left Hand Set (LHS) and a Right Hand Set (RHS) and you want to 
                find a one-to-one mapping M from LHS into RHS such that:
                    M == argmax_m  sum_{l in LHS} match_score(l,m(l))
                Where match_score() returns a scalar value indicating how good it is
                to say l maps to the RHS element m(l).  Additionally, in this model, 
                m() is allowed to indicate that l doesn't map to anything, and in this 
                case it is excluded from the sum.    

                Finally, this object supports match_score() functions of the form: 
                    match_score(l,r) == dot(w, PSI(l,r))
                where l is an element of LHS, r is an element of RHS, w is a parameter 
                vector, and PSI() is defined by the feature_extractor template argument.  
        !*/

    public:

        typedef typename feature_extractor::lhs_element  lhs_element;
        typedef typename feature_extractor::rhs_element  rhs_element;
        typedef          std::vector<long>               label_type;
        typedef          label_type                      result_type;
        typedef std::pair<std::vector<lhs_element>, std::vector<rhs_element> > sample_type;

        assignment_function(
        );
        /*!
            ensures
                - #get_feature_extractor() == feature_extractor() 
                  (i.e. it will have its default value)
                - #get_weights().size() == #get_feature_extractor().num_features()
                - #get_weights() == 0
                - #forces_assignment() == false 
        !*/

        explicit assignment_function(
            const matrix<double,0,1>& weights
        );
        /*!
            requires
                - feature_extractor().num_features() == weights.size()
            ensures
                - #get_feature_extractor() == feature_extractor() 
                  (i.e. it will have its default value)
                - #get_weights() == weights
                - #forces_assignment() == false 
        !*/

        assignment_function(
            const matrix<double,0,1>& weights,
            const feature_extractor& fe
        );
        /*!
            requires
                - fe.num_features() == weights.size()
            ensures
                - #get_feature_extractor() == fe
                - #get_weights() == weights
                - #forces_assignment() == false 
        !*/

        assignment_function(
            const matrix<double,0,1>& weights,
            const feature_extractor& fe,
            bool force_assignment
        );
        /*!
            requires
                - fe.num_features() == weights.size()
            ensures
                - #get_feature_extractor() == fe
                - #get_weights() == weights
                - #forces_assignment() == force_assignment
        !*/

        const feature_extractor& get_feature_extractor (
        ) const;
        /*!
            ensures
                - returns the feature extractor used by this object
        !*/

        const matrix<double,0,1>& get_weights (
        ) const;
        /*!
            ensures
                - returns the parameter vector (w) associated with this assignment function. 
                  The length of the vector is get_feature_extractor().num_features().  
        !*/

        bool forces_assignment (
        ) const; 
        /*!
            ensures
                - returns true if this object is in the "forced assignment mode" and false
                  otherwise.
                - When deciding how to match LHS to RHS, this object can operate in one of 
                  two modes.  In the default mode, this object will indicate that there is 
                  no match for an element of LHS if the best matching element of RHS would 
                  result in a negative match_score().  However, in the "forced assignment mode",
                  this object will always make the assignment if there is an available 
                  element in RHS, regardless of the match_score().

                  Another way to understand this distinction is to consider an example.  
                  Suppose LHS and RHS both contain 10 elements.  Then in the default mode, 
                  it is possible for this object to indicate that there are anywhere between 
                  0 to 10 matches between LHS and RHS.  However, in forced assignment mode 
                  it will always indicate exactly 10 matches.   
        !*/

        result_type operator()(
            const std::vector<lhs_element>& lhs,
            const std::vector<rhs_element>& rhs 
        ) const
        /*!
            ensures
                - returns a vector ASSIGN such that:
                    - ASSIGN.size() == lhs.size()
                    - if (ASSIGN[i] != -1) then
                        - lhs[i] is predicted to associate to rhs[ASSIGN[i]].
                    - else
                        - lhs[i] doesn't associate with anything in rhs.
                    - All values in ASSIGN which are not equal to -1 are unique.  
                      That is, ASSIGN will never indicate that more than one element
                      of lhs is assigned to a particular element of rhs.
        !*/

        result_type operator() (
            const sample_type& item
        ) const;
        /*!
            ensures
                - returns (*this)(item.first, item.second);
        !*/

        void predict_assignments (
            const sample_type& item,
            result_type& assignment
        ) const;
        /*!
            ensures
                - #assignment == (*this)(item)
        !*/

        void predict_assignments (
            const std::vector<lhs_element>& lhs,
            const std::vector<rhs_element>& rhs 
            result_type& assignment
        ) const;
        /*!
            ensures
                - #assignment == (*this)(lhs,rhs)
        !*/
    };

// ----------------------------------------------------------------------------------------

    template <
        typename feature_extractor
        >
    void serialize (
        const assignment_function<feature_extractor>& item,
        std::ostream& out
    );
    /*!
        provides serialization support 
    !*/

// ----------------------------------------------------------------------------------------

    template <
        typename feature_extractor
        >
    void deserialize (
        assignment_function<feature_extractor>& item,
        std::istream& in 
    );
    /*!
        provides deserialization support 
    !*/

// ----------------------------------------------------------------------------------------

}

#endif // DLIB_ASSIGNMENT_FuNCTION_ABSTRACT_H__