Skip to content

Commit

Permalink
Decomposed Layer -> Container class containing addition + MM steps.
Browse files Browse the repository at this point in the history
  • Loading branch information
alejandroarmas committed Apr 11, 2022
1 parent 2d313cc commit 966c00f
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 33 deletions.
109 changes: 84 additions & 25 deletions include/network_layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@ namespace NeuralNetwork {
class ComputationalStep: public StepInterface {

public:
std::unique_ptr<Matrix::Representation> forward(std::unique_ptr<Matrix::Representation> input) {
return Impl().forward(std::move(input)); }
std::unique_ptr<Matrix::Representation> forward(std::unique_ptr<Matrix::Representation> input) override {

// TODO: print, or error checking.

return Impl().forward(std::move(input));
}
~ComputationalStep() {}
private:
ComputationalStep& Impl() { return *static_cast<Implementation*>(this); }
Expand All @@ -39,46 +43,101 @@ namespace NeuralNetwork {
};


class Layer: public ComputationalStep<Layer> {
class ComposedStep {

public:
Layer(u_int64_t _l, u_int64_t _w, Matrix::Generation::Base& matrix_init) :
weights(std::make_unique<Matrix::Representation>(_l, _w)),
bias(std::make_unique<Matrix::Representation>(FLAT, _w)) {
virtual void add(std::unique_ptr<StepInterface> layer) = 0;
};


class BinaryOperationStep: public ComputationalStep<BinaryOperationStep> {

public:
BinaryOperationStep(Matrix::Rows _l, Matrix::Columns _w,
Matrix::Generation::Base& matrix_init) :
matrix(std::make_unique<Matrix::Representation>(_l, _w))
{

this->weights = matrix_init(std::move(this->weights));
this->bias = matrix_init(std::move(this->bias));
this->matrix = matrix_init(std::move(this->matrix));
}
std::unique_ptr<Matrix::Representation> forward(std::unique_ptr<Matrix::Representation> input);
std::unique_ptr<Matrix::Representation> giveOperand() { return std::move(this->matrix); }
protected:
std::unique_ptr<Matrix::Representation> matrix;

};


class MatrixMultiplyStep: public BinaryOperationStep {

public:
MatrixMultiplyStep(Matrix::Rows _l, Matrix::Columns _w,
Matrix::Generation::Base& matrix_init) :
BinaryOperationStep(_l, _w, matrix_init) {}
std::unique_ptr<Matrix::Representation> forward(std::unique_ptr<Matrix::Representation> input) override;
};


class AddStep: public BinaryOperationStep {

public:
AddStep(Matrix::Columns _w,
Matrix::Generation::Base& matrix_init) :
BinaryOperationStep(Matrix::Rows(FLAT), _w, matrix_init) {}
std::unique_ptr<Matrix::Representation> forward(std::unique_ptr<Matrix::Representation> input) override;
};


class Layer: public ComputationalStep<Layer>, ComposedStep {

public:
Layer(std::unique_ptr<StepInterface> _w, std::unique_ptr<StepInterface> _b) :
weights(std::move(_w)), bias(std::move(_b)) {}

std::unique_ptr<Matrix::Representation> forward(std::unique_ptr<Matrix::Representation> input) override;
void add(std::unique_ptr<StepInterface> layer) override;

private:
std::unique_ptr<Matrix::Representation> weights;
std::unique_ptr<Matrix::Representation> bias;
std::unique_ptr<StepInterface> weights;
std::unique_ptr<StepInterface> bias;
};


/*
DESCRIPTION:
Responsible for creating a tree of layers to be computed and checking if we
are allowed to compute in this order.
USAGE:
using matrix_t = Matrix::Representation;
std::unique_ptr<matrix_t> ma = std::make_unique<matrix_t>(1, 2000);
Matrix::Generation::Normal<0, 1> normal_distribution_init;
ma = normal_distribution_init(std::move(ma));
NeuralNetwork::Sequential model;
model.add(std::make_unique<NeuralNetwork::Layer>(2000, 1000, normal_distribution_init));
model.add(std::make_unique<NeuralNetwork::ActivationFunctions::ReLU>());
model.add(std::make_unique<NeuralNetwork::Layer>(1000, 10, normal_distribution_init));
model.add(std::make_unique<NeuralNetwork::ActivationFunctions::ReLU>());
auto out = model.forward(std::move(ma));
using matrix_t = Matrix::Representation;
std::unique_ptr<matrix_t> ma = std::make_unique<matrix_t>(Matrix::Rows(1), Matrix::Columns(2000));
Matrix::Generation::Normal<0, 1> normal_distribution_init;
ma = normal_distribution_init(std::move(ma));
NeuralNetwork::Sequential model;
model.add(std::make_unique<NeuralNetwork::Layer>(
std::make_unique<NeuralNetwork::MatrixMultiplyStep>(Matrix::Rows(2000), Matrix::Columns(1000), normal_distribution_init),
std::make_unique<NeuralNetwork::AddStep>(Matrix::Columns(1000), normal_distribution_init)
));
model.add(std::make_unique<NeuralNetwork::ActivationFunctions::ReLU>());
model.add(std::make_unique<NeuralNetwork::Layer>(
std::make_unique<NeuralNetwork::MatrixMultiplyStep>(Matrix::Rows(1000), Matrix::Columns(10), normal_distribution_init),
std::make_unique<NeuralNetwork::AddStep>(Matrix::Columns(10), normal_distribution_init)
));
model.add(std::make_unique<NeuralNetwork::ActivationFunctions::ReLU>());
auto out = model.forward(std::move(ma));
*/
class Sequential: public ComputationalStep<Sequential> {
class Sequential: public ComputationalStep<Sequential>, public ComposedStep {
public:
Sequential() : last_key(0) {}
~Sequential() = default;
std::unique_ptr<Matrix::Representation> forward(std::unique_ptr<Matrix::Representation> input);
void add(std::unique_ptr<StepInterface> layer);
std::unique_ptr<Matrix::Representation> forward(std::unique_ptr<Matrix::Representation> input) override;
void add(std::unique_ptr<StepInterface> layer) override;
private:
std::map<const unsigned int, std::unique_ptr<StepInterface>> _modules;
unsigned int last_key;
Expand Down
56 changes: 48 additions & 8 deletions network_layer.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

#include <memory>
#include <algorithm>

Expand All @@ -9,31 +8,72 @@
#include "config.h"


std::unique_ptr<Matrix::Representation> NeuralNetwork::Layer::forward(std::unique_ptr<Matrix::Representation> input) {
std::unique_ptr<Matrix::Representation> NeuralNetwork::MatrixMultiplyStep::forward(std::unique_ptr<Matrix::Representation> input) {

Matrix::Operations::Multiplication::ParallelDNC mm;
Matrix::Operations::Addition::Std add;

if (input == nullptr) {
throw std::invalid_argument("Matrix has no data (pointing to null).");
}

auto out = mm(input, this->matrix);

#if DEBUG
Matrix::Printer m_printer;
out = m_printer(std::move(out));
#endif


return out;
}



auto out = mm(input, this->weights);
std::unique_ptr<Matrix::Representation> NeuralNetwork::AddStep::forward(std::unique_ptr<Matrix::Representation> input) {

auto z = add(this->bias, out);
Matrix::Operations::Addition::Std add;

auto z = add(this->matrix, input);


#if DEBUG
Matrix::Printer m_printer;
z = m_printer(std::move(z));
#endif

return z;
}


std::unique_ptr<Matrix::Representation> NeuralNetwork::Layer::forward(std::unique_ptr<Matrix::Representation> input) {

if (input == nullptr) {
throw std::invalid_argument("Matrix has no data (pointing to null).");
}


auto out = this->weights->forward(std::move(input));

auto z = this->bias->forward(std::move(out));


return z;
}


void NeuralNetwork::Layer::add(std::unique_ptr<StepInterface> matrix) {

if (matrix == nullptr) {
throw std::invalid_argument("Matrix has no data (pointing to null).");
}

if (this->weights == nullptr) {
this->weights = std::move(matrix);
}
else if (this->bias == nullptr) {
this->bias = std::move(matrix);
}

}


std::unique_ptr<Matrix::Representation> NeuralNetwork::Sequential::forward(std::unique_ptr<Matrix::Representation> input) {

std::unique_ptr<Matrix::Representation> current_value = std::move(input);
Expand Down

0 comments on commit 966c00f

Please sign in to comment.