NeuralNet 1.0
Loading...
Searching...
No Matches
Dropout.hpp
1#pragma once
2
3#include <algorithm>
4#include <cereal/access.hpp>
5#include <cereal/archives/binary.hpp>
6#include <cereal/archives/portable_binary.hpp>
7#include <cereal/cereal.hpp>
8#include <cereal/types/base_class.hpp>
9#include <cereal/types/polymorphic.hpp>
10#include <iterator>
11#include <random>
12#include <tuple>
13
14#include "Layer.hpp"
15
16namespace NeuralNet {
17class Dropout : public Layer {
18 public:
19 float rate, scaleRate;
20 unsigned int seed;
21 Eigen::MatrixXd mask;
22
32 Dropout(float rate, unsigned int seed = 0) : rate(rate), seed(seed) {
33 assert(rate < 1 && rate > 0);
34 this->type = LayerType::DROPOUT;
35 this->trainingOnly = true; // Training only layer
36 this->scaleRate = 1.0 / (1.0 - rate);
37 };
38
42 std::string getSlug() const override {
43 return slug + removeTrailingZeros(std::to_string(rate));
44 }
45
53 Eigen::MatrixXd feedInputs(Eigen::MatrixXd inputs,
54 bool training = false) override {
55 return this->computeOutputs(inputs, training);
56 };
57
58 private:
59 std::vector<std::tuple<int, int>> coordinates;
60 std::string slug = "do";
61
62 // non-public serialization
63 friend class cereal::access;
64
65 Dropout(){}; // Necessary for serialization
66
67 template <class Archive>
68 void serialize(Archive& ar) {
69 ar(cereal::base_class<Layer>(this), seed, rate);
70 }
71
77 unsigned int getSeed() {
78 if (seed != 0) return seed;
79 std::random_device rd;
80 return rd();
81 };
82
83 protected:
87 void init(int numNeurons) override { this->nNeurons = numNeurons; };
88
96 Eigen::MatrixXd computeOutputs(Eigen::MatrixXd inputs,
97 bool training) override {
98 int rows = inputs.rows();
99 int cols = inputs.cols();
100 int numCoord = rows * cols; // Number of coordinates
101 mask = Eigen::MatrixXd::Constant(rows, cols, 1);
102
103 seed = getSeed();
104 std::mt19937 gen(seed);
105 const int num_zeros = static_cast<int>(numCoord * (1.0 - rate));
106
107 std::vector<std::tuple<int, int>> randCoordinates;
108
109 randCoordinates.reserve(num_zeros);
110
111 if (!coordinates.size() || coordinates.size() != (numCoord)) {
112 coordinates.clear();
113 coordinates.reserve(numCoord);
114
115 for (int i = 0; i < rows; i++) {
116 for (int j = 0; j < cols; j++) {
117 coordinates.emplace_back(std::make_tuple(i, j));
118 }
119 }
120 }
121
122 // Randomly select tuples from coordinates
123 std::sample(coordinates.begin(), coordinates.end(),
124 std::back_inserter(randCoordinates), num_zeros, gen);
125
126 for (std::tuple<int, int>& coord : randCoordinates) {
127 mask(std::get<0>(coord), std::get<1>(coord)) = 0;
128 }
129
130 Eigen::MatrixXd dO = (inputs.array() * mask.array()) * scaleRate;
131
132 // Caching outputs for training
133 if (training) outputs = dO;
134
135 return dO;
136 };
137};
138} // namespace NeuralNet
139
140namespace cereal {
141template <class Archive>
142struct specialize<Archive, NeuralNet::Dropout,
143 cereal::specialization::member_serialize> {};
144} // namespace cereal
145
146CEREAL_REGISTER_TYPE(NeuralNet::Dropout);
147
148CEREAL_REGISTER_POLYMORPHIC_RELATION(NeuralNet::Layer, NeuralNet::Dropout);
Definition Dropout.hpp:17
Eigen::MatrixXd feedInputs(Eigen::MatrixXd inputs, bool training=false) override
This method is used to feed the inputs to the layer.
Definition Dropout.hpp:53
void init(int numNeurons) override
Definition Dropout.hpp:87
Eigen::MatrixXd computeOutputs(Eigen::MatrixXd inputs, bool training) override
Drop some of the inputs randomly at the given rate.
Definition Dropout.hpp:96
std::string getSlug() const override
Dropout layer slug.
Definition Dropout.hpp:42
Dropout(float rate, unsigned int seed=0)
The Dropout layer randomly sets input units to 0 with a frequency of rate at each step during trainin...
Definition Dropout.hpp:32
Definition Layer.hpp:26