Vowpal Wabbit
memory_tree.cc
Go to the documentation of this file.
1 #include <algorithm>
2 #include <cmath>
3 #include <cstdio>
4 #include <float.h>
5 #include <time.h>
6 #include <sstream>
7 #include <ctime>
8 #include <memory>
9 
10 #include "reductions.h"
11 #include "rand48.h"
12 #include "vw.h"
13 #include "v_array.h"
14 
15 using namespace LEARNER;
16 using namespace VW::config;
17 
18 namespace memory_tree_ns
19 {
22 template <typename T>
23 void remove_at_index(v_array<T>& array, uint32_t index)
24 {
25  if (index >= array.size())
26  {
27  std::cout << "ERROR: index is larger than the size" << std::endl;
28  return;
29  }
30  if (index == array.size() - 1)
31  {
32  array.pop();
33  return;
34  }
35  for (size_t i = index + 1; i < array.size(); i++)
36  {
37  array[i - 1] = array[i];
38  }
39  array.pop();
40  return;
41 }
42 
43 void copy_example_data(example* dst, example* src, bool oas = false) // copy example data.
44 {
45  if (oas == false)
46  {
47  dst->l = src->l;
48  dst->l.multi.label = src->l.multi.label;
49  }
50  else
51  {
54  }
55  VW::copy_example_data(false, dst, src);
56 }
57 
58 inline void free_example(example* ec)
59 {
60  VW::dealloc_example(nullptr, *ec);
61  free(ec);
62 }
63 
65 // kronecker_prod at feature level:
66 
68  features& f1, features& f2, features& prod_f, float& total_sum_feat_sq, float norm_sq1, float norm_sq2)
69 {
70  prod_f.delete_v();
71  if (f2.indicies.size() == 0)
72  return;
73 
74  float denominator = pow(norm_sq1 * norm_sq2, 0.5f);
75  size_t idx1 = 0;
76  size_t idx2 = 0;
77 
78  while (idx1 < f1.size() && idx2 < f2.size())
79  {
80  uint64_t ec1pos = f1.indicies[idx1];
81  uint64_t ec2pos = f2.indicies[idx2];
82 
83  if (ec1pos < ec2pos)
84  idx1++;
85  else if (ec1pos > ec2pos)
86  idx2++;
87  else
88  {
89  prod_f.push_back(f1.values[idx1] * f2.values[idx2] / denominator, ec1pos);
90  total_sum_feat_sq += f1.values[idx1] * f2.values[idx2] / denominator; // make this out of loop
91  idx1++;
92  idx2++;
93  }
94  }
95 }
96 
97 int cmpfunc(const void* a, const void* b) { return *(char*)a - *(char*)b; }
98 
99 void diag_kronecker_product_test(example& ec1, example& ec2, example& ec, bool oas = false)
100 {
101  // copy_example_data(&ec, &ec1, oas); //no_feat false, oas: true
102  VW::dealloc_example(nullptr, ec, nullptr); // clear ec
103  copy_example_data(&ec, &ec1, oas);
104 
105  ec.total_sum_feat_sq = 0.0; // sort namespaces. pass indices array into sort...template (leave this to the end)
106 
107  qsort(ec1.indices.begin(), ec1.indices.size(), sizeof(namespace_index), cmpfunc);
108  qsort(ec2.indices.begin(), ec2.indices.size(), sizeof(namespace_index), cmpfunc);
109 
110  size_t idx1 = 0;
111  size_t idx2 = 0;
112  while (idx1 < ec1.indices.size() && idx2 < ec2.indices.size())
113  // for (size_t idx1 = 0, idx2 = 0; idx1 < ec1.indices.size() && idx2 < ec2.indices.size(); idx1++)
114  {
115  namespace_index c1 = ec1.indices[idx1];
116  namespace_index c2 = ec2.indices[idx2];
117  if (c1 < c2)
118  idx1++;
119  else if (c1 > c2)
120  idx2++;
121  else
122  {
125  idx1++;
126  idx2++;
127  }
128  }
129 }
130 
133 
136 
137 // construct node for tree.
138 struct node
139 {
140  uint64_t parent; // parent index
141  int internal;
142  // bool internal; //an internal or leaf
143  uint32_t depth; // depth.
144  uint64_t base_router; // use to index router.
145  uint64_t left; // left child.
146  uint64_t right; // right child.
147 
148  double nl; // number of examples routed to left.
149  double nr; // number of examples routed to right.
150 
152 
153  node() // construct:
154  {
155  parent = 0;
156  internal = 0; // 0:not used, 1:internal, -1:leaf
157  // internal = false;
158  depth = 0;
159  base_router = 0;
160  left = 0;
161  right = 0;
162  nl = 0.001; // initilze to 1, as we need to do nl/nr.
163  nr = 0.001;
164  examples_index = v_init<uint32_t>();
165  }
166 };
167 
168 // memory_tree
170 {
171  vw* all;
172  std::shared_ptr<rand_state> _random_state;
173 
174  v_array<node> nodes; // array of nodes.
175  v_array<example*> examples; // array of example points
176 
178  size_t max_nodes;
180  size_t max_routers;
182  float alpha; // for cpt type of update.
183  uint64_t routers_used;
184  int iter;
185  uint32_t dream_repeats; // number of dream operations per example.
186 
188 
189  size_t max_depth;
191 
192  float construct_time; // recording the time for constructing the memory tree
193  float test_time; // recording the test time
194 
195  uint32_t num_mistakes;
196  bool learn_at_leaf; // indicator for turning on learning the scorer function at the leaf level
197 
198  bool test_mode;
199 
200  size_t current_pass; // for tracking # of passes over the dataset
201  size_t final_pass;
202 
203  int top_K; // commands:
204  bool oas; // indicator for multi-label classification (oas = 1)
206 
207  bool online; // indicator for running CMT in online fashion
208 
209  float F1_score;
211 
213 
215  {
216  nodes = v_init<node>();
217  examples = v_init<example*>();
218  alpha = 0.5;
219  routers_used = 0;
220  iter = 0;
221  num_mistakes = 0;
222  test_mode = false;
223  max_depth = 0;
224  max_ex_in_leaf = 0;
225  construct_time = 0;
226  test_time = 0;
227  top_K = 1;
228  }
229 
231  {
232  for (auto& node : nodes) node.examples_index.delete_v();
233  nodes.delete_v();
234  for (auto ex : examples) free_example(ex);
235  examples.delete_v();
236  if (kprod_ec)
237  free_example(kprod_ec);
238  }
239 };
240 
241 float linear_kernel(const flat_example* fec1, const flat_example* fec2)
242 {
243  float dotprod = 0;
244 
245  features& fs_1 = (features&)fec1->fs;
246  features& fs_2 = (features&)fec2->fs;
247  if (fs_2.indicies.size() == 0)
248  return 0.f;
249 
250  for (size_t idx1 = 0, idx2 = 0; idx1 < fs_1.size() && idx2 < fs_2.size(); idx1++)
251  {
252  uint64_t ec1pos = fs_1.indicies[idx1];
253  uint64_t ec2pos = fs_2.indicies[idx2];
254  if (ec1pos < ec2pos)
255  continue;
256 
257  while (ec1pos > ec2pos && ++idx2 < fs_2.size()) ec2pos = fs_2.indicies[idx2];
258 
259  if (ec1pos == ec2pos)
260  {
261  dotprod += fs_1.values[idx1] * fs_2.values[idx2];
262  ++idx2;
263  }
264  }
265  return dotprod;
266 }
267 
269 {
270  flat_example* fec1 = flatten_sort_example(*b.all, ec1);
271  flat_example* fec2 = flatten_sort_example(*b.all, ec2);
272  float norm_sqrt = pow(fec1->total_sum_feat_sq * fec2->total_sum_feat_sq, 0.5f);
273  float linear_prod = linear_kernel(fec1, fec2);
274  // fec1->fs.delete_v();
275  // fec2->fs.delete_v();
276  free_flatten_example(fec1);
277  free_flatten_example(fec2);
278  return linear_prod / norm_sqrt;
279 }
280 
282 {
283  // srand48(4000);
284  // simple initilization: initilize the root only
285  b.iter = 0;
286  b.num_mistakes = 0;
287  b.routers_used = 0;
288  b.test_mode = false;
289  b.max_depth = 0;
290  b.max_ex_in_leaf = 0;
291  b.construct_time = 0;
292  b.test_time = 0;
293  b.top_K = 1;
294  b.hamming_loss = 0.f;
295  b.F1_score = 0.f;
296 
297  b.nodes.push_back(node());
298  b.nodes[0].internal = -1; // mark the root as leaf
299  b.nodes[0].base_router = (b.routers_used++);
300 
301  b.kprod_ec = &calloc_or_throw<example>(); // allocate space for kronecker product example
302 
303  b.total_num_queries = 0;
304  b.max_routers = b.max_nodes;
305  std::cout << "tree initiazliation is done...." << std::endl
306  << "max nodes " << b.max_nodes << std::endl
307  << "tree size: " << b.nodes.size() << std::endl
308  << "max number of unique labels: " << b.max_num_labels << std::endl
309  << "learn at leaf: " << b.learn_at_leaf << std::endl
310  << "num of dream operations per example: " << b.dream_repeats << std::endl
311  << "current_pass: " << b.current_pass << std::endl
312  << "oas: " << b.oas << std::endl;
313 }
314 
315 // rout based on the prediction
316 inline uint64_t insert_descent(node& n, const float prediction)
317 {
318  // prediction <0 go left, otherwise go right
319  if (prediction < 0)
320  {
321  n.nl++; // increment the number of examples routed to the left.
322  return n.left;
323  }
324  else
325  { // otherwise go right.
326  n.nr++; // increment the number of examples routed to the right.
327  return n.right;
328  }
329 }
330 
331 // return the id of the example and the leaf id (stored in cn)
332 inline int random_sample_example_pop(memory_tree& b, uint64_t& cn)
333 {
334  cn = 0; // always start from the root:
335  while (b.nodes[cn].internal == 1)
336  {
337  float pred = 0.; // deal with some edge cases:
338  if (b.nodes[cn].nl < 1) // no examples routed to left ever:
339  pred = 1.f; // go right.
340  else if (b.nodes[cn].nr < 1) // no examples routed to right ever:
341  pred = -1.f; // go left.
342  else if ((b.nodes[cn].nl >= 1) && (b.nodes[cn].nr >= 1))
343  pred = b._random_state->get_and_update_random() < (b.nodes[cn].nl * 1. / (b.nodes[cn].nr + b.nodes[cn].nl)) ? -1.f
344  : 1.f;
345  else
346  {
347  std::cout << cn << " " << b.nodes[cn].nl << " " << b.nodes[cn].nr << std::endl;
348  std::cout << "Error: nl = 0, and nr = 0, exit...";
349  exit(0);
350  }
351 
352  if (pred < 0)
353  {
354  b.nodes[cn].nl--;
355  cn = b.nodes[cn].left;
356  }
357  else
358  {
359  b.nodes[cn].nr--;
360  cn = b.nodes[cn].right;
361  }
362  }
363 
364  if (b.nodes[cn].examples_index.size() >= 1)
365  {
366  int loc_at_leaf = int(b._random_state->get_and_update_random() * b.nodes[cn].examples_index.size());
367  uint32_t ec_id = b.nodes[cn].examples_index[loc_at_leaf];
368  remove_at_index(b.nodes[cn].examples_index, loc_at_leaf);
369  return ec_id;
370  }
371  else
372  return -1;
373 }
374 
375 // train the node with id cn, using the statistics stored in the node to
376 // formulate a binary classificaiton example.
377 float train_node(memory_tree& b, single_learner& base, example& ec, const uint64_t cn)
378 {
379  // predict, learn and predict
380  // note: here we first train the router and then predict.
382  uint32_t save_multi_pred = 0;
384  MULTILABEL::labels preds;
385  if (b.oas == false)
386  {
387  mc = ec.l.multi;
388  save_multi_pred = ec.pred.multiclass;
389  }
390  else
391  {
392  multilabels = ec.l.multilabels;
393  preds = ec.pred.multilabels;
394  }
395 
396  ec.l.simple = {1.f, 1.f, 0.};
397  base.predict(ec, b.nodes[cn].base_router);
398  float prediction = ec.pred.scalar;
399  // float imp_weight = 1.f; //no importance weight.
400 
401  float weighted_value =
402  (float)((1. - b.alpha) * log(b.nodes[cn].nl / (b.nodes[cn].nr + 1e-1)) / log(2.) + b.alpha * prediction);
403  float route_label = weighted_value < 0.f ? -1.f : 1.f;
404 
405  // ec.l.simple = {route_label, imp_weight, 0.f};
406  float ec_input_weight = ec.weight;
407  ec.weight = 1.f;
408  ec.l.simple = {route_label, 1., 0.f};
409  base.learn(ec, b.nodes[cn].base_router); // update the router according to the new example.
410 
411  base.predict(ec, b.nodes[cn].base_router);
412  float save_binary_scalar = ec.pred.scalar;
413 
414  if (b.oas == false)
415  {
416  ec.l.multi = mc;
417  ec.pred.multiclass = save_multi_pred;
418  }
419  else
420  {
421  ec.pred.multilabels = preds;
423  }
424  ec.weight = ec_input_weight;
425 
426  return save_binary_scalar;
427 }
428 
429 // turn a leaf into an internal node, and create two children
430 // when the number of examples is too big
431 void split_leaf(memory_tree& b, single_learner& base, const uint64_t cn)
432 {
433  // create two children
434  b.nodes[cn].internal = 1; // swith to internal node.
435  uint32_t left_child = (uint32_t)b.nodes.size();
436  b.nodes.push_back(node());
437  b.nodes[left_child].internal = -1; // left leaf
438  b.nodes[left_child].base_router = (b.routers_used++);
439  uint32_t right_child = (uint32_t)b.nodes.size();
440  b.nodes.push_back(node());
441  b.nodes[right_child].internal = -1; // right leaf
442  b.nodes[right_child].base_router = (b.routers_used++);
443 
444  if (b.nodes[cn].depth + 1 > b.max_depth)
445  {
446  b.max_depth = b.nodes[cn].depth + 1;
447  std::cout << "depth " << b.max_depth << std::endl;
448  }
449 
450  b.nodes[cn].left = left_child;
451  b.nodes[cn].right = right_child;
452  b.nodes[left_child].parent = cn;
453  b.nodes[right_child].parent = cn;
454  b.nodes[left_child].depth = b.nodes[cn].depth + 1;
455  b.nodes[right_child].depth = b.nodes[cn].depth + 1;
456 
457  if (b.nodes[left_child].depth > b.max_depth)
458  b.max_depth = b.nodes[left_child].depth;
459 
460  // rout the examples stored in the node to the left and right
461  for (size_t ec_id = 0; ec_id < b.nodes[cn].examples_index.size(); ec_id++) // scan all examples stored in the cn
462  {
463  uint32_t ec_pos = b.nodes[cn].examples_index[ec_id];
465  uint32_t save_multi_pred = 0;
467  MULTILABEL::labels preds;
468  if (b.oas == false)
469  {
470  mc = b.examples[ec_pos]->l.multi;
471  save_multi_pred = b.examples[ec_pos]->pred.multiclass;
472  }
473  else
474  {
475  multilabels = b.examples[ec_pos]->l.multilabels;
476  preds = b.examples[ec_pos]->pred.multilabels;
477  }
478 
479  b.examples[ec_pos]->l.simple = {1.f, 1.f, 0.f};
480  base.predict(*b.examples[ec_pos], b.nodes[cn].base_router); // re-predict
481  float scalar = b.examples[ec_pos]->pred.scalar; // this is spliting the leaf.
482  if (scalar < 0)
483  {
484  b.nodes[left_child].examples_index.push_back(ec_pos);
485  float leaf_pred = train_node(b, base, *b.examples[ec_pos], left_child);
486  insert_descent(b.nodes[left_child], leaf_pred); // fake descent, only for update nl and nr
487  }
488  else
489  {
490  b.nodes[right_child].examples_index.push_back(ec_pos);
491  float leaf_pred = train_node(b, base, *b.examples[ec_pos], right_child);
492  insert_descent(b.nodes[right_child], leaf_pred); // fake descent. for update nr and nl
493  }
494 
495  if (b.oas == false)
496  {
497  b.examples[ec_pos]->l.multi = mc;
498  b.examples[ec_pos]->pred.multiclass = save_multi_pred;
499  }
500  else
501  {
502  b.examples[ec_pos]->pred.multilabels = preds;
503  b.examples[ec_pos]->l.multilabels = multilabels;
504  }
505  }
506  b.nodes[cn].examples_index.delete_v(); // empty the cn's example list
507  b.nodes[cn].nl = std::max(double(b.nodes[left_child].examples_index.size()), 0.001); // avoid to set nl to zero
508  b.nodes[cn].nr = std::max(double(b.nodes[right_child].examples_index.size()), 0.001); // avoid to set nr to zero
509 
510  if (std::max(b.nodes[cn].nl, b.nodes[cn].nr) > b.max_ex_in_leaf)
511  {
512  b.max_ex_in_leaf = (size_t)std::max(b.nodes[cn].nl, b.nodes[cn].nr);
513  // std::cout<<b.max_ex_in_leaf<< std::endl;
514  }
515 }
516 
517 int compare_label(const void* a, const void* b) { return *(uint32_t*)a - *(uint32_t*)b; }
518 
519 inline uint32_t over_lap(v_array<uint32_t>& array_1, v_array<uint32_t>& array_2)
520 {
521  uint32_t num_overlap = 0;
522 
523  qsort(array_1.begin(), array_1.size(), sizeof(uint32_t), compare_label);
524  qsort(array_2.begin(), array_2.size(), sizeof(uint32_t), compare_label);
525 
526  uint32_t idx1 = 0;
527  uint32_t idx2 = 0;
528  while (idx1 < array_1.size() && idx2 < array_2.size())
529  {
530  uint32_t c1 = array_1[idx1];
531  uint32_t c2 = array_2[idx2];
532  if (c1 < c2)
533  idx1++;
534  else if (c1 > c2)
535  idx2++;
536  else
537  {
538  num_overlap++;
539  idx1++;
540  idx2++;
541  }
542  }
543  return num_overlap;
544 }
545 
546 // template<typename T>
547 inline uint32_t hamming_loss(v_array<uint32_t>& array_1, v_array<uint32_t>& array_2)
548 {
549  uint32_t overlap = over_lap(array_1, array_2);
550  return (uint32_t)(array_1.size() + array_2.size() - 2 * overlap);
551 }
552 
553 void collect_labels_from_leaf(memory_tree& b, const uint64_t cn, v_array<uint32_t>& leaf_labs)
554 {
555  if (b.nodes[cn].internal != -1)
556  std::cout << "something is wrong, it should be a leaf node" << std::endl;
557 
558  leaf_labs.clear();
559  for (size_t i = 0; i < b.nodes[cn].examples_index.size(); i++)
560  { // scan through each memory in the leaf
561  uint32_t loc = b.nodes[cn].examples_index[i];
562  for (uint32_t lab : b.examples[loc]->l.multilabels.label_v)
563  { // scan through each label:
564  if (v_array_contains(leaf_labs, lab) == false)
565  leaf_labs.push_back(lab);
566  }
567  }
568 }
569 
570 inline void train_one_against_some_at_leaf(memory_tree& b, single_learner& base, const uint64_t cn, example& ec)
571 {
572  v_array<uint32_t> leaf_labs = v_init<uint32_t>();
573  collect_labels_from_leaf(b, cn, leaf_labs); // unique labels from the leaf.
576  ec.l.simple = {FLT_MAX, 1.f, 0.f};
577  for (size_t i = 0; i < leaf_labs.size(); i++)
578  {
579  ec.l.simple.label = -1.f;
580  if (v_array_contains(multilabels.label_v, leaf_labs[i]))
581  ec.l.simple.label = 1.f;
582  base.learn(ec, b.max_routers + 1 + leaf_labs[i]);
583  }
584  ec.pred.multilabels = preds;
586 }
587 
589  memory_tree& b, single_learner& base, const uint64_t cn, example& ec, v_array<uint32_t>& selected_labs)
590 {
591  selected_labs.delete_v();
592  v_array<uint32_t> leaf_labs = v_init<uint32_t>();
593  collect_labels_from_leaf(b, cn, leaf_labs); // unique labels stored in the leaf.
596  ec.l.simple = {FLT_MAX, 1.f, 0.f};
597  for (size_t i = 0; i < leaf_labs.size(); i++)
598  {
599  base.predict(ec, b.max_routers + 1 + leaf_labs[i]);
600  float score = ec.pred.scalar;
601  if (score > 0)
602  selected_labs.push_back(leaf_labs[i]);
603  }
604  ec.pred.multilabels = preds;
606 
607  return hamming_loss(ec.l.multilabels.label_v, selected_labs);
608 }
609 
610 // pick up the "closest" example in the leaf using the score function.
611 int64_t pick_nearest(memory_tree& b, single_learner& base, const uint64_t cn, example& ec)
612 {
613  if (b.nodes[cn].examples_index.size() > 0)
614  {
615  float max_score = -FLT_MAX;
616  int64_t max_pos = -1;
617  for (size_t i = 0; i < b.nodes[cn].examples_index.size(); i++)
618  {
619  float score = 0.f;
620  uint32_t loc = b.nodes[cn].examples_index[i];
621 
622  // do not use reward to update memory tree during the very first pass
623  //(which is for unsupervised training for memory tree)
624  if (b.learn_at_leaf == true && b.current_pass >= 1)
625  {
626  float tmp_s = normalized_linear_prod(b, &ec, b.examples[loc]);
627  diag_kronecker_product_test(ec, *b.examples[loc], *b.kprod_ec, b.oas);
628  b.kprod_ec->l.simple = {FLT_MAX, 0., tmp_s};
629  base.predict(*b.kprod_ec, b.max_routers);
630  score = b.kprod_ec->partial_prediction;
631  }
632  else
633  score = normalized_linear_prod(b, &ec, b.examples[loc]);
634 
635  if (score > max_score)
636  {
637  max_score = score;
638  max_pos = (int64_t)loc;
639  }
640  }
641  return max_pos;
642  }
643  else
644  return -1;
645 }
646 
647 // for any two examples, use number of overlap labels to indicate the similarity between these two examples.
649 {
650  return (float)over_lap(ec1.l.multilabels.label_v, ec2.l.multilabels.label_v);
651 }
652 
653 // we use F1 score as the reward signal
655 {
656  float num_overlaps = get_overlap_from_two_examples(ec1, ec2);
657  float v1 = (float)(num_overlaps / (1e-7 + ec1.l.multilabels.label_v.size() * 1.));
658  float v2 = (float)(num_overlaps / (1e-7 + ec2.l.multilabels.label_v.size() * 1.));
659  if (num_overlaps == 0.f)
660  return 0.f;
661  else
662  // return v2; //only precision
663  return 2.f * (v1 * v2 / (v1 + v2));
664 }
665 
667 {
669  uint32_t save_multi_pred = 0;
671  MULTILABEL::labels preds;
672  if (b.oas == false)
673  {
674  mc = ec.l.multi;
675  save_multi_pred = ec.pred.multiclass;
676  }
677  else
678  {
679  multilabels = ec.l.multilabels;
680  preds = ec.pred.multilabels;
681  }
682 
683  uint64_t cn = 0;
684  ec.l.simple = {-1.f, 1.f, 0.};
685  while (b.nodes[cn].internal == 1)
686  { // if it's internal{
687  base.predict(ec, b.nodes[cn].base_router);
688  uint64_t newcn = ec.pred.scalar < 0 ? b.nodes[cn].left : b.nodes[cn].right; // do not need to increment nl and nr.
689  cn = newcn;
690  }
691 
692  if (b.oas == false)
693  {
694  ec.l.multi = mc;
695  ec.pred.multiclass = save_multi_pred;
696  }
697  else
698  {
699  ec.pred.multilabels = preds;
701  }
702 
703  int64_t closest_ec = 0;
704  if (b.oas == false)
705  {
706  closest_ec = pick_nearest(b, base, cn, ec);
707  if (closest_ec != -1)
708  ec.pred.multiclass = b.examples[closest_ec]->l.multi.label;
709  else
710  ec.pred.multiclass = 0;
711 
712  if (ec.l.multi.label != ec.pred.multiclass)
713  {
714  ec.loss = ec.weight;
715  b.num_mistakes++;
716  }
717  }
718  else
719  {
720  float reward = 0.f;
721  closest_ec = pick_nearest(b, base, cn, ec);
722  if (closest_ec != -1)
723  {
724  reward = F1_score_for_two_examples(ec, *b.examples[closest_ec]);
725  b.F1_score += reward;
726  }
727  v_array<uint32_t> selected_labs = v_init<uint32_t>();
728  ec.loss = (float)compute_hamming_loss_via_oas(b, base, cn, ec, selected_labs);
729  b.hamming_loss += ec.loss;
730  }
731 }
732 
733 float return_reward_from_node(memory_tree& b, single_learner& base, uint64_t cn, example& ec, float weight = 1.f)
734 {
735  // example& ec = *b.examples[ec_array_index];
737  uint32_t save_multi_pred = 0;
739  MULTILABEL::labels preds;
740  if (b.oas == false)
741  {
742  mc = ec.l.multi;
743  save_multi_pred = ec.pred.multiclass;
744  }
745  else
746  {
747  multilabels = ec.l.multilabels;
748  preds = ec.pred.multilabels;
749  }
750  ec.l.simple = {FLT_MAX, 1., 0.0};
751  while (b.nodes[cn].internal != -1)
752  {
753  base.predict(ec, b.nodes[cn].base_router);
754  float prediction = ec.pred.scalar;
755  cn = prediction < 0 ? b.nodes[cn].left : b.nodes[cn].right;
756  }
757 
758  if (b.oas == false)
759  {
760  ec.l.multi = mc;
761  ec.pred.multiclass = save_multi_pred;
762  }
763  else
764  {
765  ec.pred.multilabels = preds;
767  }
768 
769  // get to leaf now:
770  int64_t closest_ec = 0;
771  float reward = 0.f;
772  closest_ec = pick_nearest(b, base, cn, ec); // no randomness for picking example.
773  if (b.oas == false)
774  {
775  if ((closest_ec != -1) && (b.examples[closest_ec]->l.multi.label == ec.l.multi.label))
776  reward = 1.f;
777  }
778  else
779  {
780  if (closest_ec != -1)
781  reward = F1_score_for_two_examples(ec, *b.examples[closest_ec]);
782  }
783  b.total_num_queries++;
784 
785  if (b.learn_at_leaf == true && closest_ec != -1)
786  {
787  float score = normalized_linear_prod(b, &ec, b.examples[closest_ec]);
788  diag_kronecker_product_test(ec, *b.examples[closest_ec], *b.kprod_ec, b.oas);
789  b.kprod_ec->l.simple = {reward, 1.f, -score};
790  b.kprod_ec->weight = weight;
791  base.learn(*b.kprod_ec, b.max_routers);
792  }
793 
794  if (b.oas == true)
795  train_one_against_some_at_leaf(b, base, cn, ec);
796 
797  return reward;
798 }
799 
801  memory_tree& b, single_learner& base, const uint64_t& leaf_id, example& ec, const float& weight)
802 {
803  b.total_num_queries++;
804  int32_t ec_id = -1;
805  float reward = 0.f;
806  if (b.nodes[leaf_id].examples_index.size() > 0)
807  {
808  uint32_t pos = uint32_t(b._random_state->get_and_update_random() * b.nodes[leaf_id].examples_index.size());
809  ec_id = b.nodes[leaf_id].examples_index[pos];
810  }
811  if (ec_id != -1)
812  {
813  if (b.examples[ec_id]->l.multi.label == ec.l.multi.label)
814  reward = 1.f;
815  float score = normalized_linear_prod(b, &ec, b.examples[ec_id]);
816  diag_kronecker_product_test(ec, *b.examples[ec_id], *b.kprod_ec, b.oas);
817  b.kprod_ec->l.simple = {reward, 1.f, -score};
818  b.kprod_ec->weight = weight; //* b.nodes[leaf_id].examples_index.size();
819  base.learn(*b.kprod_ec, b.max_routers);
820  }
821  return;
822 }
823 
824 void route_to_leaf(memory_tree& b, single_learner& base, const uint32_t& ec_array_index, uint64_t cn,
825  v_array<uint64_t>& path, bool insertion)
826 {
827  example& ec = *b.examples[ec_array_index];
828 
830  uint32_t save_multi_pred = 0;
832  MULTILABEL::labels preds;
833  if (b.oas == false)
834  {
835  mc = ec.l.multi;
836  save_multi_pred = ec.pred.multiclass;
837  }
838  else
839  {
840  multilabels = ec.l.multilabels;
841  preds = ec.pred.multilabels;
842  }
843 
844  path.clear();
845  ec.l.simple = {FLT_MAX, 1.0, 0.0};
846  while (b.nodes[cn].internal != -1)
847  {
848  path.push_back(cn); // path stores node id from the root to the leaf
849  base.predict(ec, b.nodes[cn].base_router);
850  float prediction = ec.pred.scalar;
851  if (insertion == false)
852  cn = prediction < 0 ? b.nodes[cn].left : b.nodes[cn].right;
853  else
854  cn = insert_descent(b.nodes[cn], prediction);
855  }
856  path.push_back(cn); // push back the leaf
857 
858  if (b.oas == false)
859  {
860  ec.l.multi = mc;
861  ec.pred.multiclass = save_multi_pred;
862  }
863  else
864  {
865  ec.pred.multilabels = preds;
867  }
868 
869  // std::cout<<"at route to leaf: "<<path.size()<< std::endl;
870  if (insertion == true)
871  {
872  b.nodes[cn].examples_index.push_back(ec_array_index);
873  if ((b.nodes[cn].examples_index.size() >= b.max_leaf_examples) && (b.nodes.size() + 2 < b.max_nodes))
874  split_leaf(b, base, cn);
875  }
876 }
877 
878 // we roll in, then stop at a random step, do exploration. //no real insertion happens in the function.
879 void single_query_and_learn(memory_tree& b, single_learner& base, const uint32_t& ec_array_index, example& ec)
880 {
881  v_array<uint64_t> path_to_leaf = v_init<uint64_t>();
882  route_to_leaf(b, base, ec_array_index, 0, path_to_leaf, false); // no insertion happens here.
883 
884  if (path_to_leaf.size() > 1)
885  {
886  // uint32_t random_pos = merand48(b._random_state->get_current_state())*(path_to_leaf.size()-1);
887  uint32_t random_pos = (uint32_t)(b._random_state->get_and_update_random() * (path_to_leaf.size())); // include leaf
888  uint64_t cn = path_to_leaf[random_pos];
889 
890  if (b.nodes[cn].internal != -1)
891  { // if it's an internal node:'
892  float objective = 0.f;
893  float prob_right = 0.5;
894  float coin = b._random_state->get_and_update_random() < prob_right ? 1.f : -1.f;
895  float weight = path_to_leaf.size() * 1.f / (path_to_leaf.size() - 1.f);
896  if (coin == -1.f)
897  { // go left
898  float reward_left_subtree = return_reward_from_node(b, base, b.nodes[cn].left, ec, weight);
899  objective = (float)((1. - b.alpha) * log(b.nodes[cn].nl / b.nodes[cn].nr) +
900  b.alpha * (-reward_left_subtree / (1. - prob_right)) / 2.);
901  }
902  else
903  { // go right:
904  float reward_right_subtree = return_reward_from_node(b, base, b.nodes[cn].right, ec, weight);
905  objective = (float)((1. - b.alpha) * log(b.nodes[cn].nl / b.nodes[cn].nr) +
906  b.alpha * (reward_right_subtree / prob_right) / 2.);
907  }
908 
909  float ec_input_weight = ec.weight;
910 
913  MULTILABEL::labels preds;
914  if (b.oas == false)
915  mc = ec.l.multi;
916  else
917  {
918  multilabels = ec.l.multilabels;
919  preds = ec.pred.multilabels;
920  }
921 
922  ec.weight = fabs(objective);
923  if (ec.weight >= 100.f) // crop the weight, otherwise sometimes cause NAN outputs.
924  ec.weight = 100.f;
925  else if (ec.weight < .01f)
926  ec.weight = 0.01f;
927  ec.l.simple = {objective < 0. ? -1.f : 1.f, 1.f, 0.};
928  base.learn(ec, b.nodes[cn].base_router);
929 
930  if (b.oas == false)
931  ec.l.multi = mc;
932  else
933  {
934  ec.pred.multilabels = preds;
936  }
937  ec.weight = ec_input_weight; // restore the original weight
938  }
939  else
940  { // if it's a leaf node:
941  float weight = 1.f; // float(path_to_leaf.size());
942  if (b.learn_at_leaf == true)
944  b, base, cn, ec, weight); // randomly sample one example, query reward, and update leaf learner
945 
946  if (b.oas == true)
947  train_one_against_some_at_leaf(b, base, cn, ec);
948  }
949  }
950  path_to_leaf.delete_v();
951 }
952 
953 // using reward signals
954 void update_rew(memory_tree& b, single_learner& base, const uint32_t& ec_array_index, example& ec)
955 {
956  single_query_and_learn(b, base, ec_array_index, ec);
957 }
958 
959 // node here the ec is already stored in the b.examples, the task here is to rout it to the leaf,
960 // and insert the ec_array_index to the leaf.
961 void insert_example(memory_tree& b, single_learner& base, const uint32_t& ec_array_index, bool fake_insert = false)
962 {
963  uint64_t cn = 0; // start from the root.
964  while (b.nodes[cn].internal == 1) // if it's internal node:
965  {
966  // predict and train the node at cn.
967  float router_pred = train_node(b, base, *b.examples[ec_array_index], cn);
968  uint64_t newcn = insert_descent(b.nodes[cn], router_pred); // updated nr or nl
969  cn = newcn;
970  }
971 
972  if (b.oas == true) // if useing oas as inference procedure, we just train oas here, as it's independent of the memory
973  // unit anyway'
974  train_one_against_some_at_leaf(b, base, cn, *b.examples[ec_array_index]);
975 
976  if ((b.nodes[cn].internal == -1) && (fake_insert == false)) // get to leaf:
977  {
978  b.nodes[cn].examples_index.push_back(ec_array_index);
979  if (b.nodes[cn].examples_index.size() > b.max_ex_in_leaf)
980  {
981  b.max_ex_in_leaf = b.nodes[cn].examples_index.size();
982  }
983  float leaf_pred = train_node(b, base, *b.examples[ec_array_index], cn); // tain the leaf as well.
984  insert_descent(b.nodes[cn], leaf_pred); // this is a faked descent, the purpose is only to update nl and nr of cn
985 
986  // if the number of examples exceeds the max_leaf_examples, and not reach the max_nodes - 2 yet, we split:
987  if ((b.nodes[cn].examples_index.size() >= b.max_leaf_examples) && (b.nodes.size() + 2 <= b.max_nodes))
988  {
989  split_leaf(b, base, cn);
990  }
991  }
992 }
993 
995 {
996  uint64_t cn = 0; // start from root, randomly descent down!
997  int ec_id = random_sample_example_pop(b, cn);
998  if (ec_id >= 0)
999  {
1000  if (b.current_pass < 1)
1001  insert_example(b, base, ec_id); // unsupervised learning
1002  else
1003  {
1004  if (b.dream_at_update == false)
1005  {
1006  v_array<uint64_t> tmp_path = v_init<uint64_t>();
1007  route_to_leaf(b, base, ec_id, 0, tmp_path, true);
1008  tmp_path.delete_v();
1009  }
1010  else
1011  {
1012  insert_example(b, base, ec_id);
1013  }
1014  }
1015  }
1016 }
1017 
1018 // learn: descent the example from the root while generating binary training
1019 // example for each node, including the leaf, and store the example at the leaf.
1021 {
1022  if (b.test_mode == false)
1023  {
1024  b.iter++;
1025  predict(b, base, ec);
1026 
1027  if (b.iter % 5000 == 0)
1028  {
1029  if (b.oas == false)
1030  std::cout << "at iter " << b.iter << ", top(" << b.top_K << ") pred error: " << b.num_mistakes * 1. / b.iter
1031  << ", total num queires so far: " << b.total_num_queries << ", max depth: " << b.max_depth
1032  << ", max exp in leaf: " << b.max_ex_in_leaf << std::endl;
1033  else
1034  std::cout << "at iter " << b.iter << ", avg hamming loss: " << b.hamming_loss * 1. / b.iter << std::endl;
1035  }
1036 
1037  clock_t begin = clock();
1038 
1039  if (b.current_pass < 1)
1040  { // in the first pass, we need to store the memory:
1041  example* new_ec = &calloc_or_throw<example>();
1042  copy_example_data(new_ec, &ec, b.oas);
1043  b.examples.push_back(new_ec);
1044  if (b.online == true)
1045  update_rew(b, base, (uint32_t)(b.examples.size() - 1), *b.examples[b.examples.size() - 1]); // query and learn
1046 
1047  insert_example(b, base, (uint32_t)(b.examples.size() - 1)); // unsupervised learning.
1048  for (uint32_t i = 0; i < b.dream_repeats; i++) experience_replay(b, base);
1049  }
1050  else
1051  { // starting from the current pass, we just learn using reinforcement signal, no insertion needed:
1052  size_t ec_id = (b.iter) % b.examples.size();
1053  update_rew(b, base, (uint32_t)ec_id, *b.examples[ec_id]); // no insertion will happen in this call
1054  for (uint32_t i = 0; i < b.dream_repeats; i++) experience_replay(b, base);
1055  }
1056  b.construct_time += float(clock() - begin) / CLOCKS_PER_SEC;
1057  }
1058  else if (b.test_mode == true)
1059  {
1060  b.iter++;
1061  if (b.iter % 5000 == 0)
1062  {
1063  if (b.oas == false)
1064  std::cout << "at iter " << b.iter << ", pred error: " << b.num_mistakes * 1. / b.iter << std::endl;
1065  else
1066  std::cout << "at iter " << b.iter << ", avg hamming loss: " << b.hamming_loss * 1. / b.iter << std::endl;
1067  }
1068  clock_t begin = clock();
1069  predict(b, base, ec);
1070  b.test_time += float(clock() - begin) / CLOCKS_PER_SEC;
1071  }
1072 }
1073 
1075 {
1076  b.current_pass++;
1077  std::cout << "######### Current Pass: " << b.current_pass
1078  << ", with number of memories strored so far: " << b.examples.size() << std::endl;
1079 }
1080 
1083 
1084 void save_load_example(example* ec, io_buf& model_file, bool& read, bool& text, std::stringstream& msg, bool& oas)
1085 { // deal with tag
1086  // deal with labels:
1087  writeit(ec->num_features, "num_features");
1088  writeit(ec->total_sum_feat_sq, "total_sum_features");
1089  writeit(ec->weight, "example_weight");
1090  writeit(ec->loss, "loss");
1091  writeit(ec->ft_offset, "ft_offset");
1092  if (oas == false)
1093  { // multi-class
1094  writeit(ec->l.multi.label, "multiclass_label");
1095  writeit(ec->l.multi.weight, "multiclass_weight");
1096  }
1097  else
1098  { // multi-label
1099  writeitvar(ec->l.multilabels.label_v.size(), "label_size", label_size);
1100  if (read)
1101  {
1102  ec->l.multilabels.label_v.clear();
1103  for (uint32_t i = 0; i < label_size; i++) ec->l.multilabels.label_v.push_back(0);
1104  }
1105  for (uint32_t i = 0; i < label_size; i++) writeit(ec->l.multilabels.label_v[i], "ec_label");
1106  }
1107 
1108  writeitvar(ec->tag.size(), "tags", tag_number);
1109  if (read)
1110  {
1111  ec->tag.clear();
1112  for (uint32_t i = 0; i < tag_number; i++) ec->tag.push_back('a');
1113  }
1114  for (uint32_t i = 0; i < tag_number; i++) writeit(ec->tag[i], "tag");
1115 
1116  // deal with tag:
1117  writeitvar(ec->indices.size(), "namespaces", namespace_size);
1118  if (read)
1119  {
1120  ec->indices.delete_v();
1121  for (uint32_t i = 0; i < namespace_size; i++)
1122  {
1123  ec->indices.push_back('\0');
1124  }
1125  }
1126  for (uint32_t i = 0; i < namespace_size; i++) writeit(ec->indices[i], "namespace_index");
1127 
1128  // deal with features
1129  for (namespace_index nc : ec->indices)
1130  {
1131  features* fs = &ec->feature_space[nc];
1132  writeitvar(fs->size(), "features_", feat_size);
1133  if (read)
1134  {
1135  fs->clear();
1136  fs->values = v_init<feature_value>();
1137  fs->indicies = v_init<feature_index>();
1138  for (uint32_t f_i = 0; f_i < feat_size; f_i++)
1139  {
1140  fs->push_back(0, 0);
1141  }
1142  }
1143  for (uint32_t f_i = 0; f_i < feat_size; f_i++) writeit(fs->values[f_i], "value");
1144  for (uint32_t f_i = 0; f_i < feat_size; f_i++) writeit(fs->indicies[f_i], "index");
1145  }
1146 }
1147 
1148 void save_load_node(node& cn, io_buf& model_file, bool& read, bool& text, std::stringstream& msg)
1149 {
1150  writeit(cn.parent, "parent");
1151  writeit(cn.internal, "internal");
1152  writeit(cn.depth, "depth");
1153  writeit(cn.base_router, "base_router");
1154  writeit(cn.left, "left");
1155  writeit(cn.right, "right");
1156  writeit(cn.nl, "nl");
1157  writeit(cn.nr, "nr");
1158  writeitvar(cn.examples_index.size(), "leaf_n_examples", leaf_n_examples);
1159  if (read)
1160  {
1161  cn.examples_index.clear();
1162  for (uint32_t k = 0; k < leaf_n_examples; k++) cn.examples_index.push_back(0);
1163  }
1164  for (uint32_t k = 0; k < leaf_n_examples; k++) writeit(cn.examples_index[k], "example_location");
1165 }
1166 
1167 void save_load_memory_tree(memory_tree& b, io_buf& model_file, bool read, bool text)
1168 {
1169  std::stringstream msg;
1170  if (model_file.files.size() > 0)
1171  {
1172  if (read)
1173  b.test_mode = true;
1174 
1175  if (read)
1176  {
1177  uint32_t ss = 0;
1178  writeit(ss, "stride_shift");
1179  b.all->weights.stride_shift(ss);
1180  }
1181  else
1182  {
1183  size_t ss = b.all->weights.stride_shift();
1184  writeit(ss, "stride_shift");
1185  }
1186 
1187  writeit(b.max_nodes, "max_nodes");
1188  writeit(b.learn_at_leaf, "learn_at_leaf");
1189  writeit(b.oas, "oas");
1190  // writeit(b.leaf_example_multiplier, "leaf_example_multiplier")
1191  writeitvar(b.nodes.size(), "nodes", n_nodes);
1192  writeit(b.max_num_labels, "max_number_of_labels");
1193 
1194  if (read)
1195  {
1196  b.nodes.clear();
1197  for (uint32_t i = 0; i < n_nodes; i++) b.nodes.push_back(node());
1198  }
1199 
1200  // node
1201  for (uint32_t i = 0; i < n_nodes; i++)
1202  {
1203  save_load_node(b.nodes[i], model_file, read, text, msg);
1204  }
1205  // deal with examples:
1206  writeitvar(b.examples.size(), "examples", n_examples);
1207  if (read)
1208  {
1209  b.examples.clear();
1210  for (uint32_t i = 0; i < n_examples; i++)
1211  {
1212  example* new_ec = &calloc_or_throw<example>();
1213  b.examples.push_back(new_ec);
1214  }
1215  }
1216  for (uint32_t i = 0; i < n_examples; i++) save_load_example(b.examples[i], model_file, read, text, msg, b.oas);
1217  // std::cout<<"done loading...."<< std::endl;
1218  }
1219 }
1221 } // namespace memory_tree_ns
1222 
1224 {
1225  using namespace memory_tree_ns;
1226  auto tree = scoped_calloc_or_throw<memory_tree>();
1227  option_group_definition new_options("Memory Tree");
1228 
1229  new_options
1230  .add(make_option("memory_tree", tree->max_nodes)
1231  .keep()
1232  .default_value(0)
1233  .help("Make a memory tree with at most <n> nodes"))
1234  .add(make_option("max_number_of_labels", tree->max_num_labels)
1235  .default_value(10)
1236  .help("max number of unique label"))
1237  .add(make_option("leaf_example_multiplier", tree->leaf_example_multiplier)
1238  .default_value(1)
1239  .help("multiplier on examples per leaf (default = log nodes)"))
1240  .add(make_option("alpha", tree->alpha).default_value(0.1f).help("Alpha"))
1241  .add(make_option("dream_repeats", tree->dream_repeats)
1242  .default_value(1)
1243  .help("number of dream operations per example (default = 1)"))
1244  .add(make_option("top_K", tree->top_K).default_value(1).help("top K prediction error (default 1)"))
1245  .add(make_option("learn_at_leaf", tree->learn_at_leaf).help("whether or not learn at leaf (defualt = True)"))
1246  .add(make_option("oas", tree->oas).help("use oas at the leaf"))
1247  .add(make_option("dream_at_update", tree->dream_at_update)
1248  .default_value(0)
1249  .help("turn on dream operations at reward based update as well"))
1250  .add(make_option("online", tree->online).help("turn on dream operations at reward based update as well"));
1251  options.add_and_parse(new_options);
1252  if (!tree->max_nodes)
1253  {
1254  return nullptr;
1255  }
1256 
1257  tree->all = &all;
1258  tree->_random_state = all.get_random_state();
1259  tree->current_pass = 0;
1260  tree->final_pass = all.numpasses;
1261 
1262  tree->max_leaf_examples = (size_t)(tree->leaf_example_multiplier * (log(tree->max_nodes) / log(2)));
1263 
1264  init_tree(*tree);
1265 
1266  if (!all.quiet)
1267  all.trace_message << "memory_tree:"
1268  << " "
1269  << "max_nodes = " << tree->max_nodes << " "
1270  << "max_leaf_examples = " << tree->max_leaf_examples << " "
1271  << "alpha = " << tree->alpha << " "
1272  << "oas = " << tree->oas << " "
1273  << "online =" << tree->online << " " << std::endl;
1274 
1275  size_t num_learners = 0;
1276 
1277  // multi-class classification
1278  if (tree->oas == false)
1279  {
1280  num_learners = tree->max_nodes + 1;
1282  init_multiclass_learner(tree, as_singleline(setup_base(options, all)), learn, predict, all.p, num_learners);
1283  // srand(time(0));
1286 
1287  return make_base(l);
1288  } // multi-label classification
1289  else
1290  {
1291  num_learners = tree->max_nodes + 1 + tree->max_num_labels;
1293  tree, as_singleline(setup_base(options, all)), learn, predict, num_learners, prediction_type::multilabels);
1294 
1295  // all.p->lp = MULTILABEL::multilabel;
1296  // all.label_type = label_type::multi;
1297  // all.delete_prediction = MULTILABEL::multilabel.delete_label;
1298  // srand(time(0));
1301  // l.set_end_pass(end_pass);
1302 
1303  all.p->lp = MULTILABEL::multilabel;
1306 
1307  return make_base(l);
1308  }
1309 }
v_array< char > tag
Definition: example.h:63
v_array< namespace_index > indices
void update_rew(memory_tree &b, single_learner &base, const uint32_t &ec_array_index, example &ec)
Definition: memory_tree.cc:954
void remove_at_index(v_array< T > &array, uint32_t index)
Definition: memory_tree.cc:23
uint32_t multiclass
Definition: example.h:49
parameters weights
Definition: global_data.h:537
base_learner * memory_tree_setup(options_i &options, vw &all)
void predict(E &ec, size_t i=0)
Definition: learner.h:169
void diag_kronecker_prod_fs_test(features &f1, features &f2, features &prod_f, float &total_sum_feat_sq, float norm_sq1, float norm_sq2)
Definition: memory_tree.cc:67
void(* delete_prediction)(void *)
Definition: global_data.h:485
T pop()
Definition: v_array.h:58
void predict(memory_tree &b, single_learner &base, example &ec)
Definition: memory_tree.cc:666
void push_back(feature_value v, feature_index i)
float scalar
Definition: example.h:45
void learn_at_leaf_random(memory_tree &b, single_learner &base, const uint64_t &leaf_id, example &ec, const float &weight)
Definition: memory_tree.cc:800
void(* delete_label)(void *)
Definition: label_parser.h:16
void copy_example_data(bool audit, example *dst, example *src)
Definition: example.cc:72
void copy_array(v_array< T > &dst, const v_array< T > &src)
Definition: v_array.h:185
v_array< feature_index > indicies
label_type::label_type_t label_type
Definition: global_data.h:550
void dealloc_example(void(*delete_label)(void *), example &ec, void(*delete_prediction)(void *))
Definition: example.cc:219
float total_sum_feat_sq
Definition: example.h:96
void split_leaf(memory_tree &b, single_learner &base, const uint64_t cn)
Definition: memory_tree.cc:431
void delete_v()
the core definition of a set of features.
v_array< uint32_t > examples_index
Definition: memory_tree.cc:151
base_learner * make_base(learner< T, E > &base)
Definition: learner.h:462
float partial_prediction
Definition: example.h:68
v_array< act_score > path
Definition: search_meta.cc:53
bool quiet
Definition: global_data.h:487
v_array< feature_value > values
virtual void add_and_parse(const option_group_definition &group)=0
void set_save_load(void(*sl)(T &, io_buf &, bool, bool))
Definition: learner.h:257
float label
Definition: simple_label.h:14
label_data simple
Definition: example.h:28
void free_flatten_example(flat_example *fec)
Definition: example.cc:190
uint64_t insert_descent(node &n, const float prediction)
Definition: memory_tree.cc:316
features fs
Definition: example.h:97
void save_load_example(example *ec, io_buf &model_file, bool &read, bool &text, std::stringstream &msg, bool &oas)
T *& begin()
Definition: v_array.h:42
size_t size() const
Definition: v_array.h:68
#define writeit(what, str)
Definition: io_buf.h:349
uint32_t over_lap(v_array< uint32_t > &array_1, v_array< uint32_t > &array_2)
Definition: memory_tree.cc:519
void train_node(log_multi &b, single_learner &base, example &ec, uint32_t &current, uint32_t &class_index, uint32_t)
Definition: log_multi.cc:251
float return_reward_from_node(memory_tree &b, single_learner &base, uint64_t cn, example &ec, float weight=1.f)
Definition: memory_tree.cc:733
int compare_label(const void *a, const void *b)
Definition: memory_tree.cc:517
parser * p
Definition: global_data.h:377
void insert_example(memory_tree &b, single_learner &base, const uint32_t &ec_array_index, bool fake_insert=false)
Definition: memory_tree.cc:961
std::shared_ptr< rand_state > get_random_state()
Definition: global_data.h:553
std::array< features, NUM_NAMESPACES > feature_space
single_learner * as_singleline(learner< T, E > *l)
Definition: learner.h:476
MULTICLASS::label_t multi
Definition: example.h:29
size_t size() const
float get_overlap_from_two_examples(example &ec1, example &ec2)
Definition: memory_tree.cc:648
void diag_kronecker_product_test(example &ec1, example &ec2, example &ec, bool oas=false)
Definition: memory_tree.cc:99
float normalized_linear_prod(memory_tree &b, example *ec1, example *ec2)
Definition: memory_tree.cc:268
learner< T, E > & init_learner(free_ptr< T > &dat, L *base, void(*learn)(T &, L &, E &), void(*predict)(T &, L &, E &), size_t ws, prediction_type::prediction_type_t pred_type)
Definition: learner.h:369
void push_back(const T &new_ele)
Definition: v_array.h:107
void save_load_memory_tree(memory_tree &b, io_buf &model_file, bool read, bool text)
void end_pass(example &ec, vw &all)
Definition: learner.cc:44
uint32_t compute_hamming_loss_via_oas(memory_tree &b, single_learner &base, const uint64_t cn, example &ec, v_array< uint32_t > &selected_labs)
Definition: memory_tree.cc:588
v_array< int > files
Definition: io_buf.h:64
void collect_labels_from_leaf(memory_tree &b, const uint64_t cn, v_array< uint32_t > &leaf_labs)
Definition: memory_tree.cc:553
void clear()
Definition: v_array.h:88
vw_ostream trace_message
Definition: global_data.h:424
size_t num_features
Definition: example.h:67
unsigned char namespace_index
float linear_kernel(const flat_example *fec1, const flat_example *fec2)
Definition: kernel_svm.cc:387
void single_query_and_learn(memory_tree &b, single_learner &base, const uint32_t &ec_array_index, example &ec)
Definition: memory_tree.cc:879
void clear()
Definition: io_buf.h:54
void experience_replay(memory_tree &b, single_learner &base)
Definition: memory_tree.cc:994
size_t numpasses
Definition: global_data.h:451
float loss
Definition: example.h:70
void free_example(example *ec)
Definition: memory_tree.cc:58
float weight
int add(svm_params &params, svm_example *fec)
Definition: kernel_svm.cc:546
flat_example * flatten_sort_example(vw &all, example *ec)
Definition: example.cc:182
polylabel l
Definition: example.h:57
constexpr uint64_t a
Definition: rand48.cc:11
MULTILABEL::labels multilabels
Definition: example.h:50
v_array< example * > examples
Definition: memory_tree.cc:175
typed_option< T > make_option(std::string name, T &location)
Definition: options.h:80
float total_sum_feat_sq
Definition: example.h:71
MULTILABEL::labels multilabels
Definition: example.h:34
label_parser multilabel
Definition: multilabel.cc:118
v_array< uint32_t > label_v
Definition: multilabel.h:16
void train_one_against_some_at_leaf(memory_tree &b, single_learner &base, const uint64_t cn, example &ec)
Definition: memory_tree.cc:570
void set_end_pass(void(*f)(T &))
Definition: learner.h:286
void save_load_node(node &cn, io_buf &model_file, bool &read, bool &text, std::stringstream &msg)
void init_tree(log_multi &d)
Definition: log_multi.cc:122
std::shared_ptr< rand_state > _random_state
Definition: memory_tree.cc:172
int64_t pick_nearest(memory_tree &b, single_learner &base, const uint64_t cn, example &ec)
Definition: memory_tree.cc:611
learner< T, E > & init_multiclass_learner(free_ptr< T > &dat, L *base, void(*learn)(T &, L &, E &), void(*predict)(T &, L &, E &), parser *p, size_t ws, prediction_type::prediction_type_t pred_type=prediction_type::multiclass)
Definition: learner.h:437
void route_to_leaf(memory_tree &b, single_learner &base, const uint32_t &ec_array_index, uint64_t cn, v_array< uint64_t > &path, bool insertion)
Definition: memory_tree.cc:824
uint32_t stride_shift()
LEARNER::base_learner * setup_base(options_i &options, vw &all)
Definition: parse_args.cc:1222
void learn(memory_tree &b, single_learner &base, example &ec)
polyprediction pred
Definition: example.h:60
void delete_v()
Definition: v_array.h:98
void learn(E &ec, size_t i=0)
Definition: learner.h:160
bool v_array_contains(v_array< T > &A, T x)
Definition: v_array.h:237
float weight
Definition: example.h:62
float f
Definition: cache.cc:40
void copy_example_data(example *dst, example *src, bool oas=false)
Definition: memory_tree.cc:43
int random_sample_example_pop(memory_tree &b, uint64_t &cn)
Definition: memory_tree.cc:332
label_parser lp
Definition: parser.h:102
int cmpfunc(const void *a, const void *b)
Definition: memory_tree.cc:97
uint32_t hamming_loss(v_array< uint32_t > &array_1, v_array< uint32_t > &array_2)
Definition: memory_tree.cc:547
#define writeitvar(what, str, mywhat)
Definition: io_buf.h:356
float F1_score_for_two_examples(example &ec1, example &ec2)
Definition: memory_tree.cc:654