70 larank_kcache_t *
self;
71 self = SG_CALLOC (larank_kcache_t, 1);
74 self->func = kernelfunc;
75 self->prevbuddy =
self;
76 self->nextbuddy =
self;
77 self->cursize =
sizeof (larank_kcache_t);
78 self->maxsize = 256 * 1024 * 1024;
79 self->qprev = SG_MALLOC(int32_t, 1);
80 self->qnext = SG_MALLOC(int32_t, 1);
81 self->rnext =
self->qnext + 1;
82 self->rprev =
self->qprev + 1;
88 static void xtruncate (larank_kcache_t *
self, int32_t k, int32_t nlen)
90 int32_t olen =
self->rsize[k];
98 memcpy (ndata, odata, nlen *
sizeof (
float32_t));
103 self->rnext[
self->rprev[k]] =
self->rnext[k];
104 self->rprev[
self->rnext[k]] =
self->rprev[k];
105 self->rnext[k] =
self->rprev[k] = k;
108 self->rdata[k] = ndata;
109 self->rsize[k] = nlen;
110 self->cursize += (int64_t) (nlen - olen) *
sizeof (
float32_t);
114 static void xpurge (larank_kcache_t *
self)
116 if (self->cursize > self->maxsize)
118 int32_t k =
self->rprev[-1];
119 while (self->cursize > self->maxsize && k != self->rnext[-1])
121 int32_t pk =
self->rprev[k];
132 self->maxsize = entries;
141 larank_kcache_t *nb =
self->nextbuddy;
142 larank_kcache_t *pb =
self->prevbuddy;
151 for (i = 0; i <
self->l; i++)
153 SG_FREE (self->rdata[i]);
155 SG_FREE (self->rdata);
157 SG_FREE (self->rsize);
159 SG_FREE (self->rdiag);
161 SG_FREE (self->qnext);
163 SG_FREE (self->qprev);
164 memset (
self, 0,
sizeof (larank_kcache_t));
169 static void xminsize (larank_kcache_t *
self, int32_t n)
171 int32_t ol =
self->l;
178 self->i2r = SG_REALLOC (int32_t, self->i2r, self->l, nl);
179 self->r2i = SG_REALLOC (int32_t, self->r2i, self->l, nl);
180 self->rsize = SG_REALLOC (int32_t, self->rsize, self->l, nl);
181 self->qnext = SG_REALLOC (int32_t, self->qnext, 1+self->l, (1 + nl));
182 self->qprev = SG_REALLOC (int32_t, self->qprev, 1+self->l, (1 + nl));
183 self->rdiag = SG_REALLOC (
float32_t, self->rdiag, self->l, nl);
184 self->rdata = SG_REALLOC (
float32_t*, self->rdata, self->l, nl);
185 self->rnext =
self->qnext + 1;
186 self->rprev =
self->qprev + 1;
187 for (i = ol; i < nl; i++)
206 static void xextend (larank_kcache_t *
self, int32_t k, int32_t nlen)
208 int32_t olen =
self->rsize[k];
215 memcpy (ndata, odata, olen *
sizeof (
float32_t));
218 self->rdata[k] = ndata;
219 self->rsize[k] = nlen;
220 self->cursize += (int64_t) (nlen - olen) *
sizeof (
float32_t);
221 self->maxrowlen =
CMath::max (self->maxrowlen, nlen);
225 static void xswap (larank_kcache_t *
self, int32_t i1, int32_t i2, int32_t r1, int32_t r2)
228 if (r1 < self->maxrowlen || r2 < self->maxrowlen)
231 int32_t k =
self->rnext[-1];
234 int32_t nk =
self->rnext[k];
235 int32_t n =
self->rsize[k];
236 int32_t rr =
self->i2r[k];
249 d[r1] =
self->rdiag[k];
253 int32_t arsize =
self->rsize[i2];
254 if (rr < arsize && rr != r1)
255 d[r1] =
self->rdata[i2][rr];
264 d[r2] =
self->rdiag[k];
268 int32_t arsize =
self->rsize[i1];
269 if (rr < arsize && rr != r2)
270 d[r2] =
self->rdata[i1][rr];
278 self->maxrowlen = mrl;
290 xswap (
self, self->r2i[r1], self->r2i[r2], r1, r2);
296 xswap (
self, self->r2i[r1], i2, r1, self->i2r[i2]);
302 larank_kcache_t *cache =
self->nextbuddy;
305 int32_t l = cache->l;
308 int32_t s = cache->rsize[i];
309 int32_t p = cache->i2r[j];
311 return cache->rdata[i][p];
312 if (i == j && s >= 0)
313 return cache->rdiag[i];
317 return cache->rdata[j][p];
319 cache = cache->nextbuddy;
321 while (cache !=
self);
323 return self->func->kernel(i, j);
332 return xquery (
self, i, j);
338 larank_kcache_t *p =
self;
339 larank_kcache_t *selflast =
self->prevbuddy;
340 larank_kcache_t *buddylast = buddy->prevbuddy;
342 ASSERT (self->func == buddy->func)
352 selflast->nextbuddy = buddy;
353 buddy->prevbuddy = selflast;
354 buddylast->nextbuddy =
self;
355 self->prevbuddy = buddylast;
362 if (i < self->l && len <= self->rsize[i])
364 self->rnext[
self->rprev[i]] =
self->rnext[i];
365 self->rprev[
self->rnext[i]] =
self->rprev[i];
371 if (i >= self->l || len >= self->l)
373 olen =
self->rsize[i];
378 self->rdiag[i] =
self->func->kernel(i, i);
379 olen =
self->rsize[i] = 0;
383 self->rsize[i] = olen;
384 for (p = olen; p < len; p++)
386 self->rsize[i] = len;
388 self->rnext[
self->rprev[i]] =
self->rnext[i];
389 self->rprev[
self->rnext[i]] =
self->rprev[i];
393 self->rnext[i] =
self->rnext[-1];
394 self->rnext[
self->rprev[i]] = i;
395 self->rprev[
self->rnext[i]] = i;
396 return self->rdata[i];
403 void LaRankOutput::initialize (
CKernel* kfunc, int64_t cache)
415 void LaRankOutput::destroy ()
426 float64_t LaRankOutput::computeScore (int32_t x_id)
438 float64_t LaRankOutput::computeGradient (int32_t xi_id, int32_t yi, int32_t ythis)
440 return (yi == ythis ? 1 : 0) - computeScore (xi_id);
448 for (int32_t r = 0; r < l; r++)
464 beta = SG_REALLOC(
float32_t, beta, l, l+1);
472 for (int32_t r = 0; r < l; r++)
475 g[r]=oldg - lambda * row[r];
481 void LaRankOutput::set_kernel_buddy (larank_kcache_t * bud)
487 int32_t LaRankOutput::cleanup ()
490 std::vector < int32_t >idx;
491 for (int32_t x = 0; x < l; x++)
493 if ((beta[x] < FLT_EPSILON) && (beta[x] > -FLT_EPSILON))
499 int32_t new_l = l - count;
500 for (int32_t xx = 0; xx < count; xx++)
502 int32_t i = idx[xx] - xx;
503 for (int32_t r = i; r < (l - 1); r++)
510 beta = SG_REALLOC(
float32_t, beta, l, new_l+1);
511 g = SG_REALLOC(
float32_t, g, l, new_l+1);
524 for (int32_t r = 0; r < l; r++)
532 float64_t LaRankOutput::getKii (int32_t x_id)
538 float64_t LaRankOutput::getBeta (int32_t x_id)
542 for (int32_t r = 0; r < l; r++)
548 return (xr < 0 ? 0 : beta[xr]);
552 float64_t LaRankOutput::getGradient (int32_t x_id)
556 for (int32_t r = 0; r < l; r++)
562 return (xr < 0 ? 0 : g[xr]);
564 bool LaRankOutput::isSupportVector (int32_t x_id)
const
568 for (int32_t r = 0; r < l; r++)
578 int32_t LaRankOutput::getSV (
float32_t* &sv)
const
582 for (int32_t r = 0; r < l; r++)
588 nb_seen_examples (0), nb_removed (0),
589 n_pro (0), n_rep (0), n_opt (0),
590 w_pro (1), w_rep (1), w_opt (1), y0 (0), m_dual (0),
591 batch_mode(true), step(0)
597 nb_seen_examples (0), nb_removed (0),
598 n_pro (0), n_rep (0), n_opt (0),
599 w_pro (1), w_rep (1), w_opt (1), y0 (0), m_dual (0),
600 batch_mode(true), step(0)
623 SG_ERROR(
"Numbert of vectors (%d) does not match number of labels (%d)\n",
642 for (int32_t i = 0; i <
nb_train; i++)
650 SG_DEBUG(
"Done: %d %% Train error (online): %f%%\n",
656 SG_DEBUG(
"End of iteration %d\n", n_it++)
657 SG_DEBUG(
"Train error (online): %f%%\n", (tr_err / nb_train) * 100)
666 int32_t num_classes = outputs.size();
668 SG_DEBUG(
"%d classes\n", num_classes)
672 for (outputhash_t::const_iterator it = outputs.begin (); it != outputs.end (); ++it)
674 const LaRankOutput* o=&(it->second);
676 larank_kcache_t* k=o->getKernel();
677 int32_t l=o->get_l();
682 SG_DEBUG(
"svm[%d] has %d sv, b=%f\n", i, l, 0.0)
686 for (int32_t j=0; j<l; j++)
708 outputs.insert (std::make_pair (yi, LaRankOutput ()));
709 LaRankOutput *cur = getOutput (yi);
711 if (outputs.size () == 1)
712 y0 = outputs.begin ()->first;
714 if (outputs.size () > 1)
716 LaRankOutput *out0 = getOutput (y0);
717 cur->set_kernel_buddy (out0->getKernel ());
721 LaRankPattern tpattern (x_id, yi);
722 LaRankPattern & pattern = (patterns.isPattern (x_id)) ? patterns.getPattern (x_id) : tpattern;
726 process_return_t pro_ret = process (pattern, processNew);
727 float64_t dual_increase = pro_ret.dual_increase;
729 float64_t coeff = dual_increase / (0.00001 + duration);
730 m_dual += dual_increase;
732 w_pro = 0.05 * coeff + (1 - 0.05) * w_pro;
740 if (w_pro < prop_min)
742 if (w_rep < prop_min)
744 if (w_opt < prop_min)
746 w_sum = w_pro + w_rep + w_opt;
752 else if ((r > w_pro) && (r <= w_pro + w_rep))
757 float64_t lcoeff = ldual_increase / (0.00001 + lduration);
758 m_dual += ldual_increase;
760 w_rep = 0.05 * lcoeff + (1 - 0.05) * w_rep;
767 float64_t lcoeff = ldual_increase / (0.00001 + lduration);
768 m_dual += ldual_increase;
770 w_opt = 0.05 * lcoeff + (1 - 0.05) * w_opt;
773 if (nb_seen_examples % 100 == 0)
774 nb_removed += cleanup ();
775 return pro_ret.ypred;
783 for (outputhash_t::iterator it = outputs.begin (); it != outputs.end ();++it)
785 float64_t score = it->second.computeScore (x_id);
786 if (score > score_max)
797 for (outputhash_t::iterator it = outputs.begin (); it != outputs.end ();++it)
798 it->second.destroy ();
808 for (uint32_t i = 0; i < patterns.maxcount (); ++i)
810 const LaRankPattern & p = patterns[i];
813 LaRankOutput *out = getOutput (p.y);
816 sum_bi += out->getBeta (p.x_id);
817 float64_t gi = out->computeGradient (p.x_id, p.y, p.y);
819 for (outputhash_t::iterator it = outputs.begin (); it != outputs.end (); ++it)
821 if (it->first != p.y && it->second.isSupportVector (p.x_id))
824 it->second.computeGradient (p.x_id, p.y, it->first);
837 return outputs.size ();
844 for (outputhash_t::const_iterator it = outputs.begin (); it != outputs.end (); ++it)
847 res += it->second.getSV (sv);
857 for (uint32_t i = 0; i < patterns.maxcount (); ++i)
859 const LaRankPattern & p = patterns[i];
862 for (outputhash_t::iterator it = outputs.begin (); it != outputs.end (); ++it)
863 if (it->second.getBeta (p.x_id))
864 res += it->second.getBeta (p.x_id) * it->second.computeScore (p.x_id);
873 for (uint32_t i = 0; i < patterns.maxcount (); ++i)
875 const LaRankPattern & p = patterns[i];
878 LaRankOutput *out = getOutput (p.y);
881 res += out->getBeta (p.x_id);
886 LaRankOutput *CLaRank::getOutput (int32_t index)
888 outputhash_t::iterator it = outputs.find (index);
889 return it == outputs.end ()? NULL : &it->second;
893 CLaRank::process_return_t CLaRank::process (
const LaRankPattern & pattern, process_type ptype)
895 process_return_t pro_ret = process_return_t (0, 0);
900 std::vector < outputgradient_t > outputgradients;
904 std::vector < outputgradient_t > outputscores;
907 for (outputhash_t::iterator it = outputs.begin (); it != outputs.end (); ++it)
909 if (ptype != processOptimize
910 || it->second.isSupportVector (pattern.x_id))
913 it->second.computeGradient (pattern.x_id, pattern.y, it->first);
914 outputgradients.push_back (outputgradient_t (it->first, g));
915 if (it->first == pattern.y)
916 outputscores.push_back (outputgradient_t (it->first, (1 - g)));
918 outputscores.push_back (outputgradient_t (it->first, -g));
922 std::sort (outputgradients.begin (), outputgradients.end ());
927 std::sort (outputscores.begin (), outputscores.end ());
928 pro_ret.ypred = outputscores[0].output;
933 outputgradient_t ygp;
934 LaRankOutput *outp = NULL;
936 for (p = 0; p < outputgradients.size (); ++p)
938 outputgradient_t & current = outputgradients[p];
939 LaRankOutput *output = getOutput (current.output);
940 bool support = ptype == processOptimize || output->isSupportVector (pattern.x_id);
941 bool goodclass = current.output == pattern.y;
942 if ((!support && goodclass) ||
943 (support && output->getBeta (pattern.x_id) < (goodclass ?
get_C() : 0)))
950 if (p == outputgradients.size ())
956 outputgradient_t ygm;
957 LaRankOutput *outm = NULL;
959 for (m = outputgradients.size () - 1; m >= 0; --m)
961 outputgradient_t & current = outputgradients[m];
962 LaRankOutput *output = getOutput (current.output);
963 bool support = ptype == processOptimize || output->isSupportVector (pattern.x_id);
964 bool goodclass = current.output == pattern.y;
965 if (!goodclass || (support && output->getBeta (pattern.x_id) > 0))
978 if ((ygp.gradient - ygm.gradient) <
tau)
980 if (ptype == processNew)
981 patterns.insert (pattern);
986 float64_t kii = outp->getKii (pattern.x_id);
987 float64_t lambda = (ygp.gradient - ygm.gradient) / (2 * kii);
988 if (ptype == processOptimize || outp->isSupportVector (pattern.x_id))
990 float64_t beta = outp->getBeta (pattern.x_id);
991 if (ygp.output == pattern.y)
1002 outp->update (pattern.x_id, lambda, ygp.gradient);
1003 outm->update (pattern.x_id, -lambda, ygm.gradient);
1005 pro_ret.dual_increase = lambda * ((ygp.gradient - ygm.gradient) - lambda * kii);
1012 if (patterns.size ())
1014 for (int32_t n = 0; n < 10; ++n)
1016 process_return_t pro_ret = process (patterns.sample (), processOld);
1017 if (pro_ret.dual_increase)
1018 return pro_ret.dual_increase;
1028 if (patterns.size ())
1030 for (int32_t n = 0; n < 10; ++n)
1032 process_return_t pro_ret =
1033 process (patterns.sample(), processOptimize);
1034 dual_increase += pro_ret.dual_increase;
1037 return dual_increase;
1041 uint32_t CLaRank::cleanup ()
virtual bool init(CFeatures *lhs, CFeatures *rhs)
static void xtruncate(larank_kcache_t *self, int32_t k, int32_t nlen)
static float32_t * larank_kcache_query_row(larank_kcache_t *self, int32_t i, int32_t len)
bool batch_mode
whether to use online learning or batch training
virtual ELabelType get_label_type() const =0
static void larank_kcache_set_maximum_size(larank_kcache_t *self, int64_t entries)
The class Labels models labels, i.e. class assignments of objects.
bool train_machine(CFeatures *data)
virtual int32_t get_num_labels() const =0
static void xswap(larank_kcache_t *self, int32_t i1, int32_t i2, int32_t r1, int32_t r2)
multi-class labels 0,1,...
static float64_t log10(float64_t v)
void(* update)(float *foo, float bar)
virtual int32_t get_num_vectors() const =0
static float64_t larank_kcache_query(larank_kcache_t *self, int32_t i, int32_t j)
virtual int32_t add(int32_t x_id, int32_t yi)
virtual int32_t get_num_vec_lhs()
virtual float64_t computeGap()
static void larank_kcache_set_buddy(larank_kcache_t *self, larank_kcache_t *buddy)
static float64_t get_curtime()
static void xextend(larank_kcache_t *self, int32_t k, int32_t nlen)
Multiclass Labels for multi-class classification.
static float64_t xquery(larank_kcache_t *self, int32_t i, int32_t j)
static void larank_kcache_swap_rr(larank_kcache_t *self, int32_t r1, int32_t r2)
void set_bias(float64_t bias)
static void clear_cancel()
bool set_alpha(int32_t idx, float64_t val)
bool set_support_vector(int32_t idx, int32_t val)
static int32_t * larank_kcache_r2i(larank_kcache_t *self, int32_t n)
static float64_t dot(const bool *v1, const bool *v2, int32_t n)
Compute dot product between v1 and v2 (blas optimized)
virtual uint32_t getNumOutputs() const
static bool cancel_computations()
virtual int32_t get_num_vec_rhs()
#define SG_ABS_PROGRESS(...)
static void larank_kcache_destroy(larank_kcache_t *self)
static void xminsize(larank_kcache_t *self, int32_t n)
all of classes and functions are contained in the shogun namespace
static void larank_kcache_swap_ri(larank_kcache_t *self, int32_t r1, int32_t i2)
static larank_kcache_t * larank_kcache_create(CKernel *kernelfunc)
The class Features is the base class of all feature objects.
bool create_multiclass_svm(int32_t num_classes)
static void xpurge(larank_kcache_t *self)
A generic Support Vector Machine Interface.
virtual int32_t predict(int32_t x_id)
multiclass one vs rest strategy used to train generic multiclass machines for K-class problems with b...
bool set_svm(int32_t num, CSVM *svm)
int32_t step
progess output