NNFS
Neural network library from scratch
Loading...
Searching...
No Matches
Dense.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <iostream>
4#include <random>
5#include "Layer.hpp"
6
7namespace NNFS
8{
9
15 class Dense : public Layer
16 {
17 public:
30 Dense(int n_input, int n_output,
31 double l1_weights_regularizer = .0,
32 double l1_biases_regularizer = .0,
33 double l2_weights_regularizer = .0,
34 double l2_biases_regularizer = .0) : Layer(LayerType::DENSE), _n_input(n_input), _n_output(n_output),
35 _l1_weights_regularizer(l1_weights_regularizer),
36 _l1_biases_regularizer(l1_biases_regularizer),
37 _l2_weights_regularizer(l2_weights_regularizer),
38 _l2_biases_regularizer(l2_biases_regularizer)
39 {
40 std::random_device rd;
41 std::mt19937 gen(rd());
42 std::uniform_real_distribution<double> dis(-1, 1);
43
44 _weights = Eigen::MatrixXd::Zero(n_input, n_output).unaryExpr([&](double)
45 { return .1 * dis(gen); });
46 _biases = Eigen::MatrixXd::Zero(1, n_output);
47
48 _weights_optimizer = Eigen::MatrixXd::Zero(n_input, n_output);
49
50 _biases_optimizer = Eigen::MatrixXd::Zero(1, n_output);
51
52 _weights_optimizer_additional = Eigen::MatrixXd::Zero(n_input, n_output);
53
54 _biases_optimizer_additional = Eigen::MatrixXd::Zero(1, n_output);
55 }
56
63 void forward(Eigen::MatrixXd &out, const Eigen::MatrixXd &x)
64 {
65 _forward_input = x;
66 out = x * _weights;
67 for (int row = 0; row < out.rows(); ++row)
68 {
69 out.row(row).array() += _biases.array();
70 }
71 }
72
79 void backward(Eigen::MatrixXd &out, const Eigen::MatrixXd &dx)
80 {
81 _dweights = _forward_input.transpose() * dx;
82 _dbiases = dx.colwise().sum().array();
83
84 // Gradients on regularization
85 // L1 on weights
86 if (_l1_weights_regularizer > 0)
87 {
88 Eigen::MatrixXd dL1 = Eigen::MatrixXd::Ones(_weights.rows(), _weights.cols());
89 dL1 = (_weights.array() < 0).select(-1, dL1);
90 _dweights += _l1_weights_regularizer * dL1;
91 }
92 // L2 on weights
93 if (_l2_weights_regularizer > 0)
94 {
95 _dweights += 2 * _l2_weights_regularizer * _weights;
96 }
97 // L1 on biases
98 if (_l1_biases_regularizer > 0)
99 {
100 Eigen::MatrixXd dL1 = Eigen::MatrixXd::Ones(_biases.rows(), _biases.cols());
101 dL1 = (_biases.array() < 0).select(-1, dL1);
102 _dbiases += _l1_biases_regularizer * dL1;
103 }
104 // L2 on biases
105 if (_l2_biases_regularizer > 0)
106 {
107 _dbiases += 2 * _l2_biases_regularizer * _biases;
108 }
109
110 out = dx * _weights.transpose();
111 }
112
118 const Eigen::MatrixXd &weights() const
119 {
120 return _weights;
121 }
122
128 const Eigen::MatrixXd &biases() const
129 {
130 return _biases;
131 }
132
138 const Eigen::MatrixXd &dweights() const
139 {
140 return _dweights;
141 }
142
148 const Eigen::MatrixXd &dbiases() const
149 {
150 return _dbiases;
151 }
152
162 void weights(Eigen::MatrixXd &weights)
163 {
164 if (_weights.rows() != weights.rows() || _weights.cols() != weights.cols())
165 {
166 LOG_ERROR("Shape of new matrix does not match to initial's matrix shape.");
167 throw std::invalid_argument("Shape of new matrix does not match to initial's matrix shape.");
168 }
169
170 _weights = weights;
171 }
172
182 void biases(Eigen::MatrixXd &biases)
183 {
184 if (_biases.rows() != biases.rows() || _biases.cols() != biases.cols())
185 {
186 LOG_ERROR("Shape of new matrix does not match to initial's matrix shape.");
187 throw std::invalid_argument("Shape of new matrix does not match to initial's matrix shape.");
188 }
189 _biases = biases;
190 }
191
197 void weights_optimizer(Eigen::MatrixXd woptimizer)
198 {
199 _weights_optimizer = woptimizer;
200 }
201
207 void biases_optimizer(Eigen::MatrixXd boptimizer)
208 {
209 _biases_optimizer = boptimizer;
210 }
211
217 const Eigen::MatrixXd &weights_optimizer() const
218 {
219 return _weights_optimizer;
220 }
221
227 const Eigen::MatrixXd &biases_optimizer() const
228 {
229 return _biases_optimizer;
230 }
231
237 void weights_optimizer_additional(Eigen::MatrixXd woptimizer)
238 {
239 _weights_optimizer_additional = woptimizer;
240 }
241
247 void biases_optimizer_additional(Eigen::MatrixXd boptimizer)
248 {
249 _biases_optimizer_additional = boptimizer;
250 }
251
257 const Eigen::MatrixXd &weights_optimizer_additional() const
258 {
259 return _weights_optimizer_additional;
260 }
261
267 const Eigen::MatrixXd &biases_optimizer_additional() const
268 {
269 return _biases_optimizer_additional;
270 }
271
277 const double &l1_weights_regularizer() const
278 {
279 return _l1_weights_regularizer;
280 }
281
287 const double &l2_weights_regularizer() const
288 {
289 return _l2_weights_regularizer;
290 }
291
297 const double &l1_biases_regularizer() const
298 {
299 return _l1_biases_regularizer;
300 }
301
307 const double &l2_biases_regularizer() const
308 {
309 return _l2_biases_regularizer;
310 }
311
317 int parameters() const
318 {
319 return _n_input * _n_output + _n_output;
320 }
321
328 void shape(int &n_input, int &n_output) const
329 {
330 n_input = _n_input;
331 n_output = _n_output;
332 }
333
334 private:
335 int _n_input; // Number of input neurons
336 int _n_output; // Number of output neurons
337
338 Eigen::MatrixXd _weights; // Weights matrix
339 Eigen::MatrixXd _biases; // Biases matrix
340
341 Eigen::MatrixXd _dweights; // Weights gradients
342 Eigen::MatrixXd _dbiases; // Biases gradients
343
344 Eigen::MatrixXd _weights_optimizer; // Weights optimizer matrix
345 Eigen::MatrixXd _biases_optimizer; // Biases optimizer matrix
346
347 Eigen::MatrixXd _weights_optimizer_additional; // Additional weights optimizer matrix
348 Eigen::MatrixXd _biases_optimizer_additional; // Additional biases optimizer matrix
349
350 double _l1_weights_regularizer; // L1 weights regularizer
351 double _l1_biases_regularizer; // L1 biases regularizer
352 double _l2_weights_regularizer; // L2 weights regularizer
353 double _l2_biases_regularizer; // L2 biases regularizer
354
355 Eigen::MatrixXd _forward_input; // Forward input
356 };
357} // namespace NNFS
Dense layer.
Definition Dense.hpp:16
void biases(Eigen::MatrixXd &biases)
Set's the biases of the dense layer.
Definition Dense.hpp:182
const Eigen::MatrixXd & weights_optimizer_additional() const
Get additional weights optimizer matrix.
Definition Dense.hpp:257
const Eigen::MatrixXd & weights() const
Get weights.
Definition Dense.hpp:118
const Eigen::MatrixXd & biases_optimizer() const
Get biases optimizer matrix.
Definition Dense.hpp:227
const Eigen::MatrixXd & dweights() const
Get weights gradients.
Definition Dense.hpp:138
const double & l1_weights_regularizer() const
Get L1 weights regularizer.
Definition Dense.hpp:277
const Eigen::MatrixXd & dbiases() const
Get biases gradients.
Definition Dense.hpp:148
const double & l2_biases_regularizer() const
Get L2 biases regularizer.
Definition Dense.hpp:307
const Eigen::MatrixXd & biases_optimizer_additional() const
Get additional biases optimizer matrix.
Definition Dense.hpp:267
const Eigen::MatrixXd & biases() const
Get biases.
Definition Dense.hpp:128
int parameters() const
Calculates the number of trainable of the dense layer.
Definition Dense.hpp:317
const Eigen::MatrixXd & weights_optimizer() const
Get weights optimizer matrix.
Definition Dense.hpp:217
void shape(int &n_input, int &n_output) const
Gives the shape of the dense layer.
Definition Dense.hpp:328
void biases_optimizer_additional(Eigen::MatrixXd boptimizer)
Set's the additional biases optimizer matrix of the dense layer.
Definition Dense.hpp:247
void forward(Eigen::MatrixXd &out, const Eigen::MatrixXd &x)
Forward pass of the dense layer.
Definition Dense.hpp:63
void weights_optimizer_additional(Eigen::MatrixXd woptimizer)
Set's the additional weights optimizer matrix of the dense layer.
Definition Dense.hpp:237
const double & l2_weights_regularizer() const
Get L2 weights regularizer.
Definition Dense.hpp:287
void biases_optimizer(Eigen::MatrixXd boptimizer)
Set's the biases optimizer matrix of the dense layer.
Definition Dense.hpp:207
void weights_optimizer(Eigen::MatrixXd woptimizer)
Set's the weights optimizer matrix of the dense layer.
Definition Dense.hpp:197
const double & l1_biases_regularizer() const
Get L1 biases regularizer.
Definition Dense.hpp:297
void backward(Eigen::MatrixXd &out, const Eigen::MatrixXd &dx)
Backward pass of the dense layer.
Definition Dense.hpp:79
void weights(Eigen::MatrixXd &weights)
Set's the weights of the dense layer.
Definition Dense.hpp:162
Dense(int n_input, int n_output, double l1_weights_regularizer=.0, double l1_biases_regularizer=.0, double l2_weights_regularizer=.0, double l2_biases_regularizer=.0)
Construct a new Dense object.
Definition Dense.hpp:30
Base class for all layers.
Definition Layer.hpp:23
#define LOG_ERROR
Definition clue.hpp:138
Definition Activation.hpp:6
LayerType
Enum class for layer types.
Definition Layer.hpp:12