Compute PSI(x,label).
(self, x, label)
| 213 | self.labels = labels |
| 214 | |
| 215 | def make_psi(self, x, label): |
| 216 | """Compute PSI(x,label).""" |
| 217 | # All we are doing here is taking x, which is a 3 dimensional sample |
| 218 | # vector in this example program, and putting it into one of 3 places in |
| 219 | # a 9 dimensional PSI vector, which we then return. So this function |
| 220 | # returns PSI(x,label). To see why we setup PSI like this, recall how |
| 221 | # predict_label() works. It takes in a 9 dimensional weight vector and |
| 222 | # breaks the vector into 3 pieces. Each piece then defines a different |
| 223 | # classifier and we use them in a one-vs-all manner to predict the |
| 224 | # label. So now that we are in the structural SVM code we have to |
| 225 | # define the PSI vector to correspond to this usage. That is, we need |
| 226 | # to setup PSI so that argmax_y dot(weights,PSI(x,y)) == |
| 227 | # predict_label(weights,x). This is how we tell the structural SVM |
| 228 | # solver what kind of problem we are trying to solve. |
| 229 | # |
| 230 | # It's worth emphasizing that the single biggest step in using a |
| 231 | # structural SVM is deciding how you want to represent PSI(x,label). It |
| 232 | # is always a vector, but deciding what to put into it to solve your |
| 233 | # problem is often not a trivial task. Part of the difficulty is that |
| 234 | # you need an efficient method for finding the label that makes |
| 235 | # dot(w,PSI(x,label)) the biggest. Sometimes this is easy, but often |
| 236 | # finding the max scoring label turns into a difficult combinatorial |
| 237 | # optimization problem. So you need to pick a PSI that doesn't make the |
| 238 | # label maximization step intractable but also still well models your |
| 239 | # problem. |
| 240 | # |
| 241 | # Create a dense vector object (note that you can also use unsorted |
| 242 | # sparse vectors (i.e. dlib.sparse_vector objects) to represent your |
| 243 | # PSI vector. This is useful if you have very high dimensional PSI |
| 244 | # vectors that are mostly zeros. In the context of this example, you |
| 245 | # would simply return a dlib.sparse_vector at the end of make_psi() and |
| 246 | # the rest of the example would still work properly. ). |
| 247 | psi = dlib.vector() |
| 248 | # Set it to have 9 dimensions. Note that the elements of the vector |
| 249 | # are 0 initialized. |
| 250 | psi.resize(self.num_dimensions) |
| 251 | dims = len(x) |
| 252 | if label == 0: |
| 253 | for i in range(0, dims): |
| 254 | psi[i] = x[i] |
| 255 | elif label == 1: |
| 256 | for i in range(dims, 2 * dims): |
| 257 | psi[i] = x[i - dims] |
| 258 | else: # the label must be 2 |
| 259 | for i in range(2 * dims, 3 * dims): |
| 260 | psi[i] = x[i - 2 * dims] |
| 261 | return psi |
| 262 | |
| 263 | # Now we get to the two member functions that are directly called by |
| 264 | # dlib.solve_structural_svm_problem(). |
no test coverage detected