openGPMP
Open Source Mathematics Package
encoder.cpp
Go to the documentation of this file.
1 /*************************************************************************
2  *
3  * Project
4  * _____ _____ __ __ _____
5  * / ____| __ \| \/ | __ \
6  * ___ _ __ ___ _ __ | | __| |__) | \ / | |__) |
7  * / _ \| '_ \ / _ \ '_ \| | |_ | ___/| |\/| | ___/
8  *| (_) | |_) | __/ | | | |__| | | | | | | |
9  * \___/| .__/ \___|_| |_|\_____|_| |_| |_|_|
10  * | |
11  * |_|
12  *
13  * Copyright (C) Akiel Aries, <akiel@akiel.org>, et al.
14  *
15  * This software is licensed as described in the file LICENSE, which
16  * you should have received as part of this distribution. The terms
17  * among other details are referenced in the official documentation
18  * seen here : https://akielaries.github.io/openGPMP/ along with
19  * important files seen in this project.
20  *
21  * You may opt to use, copy, modify, merge, publish, distribute
22  * and/or sell copies of the Software, and permit persons to whom
23  * the Software is furnished to do so, under the terms of the
24  * LICENSE file. As this is an Open Source effort, all implementations
25  * must be of the same methodology.
26  *
27  *
28  *
29  * This software is distributed on an AS IS basis, WITHOUT
30  * WARRANTY OF ANY KIND, either express or implied.
31  *
32  ************************************************************************/
33 #include <algorithm>
34 #include <ctime>
35 #include <fstream>
36 #include <iostream>
37 #include <openGPMP/ml/encoder.hpp>
38 #include <random>
39 #include <vector>
40 
41 void gpmp::ml::AutoEncoder::save(const std::string &filename) const {
42  std::ofstream file(filename, std::ios::out | std::ios::binary);
43 
44  if (file.is_open()) {
45  file.write(reinterpret_cast<const char *>(&weights_input_hidden[0][0]),
46  weights_input_hidden.size() *
47  weights_input_hidden[0].size() * sizeof(double));
48  file.write(reinterpret_cast<const char *>(&weights_hidden_output[0][0]),
49  weights_hidden_output.size() *
50  weights_hidden_output[0].size() * sizeof(double));
51 
52  file.close();
53  std::cout << "Model saved successfully." << std::endl;
54  } else {
55  std::cerr << "Unable to open the file for saving." << std::endl;
56  }
57 }
58 
59 void gpmp::ml::AutoEncoder::load(const std::string &filename) {
60  std::ifstream file(filename, std::ios::in | std::ios::binary);
61 
62  if (file.is_open()) {
63  file.read(reinterpret_cast<char *>(&weights_input_hidden[0][0]),
64  weights_input_hidden.size() * weights_input_hidden[0].size() *
65  sizeof(double));
66  file.read(reinterpret_cast<char *>(&weights_hidden_output[0][0]),
67  weights_hidden_output.size() *
68  weights_hidden_output[0].size() * sizeof(double));
69 
70  file.close();
71  std::cout << "Model loaded successfully." << std::endl;
72  } else {
73  std::cerr << "Unable to open the file for loading." << std::endl;
74  }
75 }
76 
77 void gpmp::ml::AutoEncoder::lrate_set(double initial_rate) {
78  learning_rate = initial_rate;
79 }
80 
82  // reduce the learning rate by half every N epochs
83  const int decay_interval = 10;
84  if (epoch % decay_interval == 0) {
85  learning_rate /= 2.0;
86  std::cout << "Learning rate updated to: " << learning_rate
87  << " at epoch " << epoch << std::endl;
88  }
89  // TODO?
90 }
91 
93  int h_size,
94  int out_size,
95  double l_rate)
96  : input_size(in_size), hidden_size(h_size), output_size(out_size),
97  learning_rate(l_rate) {
98 
99  // initialize weights randomly
100  weights_input_hidden.resize(input_size, std::vector<double>(hidden_size));
101  weights_hidden_output.resize(hidden_size, std::vector<double>(output_size));
102 
103  for (int i = 0; i < input_size; ++i) {
104  for (int j = 0; j < hidden_size; ++j) {
105  // random values between 0 and 1
106  weights_input_hidden[i][j] = (rand() % 1000) / 1000.0;
107  }
108  }
109  for (int i = 0; i < hidden_size; ++i) {
110  for (int j = 0; j < output_size; ++j) {
111  weights_hidden_output[i][j] = (rand() % 1000) / 1000.0;
112  }
113  }
114 }
115 
116 std::vector<double>
117 gpmp::ml::AutoEncoder::sigmoid(const std::vector<double> &x) {
118  std::vector<double> result;
119  for (double val : x) {
120  result.push_back(1.0 / (1.0 + exp(-val)));
121  }
122  return result;
123 }
124 
125 std::vector<double>
126 gpmp::ml::AutoEncoder::forward(const std::vector<double> &input) {
127  // forward passes
128  std::vector<double> hidden(hidden_size);
129  std::vector<double> output(output_size);
130 
131  // calculate hidden layer values
132  for (int i = 0; i < hidden_size; ++i) {
133  hidden[i] = 0;
134  for (int j = 0; j < input_size; ++j) {
135  hidden[i] += input[j] * weights_input_hidden[j][i];
136  }
137  hidden[i] = sigmoid({hidden[i]})[0];
138  }
139 
140  // calculate output layer values
141  for (int i = 0; i < output_size; ++i) {
142  output[i] = 0;
143  for (int j = 0; j < hidden_size; ++j) {
144  output[i] += hidden[j] * weights_hidden_output[j][i];
145  }
146  output[i] = sigmoid({output[i]})[0];
147  }
148 
149  return output;
150 }
151 
153  const std::vector<std::vector<double>> &training_data,
154  int epochs) {
155  for (int epoch = 0; epoch < epochs; ++epoch) {
156  for (const auto &input : training_data) {
157  // forward pass
158  std::vector<double> hidden(hidden_size);
159  std::vector<double> output(output_size);
160 
161  // calculate hidden layer values
162  for (int i = 0; i < hidden_size; ++i) {
163  hidden[i] = 0;
164  for (int j = 0; j < input_size; ++j) {
165  hidden[i] += input[j] * weights_input_hidden[j][i];
166  }
167  hidden[i] = sigmoid({hidden[i]})[0];
168  }
169 
170  // calculate output layer values
171  for (int i = 0; i < output_size; ++i) {
172  output[i] = 0;
173  for (int j = 0; j < hidden_size; ++j) {
174  output[i] += hidden[j] * weights_hidden_output[j][i];
175  }
176  output[i] = sigmoid({output[i]})[0];
177  }
178 
179  // backward pass (gradient descent)
180  for (int i = 0; i < output_size; ++i) {
181  for (int j = 0; j < hidden_size; ++j) {
182  weights_hidden_output[j][i] -=
183  learning_rate * (output[i] - input[i]) * hidden[j];
184  }
185  }
186 
187  for (int i = 0; i < hidden_size; ++i) {
188  for (int j = 0; j < input_size; ++j) {
189  double error = 0;
190  for (int k = 0; k < output_size; ++k) {
191  error += (output[k] - input[k]) *
192  weights_hidden_output[i][k];
193  }
194  weights_input_hidden[j][i] -= learning_rate * error *
195  input[j] * (1 - hidden[i]) *
196  hidden[i];
197  }
198  }
199  }
200  }
201 }
202 
204  std::cout << "Input to Hidden Weights:\n";
205  for (int i = 0; i < input_size; ++i) {
206  for (int j = 0; j < hidden_size; ++j) {
207  std::cout << weights_input_hidden[i][j] << " ";
208  }
209  std::cout << "\n";
210  }
211 
212  std::cout << "\nHidden to Output Weights:\n";
213  for (int i = 0; i < hidden_size; ++i) {
214  for (int j = 0; j < output_size; ++j) {
215  std::cout << weights_hidden_output[i][j] << " ";
216  }
217  std::cout << "\n";
218  }
219 }
220 
222  int h_size,
223  int out_size,
224  double l_rate,
225  double s_weight,
226  double s_target)
227  : AutoEncoder(in_size, h_size, out_size, l_rate), sparsity_weight(s_weight),
228  sparsity_target(s_target) {
229 }
230 
232  const std::vector<std::vector<double>> &training_data,
233  int epochs) {
234 
235  const double SPARSITY_TARGET_DECAY = 0.1;
236 
237  for (int epoch = 0; epoch < epochs; ++epoch) {
238  for (const auto &current_input : training_data) {
239  // forward pass
240  std::vector<double> hidden = forward(current_input);
241 
242  // backward pass (gradient descent)
243  for (int i = 0; i < output_size; ++i) {
244  for (int j = 0; j < hidden_size; ++j) {
245  weights_hidden_output[j][i] -=
246  learning_rate * (hidden[i] - current_input[i]) *
247  hidden[j];
248  }
249  }
250 
251  for (int i = 0; i < hidden_size; ++i) {
252  for (int j = 0; j < input_size; ++j) {
253  double error = 0;
254  for (int k = 0; k < output_size; ++k) {
255  error += (hidden[k] - current_input[k]) *
256  weights_hidden_output[i][k];
257  }
258 
259  double sparsity_term =
260  sparsity_weight * (sparsity_target - hidden[i]);
261 
262  weights_input_hidden[j][i] -=
263  learning_rate * (error + sparsity_term) *
264  current_input[j] * (1 - hidden[i]) * hidden[i];
265  }
266  }
267 
268  for (int i = 0; i < hidden_size; ++i) {
269  double average_activation = 0.0;
270  for (const auto &input : training_data) {
271  std::vector<double> current_hidden = forward(input);
272  average_activation += current_hidden[i];
273  }
274  average_activation /= training_data.size();
275  sparsity_target =
276  (1.0 - SPARSITY_TARGET_DECAY) * sparsity_target +
277  SPARSITY_TARGET_DECAY * average_activation;
278  }
279  }
280  }
281 }
282 
284  int h_size,
285  int out_size,
286  double l_rate,
287  double c_level)
288  : AutoEncoder(in_size, h_size, out_size, l_rate),
289  corruption_level(c_level) {
290 }
291 
293  const std::vector<std::vector<double>> &training_data,
294  int epochs) {
295  std::srand(std::time(0));
296 
297  for (int epoch = 0; epoch < epochs; ++epoch) {
298  for (const auto &input : training_data) {
299  // add noise to the input data
300  std::vector<double> noisy_input = input;
301  for (double &val : noisy_input) {
302  if ((std::rand() / (RAND_MAX + 1.0)) < corruption_level) {
303  // set to zero with probability corruption_level
304  val = 0.0;
305  }
306  }
307 
308  // forward pass
309  std::vector<double> hidden = forward(noisy_input);
310 
311  // backward pass (gradient descent)
312  for (int i = 0; i < output_size; ++i) {
313  for (int j = 0; j < hidden_size; ++j) {
314  weights_hidden_output[j][i] -=
315  learning_rate * (hidden[i] - input[i]) * hidden[j];
316  }
317  }
318 
319  for (int i = 0; i < hidden_size; ++i) {
320  for (int j = 0; j < input_size; ++j) {
321  double error = 0;
322  for (int k = 0; k < output_size; ++k) {
323  error += (hidden[k] - input[k]) *
324  weights_hidden_output[i][k];
325  }
326  weights_input_hidden[j][i] -= learning_rate * error *
327  noisy_input[j] *
328  (1 - hidden[i]) * hidden[i];
329  }
330  }
331  }
332  }
333 }
334 
336  int h_size,
337  int out_size,
338  double l_rate,
339  double c_weight)
340  : AutoEncoder(in_size, h_size, out_size, l_rate),
341  contractive_weight(c_weight) {
342 }
343 
345  const std::vector<std::vector<double>> &training_data,
346  int epochs) {
347  for (int epoch = 0; epoch < epochs; ++epoch) {
348  for (const auto &input : training_data) {
349  // forward pass
350  std::vector<double> hidden = forward(input);
351 
352  // backward pass (gradient descent)
353  for (int i = 0; i < output_size; ++i) {
354  for (int j = 0; j < hidden_size; ++j) {
355  weights_hidden_output[j][i] -=
356  learning_rate * (hidden[i] - input[i]) * hidden[j];
357  }
358  }
359 
360  for (int i = 0; i < hidden_size; ++i) {
361  for (int j = 0; j < input_size; ++j) {
362  double error = 0;
363  for (int k = 0; k < output_size; ++k) {
364  error += (hidden[k] - input[k]) *
365  weights_hidden_output[i][k];
366  }
367  double contractive_term =
368  contractive_weight * hidden[i] * (1 - hidden[i]);
369  weights_input_hidden[j][i] -=
370  learning_rate * (error + contractive_term) * input[j] *
371  (1 - hidden[i]) * hidden[i];
372  }
373  }
374  }
375  }
376 }
377 
379  int h_size,
380  int out_size,
381  double l_rate,
382  double m_wt)
383  : AutoEncoder(in_size, h_size, out_size, l_rate), mdl_weight(m_wt) {
384 }
385 
387  const std::vector<std::vector<double>> &training_data,
388  int epochs) {
389  for (int epoch = 0; epoch < epochs; ++epoch) {
390  for (const auto &input : training_data) {
391  // forward pass
392  std::vector<double> hidden = forward(input);
393 
394  // backward pass (gradient descent)
395  for (int i = 0; i < output_size; ++i) {
396  for (int j = 0; j < hidden_size; ++j) {
397  weights_hidden_output[j][i] -=
398  learning_rate * (hidden[i] - input[i]) * hidden[j];
399  }
400  }
401 
402  for (int i = 0; i < hidden_size; ++i) {
403  for (int j = 0; j < input_size; ++j) {
404  double error = 0;
405  for (int k = 0; k < output_size; ++k) {
406  error += (hidden[k] - input[k]) *
407  weights_hidden_output[i][k];
408  }
409  double mdl_term = mdl_weight * log(1.0 + fabs(error));
410  weights_input_hidden[j][i] -=
411  learning_rate * (error + mdl_term) * input[j] *
412  (1 - hidden[i]) * hidden[i];
413  }
414  }
415  }
416  }
417 }
418 
420  int h_size,
421  int out_size,
422  double l_rate,
423  double temp)
424  : AutoEncoder(in_size, h_size, out_size, l_rate), temperature(temp) {
425 }
426 
428  const std::vector<std::vector<double>> &training_data,
429  int epochs) {
430  std::default_random_engine generator;
431  std::uniform_real_distribution<double> uniform_distribution(0.0, 1.0);
432 
433  for (int epoch = 0; epoch < epochs; ++epoch) {
434  for (const auto &input : training_data) {
435  // forward pass with Concrete distribution
436  std::vector<double> hidden;
437  for (int i = 0; i < hidden_size; ++i) {
438  double u = uniform_distribution(generator);
439  // Gumbel noise
440  double g = -log(-log(u));
441  double s = (input[i] + g) / temperature;
442  double p = 1.0 / (1.0 + exp(-s));
443  hidden.push_back(p);
444  }
445 
446  // backward pass (gradient descent)
447  for (int i = 0; i < output_size; ++i) {
448  for (int j = 0; j < hidden_size; ++j) {
449  weights_hidden_output[j][i] -=
450  learning_rate * (hidden[i] - input[i]) * hidden[j];
451  }
452  }
453 
454  for (int i = 0; i < hidden_size; ++i) {
455  for (int j = 0; j < input_size; ++j) {
456  double error = 0;
457  for (int k = 0; k < output_size; ++k) {
458  error += (hidden[k] - input[k]) *
459  weights_hidden_output[i][k];
460  }
461  weights_input_hidden[j][i] -= learning_rate * error *
462  input[j] * (1 - hidden[i]) *
463  hidden[i];
464  }
465  }
466  }
467  }
468 }
469 
471  int h_size,
472  int out_size,
473  double l_rate)
474  : AutoEncoder(in_size, h_size, out_size, l_rate) {
475 }
476 
478  static std::default_random_engine generator;
479  static std::normal_distribution<double> distribution(0.0, 1.0);
480  return distribution(generator);
481 }
482 
484  double log_variance) {
485  double standard_normal_sample = sample_dist();
486  return mean + exp(0.5 * log_variance) * standard_normal_sample;
487 }
488 
489 std::vector<double>
490 gpmp::ml::VariationalAutoEncoder::encoder(const std::vector<double> &input) {
491  std::vector<double> hidden(hidden_size);
492 
493  for (int i = 0; i < hidden_size; ++i) {
494  hidden[i] = 0;
495  for (int j = 0; j < input_size; ++j) {
496  hidden[i] += input[j] * weights_input_hidden[j][i];
497  }
498  hidden[i] = sigmoid({hidden[i]})[0];
499  }
500 
501  return hidden;
502 }
503 
505  const std::vector<double> &hidden_sampled) {
506  std::vector<double> output(output_size);
507 
508  for (int i = 0; i < output_size; ++i) {
509  output[i] = 0;
510  for (int j = 0; j < hidden_size; ++j) {
511  output[i] += hidden_sampled[j] * weights_hidden_output[j][i];
512  }
513  output[i] = sigmoid({output[i]})[0];
514  }
515 
516  return output;
517 }
518 
520  const std::vector<double> &input,
521  const std::vector<double> &output,
522  const std::vector<double> &hidden_sampled) {
523  for (int i = 0; i < output_size; ++i) {
524  for (int j = 0; j < hidden_size; ++j) {
525  weights_hidden_output[j][i] -=
526  learning_rate * (output[i] - input[i]) * hidden_sampled[j];
527  }
528  }
529 
530  for (int i = 0; i < hidden_size; ++i) {
531  for (int j = 0; j < input_size; ++j) {
532  double error = 0;
533  for (int k = 0; k < output_size; ++k) {
534  error += (output[k] - input[k]) * weights_hidden_output[i][k];
535  }
536  double hidden_gradient =
537  hidden_sampled[i] * (1 - hidden_sampled[i]);
538  // derivative of softplus
539  double log_variance_gradient =
540  1.0 / (1.0 + exp(-hidden_log_variance[i]));
541  weights_input_hidden[j][i] -=
542  learning_rate *
543  (error * hidden_gradient +
544  (hidden_sampled[i] - hidden_mean[i]) * hidden_gradient +
545  (hidden_log_variance[i] - log_variance_gradient) *
546  hidden_gradient) *
547  input[j];
548  }
549  }
550 }
551 
553  const std::vector<std::vector<double>> &training_data,
554  int epochs) {
555  std::default_random_engine generator;
556  std::normal_distribution<double> normal_distribution(0.0, 1.0);
557  std::vector<double> hidden_sampled;
558 
559  for (int epoch = 0; epoch < epochs; ++epoch) {
560  for (const auto &input : training_data) {
561  // forward pass (encoder)
562  hidden_mean = encoder(input);
563  hidden_log_variance = encoder(input);
564 
565  for (int i = 0; i < hidden_size; ++i) {
566  hidden_sampled.push_back(
567  reparameterize(hidden_mean[i], hidden_log_variance[i]));
568  }
569 
570  // forward pass (decoder)
571  std::vector<double> output = decoder(hidden_sampled);
572 
573  // backward pass (gradient descent)
574  gradient_descent(input, output, hidden_sampled);
575  }
576  }
577 }
578 
580  int h_size,
581  int out_size,
582  double l_rate)
583  : AutoEncoder(in_size, h_size, out_size, l_rate),
584  weights_recurrent(h_size, std::vector<double>(h_size, 0.0)) {
585 }
586 
588  const std::vector<std::vector<double>> &training_data,
589  int epochs) {
590  for (int epoch = 0; epoch < epochs; ++epoch) {
591  std::vector<double> previous_hidden(hidden_size, 0.0);
592 
593  for (const auto &input : training_data) {
594  // forward pass
595  std::vector<double> hidden = recurr_fwd(input, previous_hidden);
596  std::vector<double> output = forward(hidden);
597 
598  // backward pass (gradient descent)
599  for (int i = 0; i < output_size; ++i) {
600  for (int j = 0; j < hidden_size; ++j) {
601  weights_hidden_output[j][i] -=
602  learning_rate * (output[i] - input[i]) * hidden[j];
603  }
604  }
605 
606  for (int i = 0; i < hidden_size; ++i) {
607  for (int j = 0; j < input_size; ++j) {
608  double error = 0;
609  for (int k = 0; k < output_size; ++k) {
610  error += (output[k] - input[k]) *
611  weights_hidden_output[i][k];
612  }
613  weights_input_hidden[j][i] -= learning_rate * error *
614  input[j] * (1 - hidden[i]) *
615  hidden[i];
616  }
617  }
618 
619  // recurrent weights update
620  for (int i = 0; i < hidden_size; ++i) {
621  for (int j = 0; j < hidden_size; ++j) {
622  weights_recurrent[j][i] -=
623  learning_rate * (hidden[i] - previous_hidden[i]) *
624  hidden[j];
625  }
626  }
627 
628  previous_hidden = hidden;
629  }
630  }
631 }
632 
634  const std::vector<double> &input,
635  const std::vector<double> &previous_hidden) {
636  std::vector<double> recurrent_input(hidden_size, 0.0);
637 
638  // sum the weighted contributions from the current input and the previous
639  // hidden state
640  for (int i = 0; i < hidden_size; ++i) {
641  recurrent_input[i] = 0.0;
642  for (int j = 0; j < input_size; ++j) {
643  recurrent_input[i] += weights_input_hidden[j][i] * input[j];
644  }
645  for (int j = 0; j < hidden_size; ++j) {
646  recurrent_input[i] += weights_recurrent[j][i] * previous_hidden[j];
647  }
648  // activation function
649  // recurrent_input[i] = 1.0 / (1.0 + std::exp(-recurrent_input[i]));
650  recurrent_input[i] = sigmoid({recurrent_input[i]})[0];
651  }
652 
653  return recurrent_input;
654 }
655 
657  int h_size,
658  int out_size,
659  double l_rate)
660  : AutoEncoder(in_size, h_size, out_size, l_rate) {
661 }
662 
664  const std::vector<std::vector<double>> &training_data,
665  int epochs) {
666  for (int epoch = 0; epoch < epochs; ++epoch) {
667  for (const auto &input : training_data) {
668  // forward pass
669  std::vector<double> hidden = forward(input);
670  std::vector<double> output = forward(hidden);
671 
672  // backward pass (gradient descent)
673  for (int i = 0; i < output_size; ++i) {
674  for (int j = 0; j < hidden_size; ++j) {
675  weights_hidden_output[j][i] -=
676  learning_rate * (output[i] - input[i]) * hidden[j];
677  }
678  }
679 
680  for (int i = 0; i < hidden_size; ++i) {
681  for (int j = 0; j < input_size; ++j) {
682  double error = 0;
683  for (int k = 0; k < output_size; ++k) {
684  error += (output[k] - input[k]) *
685  weights_hidden_output[i][k];
686  }
687  weights_input_hidden[j][i] -= learning_rate * error *
688  input[j] * (1 - hidden[i]) *
689  hidden[i];
690  }
691  }
692  }
693  }
694 }
A simple implementation of a vanilla autoencoder.
Definition: encoder.hpp:59
std::vector< std::vector< double > > weights_input_hidden
Weights from the input layer to the hidden layer.
Definition: encoder.hpp:97
std::vector< std::vector< double > > weights_hidden_output
Weights from the hidden layer to the output layer.
Definition: encoder.hpp:105
int hidden_size
Size of the hidden layer.
Definition: encoder.hpp:74
virtual void lrate_update(int epoch)
Update the learning rate based on a schedule.
Definition: encoder.cpp:81
void lrate_set(double initial_rate)
Set the initial learning rate.
Definition: encoder.cpp:77
AutoEncoder(int input_size, int hidden_size, int output_size, double learning_rate)
Constructor for the AutoEncoder class.
Definition: encoder.cpp:92
virtual void train(const std::vector< std::vector< double >> &training_data, int epochs)
Train the autoencoder on a dataset.
Definition: encoder.cpp:152
int output_size
Size of the output layer.
Definition: encoder.hpp:82
std::vector< double > forward(const std::vector< double > &input)
Forward pass through the autoencoder.
Definition: encoder.cpp:126
virtual void load(const std::string &filename)
Load model weights from a file.
Definition: encoder.cpp:59
void display()
Print the weights of the autoencoder.
Definition: encoder.cpp:203
virtual void save(const std::string &filename) const
Save the model weights to a file.
Definition: encoder.cpp:41
std::vector< double > sigmoid(const std::vector< double > &x)
Sigmoid activation function.
Definition: encoder.cpp:117
int input_size
Size of the input layer.
Definition: encoder.hpp:66
virtual void train(const std::vector< std::vector< double >> &training_data, int epochs) override
Trains the Concrete autoencoder on the given training data.
Definition: encoder.cpp:427
ConcreteAutoEncoder(int input_size, int hidden_size, int output_size, double learning_rate, double temperature)
Constructor for the ConcreteAutoEncoder class.
Definition: encoder.cpp:419
ContractiveAutoEncoder(int input_size, int hidden_size, int output_size, double learning_rate, double contractive_weight)
Constructor for the ContractiveAutoEncoder class.
Definition: encoder.cpp:335
virtual void train(const std::vector< std::vector< double >> &training_data, int epochs) override
Trains the contractive autoencoder on the given training data.
Definition: encoder.cpp:344
DenoisingAutoEncoder(int input_size, int hidden_size, int output_size, double learning_rate, double corruption_level)
Constructor for the DenoisingAutoEncoder class.
Definition: encoder.cpp:283
void train(const std::vector< std::vector< double >> &training_data, int epochs) override
Adds noise to the input data and trains the denoising autoencoder.
Definition: encoder.cpp:292
virtual void train(const std::vector< std::vector< double >> &training_data, int epochs) override
Trains the fully connected autoencoder on the given training data.
Definition: encoder.cpp:663
FullAutoEncoder(int input_size, int hidden_size, int output_size, double learning_rate)
Constructor for the FullAutoEncoder class.
Definition: encoder.cpp:656
MDLAutoEncoder(int input_size, int hidden_size, int output_size, double learning_rate, double mdl_weight)
Constructor for the MDLAutoEncoder class.
Definition: encoder.cpp:378
virtual void train(const std::vector< std::vector< double >> &training_data, int epochs) override
Trains the MDL autoencoder on the given training data.
Definition: encoder.cpp:386
std::vector< double > recurr_fwd(const std::vector< double > &input, const std::vector< double > &previous_hidden)
Performs a forward pass through the recurrent layer.
Definition: encoder.cpp:633
RecurrentAutoEncoder(int input_size, int hidden_size, int output_size, double learning_rate)
Constructor for the RecurrentAutoEncoder class.
Definition: encoder.cpp:579
virtual void train(const std::vector< std::vector< double >> &training_data, int epochs) override
Trains the recurrent autoencoder on the given sequential data.
Definition: encoder.cpp:587
void train(const std::vector< std::vector< double >> &training_data, int epochs) override
Trains the sparse autoencoder on the given training data.
Definition: encoder.cpp:231
SparseAutoEncoder(int input_size, int hidden_size, int output_size, double learning_rate, double sparsity_weight, double sparsity_target)
Constructor for the SparseAutoEncoder class.
Definition: encoder.cpp:221
std::vector< double > encoder(const std::vector< double > &input)
Performs the forward pass for the encoder and returns hidden activations.
Definition: encoder.cpp:490
void gradient_descent(const std::vector< double > &input, const std::vector< double > &output, const std::vector< double > &hidden_sampled)
Performs the backward pass (gradient descent) updating weights.
Definition: encoder.cpp:519
double sample_dist()
Samples from a standard normal distribution.
Definition: encoder.cpp:477
double reparameterize(double mean, double log_variance)
Reparameterization trick for variational autoencoders.
Definition: encoder.cpp:483
VariationalAutoEncoder(int input_size, int hidden_size, int output_size, double learning_rate)
Constructor for the VariationalAutoEncoder class.
Definition: encoder.cpp:470
virtual void train(const std::vector< std::vector< double >> &training_data, int epochs) override
Trains the Variational autoencoder on the given training data.
Definition: encoder.cpp:552
std::vector< double > decoder(const std::vector< double > &hidden_sampled)
Performs the forward pass for the decoder and returns output activations.
Definition: encoder.cpp:504
Auto Encoder Neural Network effecient for unlabeled data.
static GLfloat u