UFJF - Machine Learning Toolkit  0.51.8
LMS.hpp
1 //
2 // Created by mateus558 on 03/01/19.
3 //
4 
5 #pragma once
6 
7 #include "PrimalRegressor.hpp"
8 
9 namespace mltk{
10  namespace regressor {
14  template<typename T = double>
15  class LMSPrimal : public PrimalRegressor<T> {
16  public:
17  LMSPrimal() = default;
18  explicit LMSPrimal(const Data<T>& samples, double rate = 0.5, int verbose = 0,
19  Solution *initial_solution = nullptr);
20 
21  bool train() override;
22  };
23 
24  template<typename T>
25  LMSPrimal<T>::LMSPrimal(const Data<T>& samples, double rate, int verbose,
26  Solution *initial_solution) {
27  this->samples = mltk::make_data<T>(samples);
28  this->rate = rate;
29  this->verbose = verbose;
30 
31  if (initial_solution) {
32  this->solution = *initial_solution;
33  } else {
34  this->solution.w.resize(samples.dim(), 0.0);
35  this->solution.bias = 0.0;
36  }
37  }
38 
39  template<typename T>
41  size_t j = 0, k = 0, size = this->samples->size(), dim = this->samples->dim();
42  size_t time = this->start_time + this->max_time;
43  double diff = 0.0, diffAnt = 0.0, cost_func = 0.0;
44  std::vector<double> func(size, 0.0);
45 
46  if (this->verbose) {
47  std::cout << "------------------------------------------------------------------------------------\n";
48  std::cout << " steps updates cost_function diff secs\n";
49  std::cout << "------------------------------------------------------------------------------------\n";
50  }
51 
52  this->timer.reset();
53  this->solution.w.assign(dim, 0.0);
54  mltk::Point<> w(this->samples->dim());
55  for (this->steps = 0; this->steps < this->MAX_IT; this->steps++) {
56  cost_func = 0;
57  for (j = 0; j < size; j++) {
58  auto input = (*this->samples)[j];
59  //Compute function
60  for (func[j] = this->solution.bias, k = 0; k < dim; k++) {
61  func[j] += (*input)[k] * w[k];
62  }
63  cost_func += (input->Y() - func[j]) * (input->Y() - func[j]);
64  //Verify if the point is a error
65  auto error = (input->Y() - func[j]);
66  w += this->rate * error * (*input);
67  this->solution.bias += (input->Y() - func[j]);
68  ++this->ctot;
69  }
70  cost_func *= 0.5;
71  double secs = this->timer.elapsed();
72  if (this->verbose) {
73  diff = fabs(cost_func - diffAnt);
74  std::cout << " " << this->steps << " " << this->ctot << " " << cost_func
75  << " " << diff << " " << secs << "\n";
76  }
77  if (fabs(cost_func - diffAnt) <= this->EPS) break;
78  diffAnt = cost_func;
79  if (time - this->timer.elapsed() <= 0) break;
80  }
81  for(int i = 0; i < dim; i++){
82  this->solution.w[i] = w[i];
83  }
84  if (this->verbose >= 1) {
85  std::cout << "Number of steps through data: " << this->steps << std::endl;
86  std::cout << "Number of updates: " << this->ctot << std::endl;
87 
88  if (this->verbose >= 2) {
89  for (j = 0; j < dim; ++j)
90  std::cout << "W[" << j << "]: " << this->solution.w[j]
91  << "\n";
92  std::cout << "Bias: " << this->solution.bias << "\n\n";
93  }
94  }
95 
96  return true;
97  }
98  }
99 }
size_t size() const
Returns the size of the dataset.
Definition: Data.hpp:208
size_t dim() const
Returns the dimension of the dataset.
Definition: Data.hpp:213
std::shared_ptr< Data< T > > samples
Samples used in the model training.
Definition: Learner.hpp:21
double rate
Learning rate.
Definition: Learner.hpp:23
int verbose
Verbose level of the output.
Definition: Learner.hpp:42
Wrapper for the point data.
Definition: Point.hpp:42
Definition: Solution.hpp:13
mltk::Point< double > w
Weights vector.
Definition: Solution.hpp:17
Wrapper for the implementation of the Least Mean Square primal algorithm.
Definition: LMS.hpp:15
bool train() override
Function that execute the training phase of a Learner.
Definition: LMS.hpp:40
Definition: PrimalRegressor.hpp:11
A helper class to measure execution time for benchmarking purposes.
Definition: ThreadPool.hpp:503
UFJF-MLTK main namespace for core functionalities.
Definition: classifier/Classifier.hpp:11