jacobian

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit ddadd852615a13047d6788ce992afac2b2af5c68
parent 6e347b335b4ffd2c958d9dc2f611daf36fc8b97d
Author: David Freifeld <freifeld.david@gmail.com>
Date:   Sun,  6 Sep 2020 21:54:54 -0700

Split softmax into its own function + more RNN setup

Diffstat:
Msrc/bpnn.cpp | 45+++++++++++++++++++++++++--------------------
Msrc/bpnn.hpp | 1+
Msrc/rnn.cpp | 31++++++++++++++++++++++++++++---
3 files changed, 54 insertions(+), 23 deletions(-)

diff --git a/src/bpnn.cpp b/src/bpnn.cpp @@ -159,26 +159,8 @@ void Network::set_activation(int index, std::function<float(float)> custom, std: layers[index].activation_deriv = custom_deriv; } -void Network::feedforward() +void Network::softmax() { - for (int i = 0; i < length-1; i++) { - for (int j = 0; j < layers[i].contents->rows(); j++) { - if (strcmp(layers[i].activation_str, "linear") == 0) break; - for (int k = 0; k < layers[i].contents->cols(); k++) { - (*layers[i].dZ)(j,k) = layers[i].activation_deriv((*layers[i].contents)(j,k)); - (*layers[i].contents)(j,k) = layers[i].activation((*layers[i].contents)(j,k)); - } - } - *layers[i+1].contents = (*layers[i].contents) * (*layers[i].weights); - *layers[i+1].contents += *layers[i+1].bias; - } - for (int j = 0; j < layers[length-1].contents->rows(); j++) { - if (strcmp(layers[length-1].activation_str, "linear") == 0) break; - for (int k = 0; k < layers[length-1].contents->cols(); k++) { - (*layers[length-1].dZ)(j,k) = layers[length-1].activation_deriv((*layers[length-1].contents)(j,k)); - (*layers[length-1].contents)(j,k) = layers[length-1].activation((*layers[length-1].contents)(j,k)); - } - } for (int i = 0; i < layers[length-1].contents->rows(); i++) { Eigen::MatrixXf m = layers[length-1].contents->block(i,0,1,layers[length-1].contents->cols()); Eigen::MatrixXf::Index maxRow, maxCol; @@ -198,8 +180,31 @@ void Network::feedforward() checknan(m(0,j), "output of Softmax operation"); } #endif - layers[length-1].contents->block(i,0,1,layers[length-1].contents->cols()) = m; } + layers[length-1].contents->block(i,0,1,layers[length-1].contents->cols()) = m; +} + +void Network::feedforward() +{ + for (int i = 0; i < length-1; i++) { + for (int j = 0; j < layers[i].contents->rows(); j++) { + if (strcmp(layers[i].activation_str, "linear") == 0) break; + for (int k = 0; k < layers[i].contents->cols(); k++) { + (*layers[i].dZ)(j,k) = layers[i].activation_deriv((*layers[i].contents)(j,k)); + (*layers[i].contents)(j,k) = layers[i].activation((*layers[i].contents)(j,k)); + } + } + *layers[i+1].contents = (*layers[i].contents) * (*layers[i].weights); + *layers[i+1].contents += *layers[i+1].bias; + } + for (int j = 0; j < layers[length-1].contents->rows(); j++) { + if (strcmp(layers[length-1].activation_str, "linear") == 0) break; + for (int k = 0; k < layers[length-1].contents->cols(); k++) { + (*layers[length-1].dZ)(j,k) = layers[length-1].activation_deriv((*layers[length-1].contents)(j,k)); + (*layers[length-1].contents)(j,k) = layers[length-1].activation((*layers[length-1].contents)(j,k)); + } + } + softmax(); } void Network::list_net() diff --git a/src/bpnn.hpp b/src/bpnn.hpp @@ -81,6 +81,7 @@ public: void set_activation(int index, std::function<float(float)> custom, std::function<float(float)> custom_deriv); void feedforward(); + void softmax(); void list_net(); bool early_stop; diff --git a/src/rnn.cpp b/src/rnn.cpp @@ -2,6 +2,7 @@ class RecurrentLayer : public Layer { public: + Eigen::MatrixXf* s; Eigen::MatrixXf* rec_weights; void init_weights(RecurrentLayer next); RecurrentLayer(int rows, int columns, float a=0); @@ -10,12 +11,16 @@ public: RecurrentLayer::RecurrentLayer(int rows, int columns, float a) :Layer(rows, columns, a) { + s = new Eigen::MatrixXf(contents->rows(), contents->cols()); rec_weights = new Eigen::MatrixXf(contents->cols(), contents->cols()); - for (int i = 0; i < (rec_weights->rows()*rec_weights->cols()); i++) { + for (int i = 0; i < (rec_weights->cols()*rec_weights->cols()); i++) { std::random_device rd; - std::mt19937 gen(rd()); + std::mt19937 gen(rd()); (*rec_weights)(static_cast<int>(i / columns), i%columns) = d(gen); } + for (int i = 0; i < rows*columns; i++) { + (*s)(static_cast<int>(i / nodes),i%nodes) = 0; + } } void init_weights(RecurrentLayer next) @@ -48,4 +53,24 @@ RNN::RNN(char* path, int batch_sz, float learn_rate, float bias_rate, Regulariza :Network(path, batch_sz, learn_rate, bias_rate, regularization, l, ratio, early_exit, cutoff) {} - +void RNN::feedforward() +{ + for (int i = 0; i < length-1; i++) { + for (int j = 0; j < layers[i].contents->rows(); j++) { + if (strcmp(layers[i].activation_str, "linear") == 0) break; + for (int k = 0; k < layers[i].contents->cols(); k++) { + (*layers[i].dZ)(j,k) = layers[i].activation_deriv((*layers[i].contents)(j,k)); + (*layers[i].contents)(j,k) = layers[i].activation((*layers[i].contents)(j,k)); + } + } + *layers[i+1].contents = ((*layers[i].s) * (*layers[i].rec_weights)) + ((*layers[i].contents) * (*layers[i].weights)); + *layers[i+1].contents += *layers[i+1].bias; + } + for (int j = 0; j < layers[length-1].contents->rows(); j++) { + if (strcmp(layers[length-1].activation_str, "linear") == 0) break; + for (int k = 0; k < layers[length-1].contents->cols(); k++) { + (*layers[length-1].dZ)(j,k) = layers[length-1].activation_deriv((*layers[length-1].contents)(j,k)); + (*layers[length-1].contents)(j,k) = layers[length-1].activation((*layers[length-1].contents)(j,k)); + } + } +}