SHOGUN  3.2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OnlineLibLinear.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) 2007-2010 Soeren Sonnenburg
8  * Written (W) 2011 Shashwat Lal Das
9  * Modifications (W) 2013 Thoralf Klein
10  * Copyright (c) 2007-2009 The LIBLINEAR Project.
11  * Copyright (C) 2007-2010 Fraunhofer Institute FIRST and Max-Planck-Society
12  */
13 
17 #include <shogun/lib/Time.h>
18 
19 using namespace shogun;
20 
23 {
24  init();
25 }
26 
28 {
29  init();
30  C1=C_reg;
31  C2=C_reg;
32  use_bias=true;
33 }
34 
36  float64_t C_reg, CStreamingDotFeatures* traindat)
37 {
38  init();
39  C1=C_reg;
40  C2=C_reg;
41  use_bias=true;
42 
43  set_features(traindat);
44 }
45 
47 {
48  init();
49  C1 = mch->C1;
50  C2 = mch->C2;
51  use_bias = mch->use_bias;
52 
53  set_features(mch->features);
54 
55  w_dim = mch->w_dim;
56  if (w_dim > 0)
57  {
58  w = SG_MALLOC(float32_t, w_dim);
59  memcpy(w, mch->w, w_dim*sizeof(float32_t));
60  }
61  else
62  {
63  w = NULL;
64  }
65  bias = mch->bias;
66 }
67 
68 
69 void COnlineLibLinear::init()
70 {
71  C1=1;
72  C2=1;
73  use_bias=false;
74 
75  m_parameters->add(&C1, "C1", "C Cost constant 1.");
76  m_parameters->add(&C2, "C2", "C Cost constant 2.");
77  m_parameters->add(&use_bias, "use_bias", "Indicates if bias is used.");
78 }
79 
81 {
82 }
83 
85 {
86  Cp = C1;
87  Cn = C2;
88  PGmax_old = CMath::INFTY;
89  PGmin_old = -CMath::INFTY;
90  PGmax_new = -CMath::INFTY;
91  PGmin_new = CMath::INFTY;
92 
93  diag[0]=0;diag[1]=0;diag[2]=0;
94  upper_bound[0]=Cn;upper_bound[1]=0;upper_bound[2]=Cp;
95 
96  bias = 0;
97 
98  PGmax_new = -CMath::INFTY;
99  PGmin_new = CMath::INFTY;
100 
101  v = 0;
102  nSV = 0;
103 }
104 
106 {
107  float64_t gap = PGmax_new - PGmin_new;
108 
109  SG_DONE()
110  SG_INFO("Optimization finished.\n")
111 
112  // calculate objective value
113  for (int32_t i=0; i<w_dim; i++)
114  v += w[i]*w[i];
115  v += bias*bias;
116 
117  SG_INFO("Objective value = %lf\n", v/2)
118  SG_INFO("nSV = %d\n", nSV)
119  SG_INFO("gap = %g\n", gap)
120 }
121 
123 {
124  alpha_current = 0;
125  if (label > 0)
126  y_current = +1;
127  else
128  y_current = -1;
129 
130  QD = diag[y_current + 1];
131  // Dot product of vector with itself
132  QD += SGVector<float32_t>::dot(ex.vector, ex.vector, ex.vlen);
133 
134  // Dot product of vector with learned weights
136 
137  if (use_bias)
138  G += bias;
139  G = G*y_current - 1;
140  // LINEAR TERM PART?
141 
142  C = upper_bound[y_current + 1];
143  G += alpha_current*diag[y_current + 1]; // Can be eliminated, since diag = 0 vector
144 
145  PG = 0;
146  if (alpha_current == 0) // This condition will always be true in the online version
147  {
148  if (G > PGmax_old)
149  {
150  return;
151  }
152  else if (G < 0)
153  PG = G;
154  }
155  else if (alpha_current == C)
156  {
157  if (G < PGmin_old)
158  {
159  return;
160  }
161  else if (G > 0)
162  PG = G;
163  }
164  else
165  PG = G;
166 
167  PGmax_new = CMath::max(PGmax_new, PG);
168  PGmin_new = CMath::min(PGmin_new, PG);
169 
170  if (fabs(PG) > 1.0e-12)
171  {
172  float64_t alpha_old = alpha_current;
173  alpha_current = CMath::min(CMath::max(alpha_current - G/QD, 0.0), C);
174  d = (alpha_current - alpha_old) * y_current;
175 
176  for (int32_t i=0; i < w_dim; ++i)
177  w[i] += d*ex[i];
178 
179 
180  if (use_bias)
181  bias += d;
182  }
183 
184  v += alpha_current*(alpha_current*diag[y_current + 1] - 2);
185  if (alpha_current > 0)
186  nSV++;
187 }
188 
190 {
191  alpha_current = 0;
192  if (label > 0)
193  y_current = +1;
194  else
195  y_current = -1;
196 
197  QD = diag[y_current + 1];
198  // Dot product of vector with itself
200 
201  // Dot product of vector with learned weights
202  G = ex.dense_dot(1.0,w,w_dim,0.0);
203 
204  if (use_bias)
205  G += bias;
206  G = G*y_current - 1;
207  // LINEAR TERM PART?
208 
209  C = upper_bound[y_current + 1];
210  G += alpha_current*diag[y_current + 1]; // Can be eliminated, since diag = 0 vector
211 
212  PG = 0;
213  if (alpha_current == 0) // This condition will always be true in the online version
214  {
215  if (G > PGmax_old)
216  {
217  return;
218  }
219  else if (G < 0)
220  PG = G;
221  }
222  else if (alpha_current == C)
223  {
224  if (G < PGmin_old)
225  {
226  return;
227  }
228  else if (G > 0)
229  PG = G;
230  }
231  else
232  PG = G;
233 
234  PGmax_new = CMath::max(PGmax_new, PG);
235  PGmin_new = CMath::min(PGmin_new, PG);
236 
237  if (fabs(PG) > 1.0e-12)
238  {
239  float64_t alpha_old = alpha_current;
240  alpha_current = CMath::min(CMath::max(alpha_current - G/QD, 0.0), C);
241  d = (alpha_current - alpha_old) * y_current;
242 
243  for (int32_t i=0; i < ex.num_feat_entries; i++)
244  w[ex.features[i].feat_index] += d*ex.features[i].entry;
245 
246 
247  if (use_bias)
248  bias += d;
249  }
250 
251  v += alpha_current*(alpha_current*diag[y_current + 1] - 2);
252  if (alpha_current > 0)
253  nSV++;
254 }
255 
257 {
259 
262  dynamic_cast<CStreamingDenseFeatures<float32_t> *>(feature);
263  if (feat == NULL)
264  SG_ERROR("Expected streaming dense feature <float32_t>\n")
265 
266  train_one(feat->get_vector(), label);
267  }
270  dynamic_cast<CStreamingSparseFeatures<float32_t> *>(feature);
271  if (feat == NULL)
272  SG_ERROR("Expected streaming sparse feature <float32_t>\n")
273 
274  train_one(feat->get_vector(), label);
275  }
276  else {
278  }
279 }

SHOGUN Machine Learning Toolbox - Documentation