SHOGUN  3.2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
StochasticSOSVM.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 2013 Shell Hu
8  * Copyright (C) 2013 Shell Hu
9  */
10 
14 
15 using namespace shogun;
16 
19 {
20  init();
21 }
22 
24  CStructuredModel* model,
25  CStructuredLabels* labs,
26  bool do_weighted_averaging,
27  bool verbose)
28 : CLinearStructuredOutputMachine(model, labs)
29 {
30  REQUIRE(model != NULL && labs != NULL,
31  "%s::CStochasticSOSVM(): model and labels cannot be NULL!\n", get_name());
32 
33  REQUIRE(labs->get_num_labels() > 0,
34  "%s::CStochasticSOSVM(): number of labels should be greater than 0!\n", get_name());
35 
36  init();
37  m_lambda = 1.0 / labs->get_num_labels();
38  m_do_weighted_averaging = do_weighted_averaging;
39  m_verbose = verbose;
40 }
41 
42 void CStochasticSOSVM::init()
43 {
44  SG_ADD(&m_lambda, "lambda", "Regularization constant", MS_NOT_AVAILABLE);
45  SG_ADD(&m_num_iter, "num_iter", "Number of iterations", MS_NOT_AVAILABLE);
46  SG_ADD(&m_do_weighted_averaging, "do_weighted_averaging", "Do weighted averaging", MS_NOT_AVAILABLE);
47  SG_ADD(&m_debug_multiplier, "debug_multiplier", "Debug multiplier", MS_NOT_AVAILABLE);
48  SG_ADD(&m_rand_seed, "rand_seed", "Random seed", MS_NOT_AVAILABLE);
49 
50  m_lambda = 1.0;
51  m_num_iter = 50;
52  m_do_weighted_averaging = true;
53  m_debug_multiplier = 0;
54  m_rand_seed = 1;
55 }
56 
58 {
59 }
60 
62 {
63  return CT_STOCHASTICSOSVM;
64 }
65 
67 {
68  SG_DEBUG("Entering CStochasticSOSVM::train_machine.\n");
69  if (data)
70  set_features(data);
71 
72  // Initialize the model for training
74  // Check that the scenary is correct to start with training
76  SG_DEBUG("The training setup is correct.\n");
77 
78  // Dimensionality of the joint feature space
79  int32_t M = m_model->get_dim();
80  // Number of training examples
82 
83  SG_DEBUG("M=%d, N =%d.\n", M, N);
84 
85  // Initialize the weight vector
87  m_w.zero();
88 
89  SGVector<float64_t> w_avg;
90  if (m_do_weighted_averaging)
91  w_avg = m_w.clone();
92 
93  // logging
94  if (m_verbose)
95  {
96  if (m_helper != NULL)
98 
99  m_helper = new CSOSVMHelper();
100  SG_REF(m_helper);
101  }
102 
103  int32_t debug_iter = 1;
104  if (m_debug_multiplier == 0)
105  {
106  debug_iter = N;
107  m_debug_multiplier = 100;
108  }
109 
110  CMath::init_random(m_rand_seed);
111 
112  // Main loop
113  int32_t k = 0;
114  for (int32_t pi = 0; pi < m_num_iter; ++pi)
115  {
116  for (int32_t si = 0; si < N; ++si)
117  {
118  // 1) Picking random example
119  int32_t i = CMath::random(0, N-1);
120 
121  // 2) solve the loss-augmented inference for point i
122  CResultSet* result = m_model->argmax(m_w, i);
123 
124  // 3) get the subgradient
125  // psi_i(y) := phi(x_i,y_i) - phi(x_i, y)
126  SGVector<float64_t> psi_i(M);
127  SGVector<float64_t> w_s(M);
128 
130  1.0, result->psi_truth.vector, -1.0, result->psi_pred.vector, psi_i.vlen);
131 
132  w_s = psi_i.clone();
133  w_s.scale(1.0 / (N*m_lambda));
134 
135  // 4) step-size gamma
136  float64_t gamma = 1.0 / (k+1.0);
137 
138  // 5) finally update the weights
140  1.0-gamma, m_w.vector, gamma*N, w_s.vector, m_w.vlen);
141 
142  // 6) Optionally, update the weighted average
143  if (m_do_weighted_averaging)
144  {
145  float64_t rho = 2.0 / (k+2.0);
147  1.0-rho, w_avg.vector, rho, m_w.vector, w_avg.vlen);
148  }
149 
150  k += 1;
151  SG_UNREF(result);
152 
153  // Debug: compute objective and training error
154  if (m_verbose && k == debug_iter)
155  {
156  SGVector<float64_t> w_debug;
157  if (m_do_weighted_averaging)
158  w_debug = w_avg.clone();
159  else
160  w_debug = m_w.clone();
161 
162  float64_t primal = CSOSVMHelper::primal_objective(w_debug, m_model, m_lambda);
163  float64_t train_error = CSOSVMHelper::average_loss(w_debug, m_model);
164 
165  SG_DEBUG("pass %d (iteration %d), SVM primal = %f, train_error = %f \n",
166  pi, k, primal, train_error);
167 
168  m_helper->add_debug_info(primal, (1.0*k) / N, train_error);
169 
170  debug_iter = CMath::min(debug_iter+N, debug_iter*(1+m_debug_multiplier/100));
171  }
172  }
173  }
174 
175  if (m_do_weighted_averaging)
176  m_w = w_avg.clone();
177 
178  if (m_verbose)
179  m_helper->terminate();
180 
181  SG_DEBUG("Leaving CStochasticSOSVM::train_machine.\n");
182  return true;
183 }
184 
186 {
187  return m_lambda;
188 }
189 
191 {
192  m_lambda = lbda;
193 }
194 
196 {
197  return m_num_iter;
198 }
199 
200 void CStochasticSOSVM::set_num_iter(int32_t num_iter)
201 {
202  m_num_iter = num_iter;
203 }
204 
206 {
207  return m_debug_multiplier;
208 }
209 
211 {
212  m_debug_multiplier = multiplier;
213 }
214 
216 {
217  return m_rand_seed;
218 }
219 
220 void CStochasticSOSVM::set_rand_seed(uint32_t rand_seed)
221 {
222  m_rand_seed = rand_seed;
223 }
224 

SHOGUN Machine Learning Toolbox - Documentation