jacobian

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

commit a74bbc575ff06ed02020a2bbef68c398d1ee2da3
parent e3b403e0fed7926fc886bfb1fb307ee8539cc875
Author: David Freifeld <freifeld.david@gmail.com>
Date:   Tue, 11 Aug 2020 13:23:16 -0700

Working on checks some more

Diffstat:
Mexample.cpp | 2+-
Msrc/bpnn.cpp | 32++++++--------------------------
Msrc/bpnn.hpp | 3+--
Msrc/checks.cpp | 314+++++++++++++++++++++++++++++++++++++++++--------------------------------------
4 files changed, 172 insertions(+), 179 deletions(-)

diff --git a/example.cpp b/example.cpp @@ -23,7 +23,7 @@ double bench(int batch_sz, int epochs) net.add_layer(5, "lecun_tanh"); net.add_layer(2, "linear"); net.initialize(); - checks(net); + checks(); for (int i = 0; i < epochs; i++) { net.train(); } diff --git a/src/bpnn.cpp b/src/bpnn.cpp @@ -40,38 +40,18 @@ Layer::Layer(int batch_sz, int nodes, float a) } } -Layer::Layer(const Layer& that) -{ - contents = new Eigen::MatrixXf (that.contents->rows(), that.contents->cols()); - dZ = new Eigen::MatrixXf (that.dZ->rows(), that.dZ->cols()); - bias = new Eigen::MatrixXf (that.bias->rows(), that.bias->cols()); - v = new Eigen::MatrixXf (that.v->rows(), that.v->cols()); - m = new Eigen::MatrixXf (that.m->rows(), that.m->cols()); - weights = new Eigen::MatrixXf (that.weights->rows(), that.weights->cols()); - activation = that.activation; - activation_deriv = that.activation_deriv; - alpha = that.alpha; - strcpy(activation_str, that.activation_str); - *contents = *that.contents; - *v = *that.v; - *m = *that.m; - *weights = *that.weights; - *bias = *that.bias; - *dZ = *that.dZ; -} - void Layer::operator=(const Layer& that) { activation = that.activation; activation_deriv = that.activation_deriv; alpha = that.alpha; strcpy(activation_str, that.activation_str); - *contents = *that.contents; - *v = *that.v; - *m = *that.m; - *weights = *that.weights; - *bias = *that.bias; - *dZ = *that.dZ; + // *contents = *that.contents; + // *v = *that.v; + // *m = *that.m; + // *weights = *that.weights; + // *bias = *that.bias; + // *dZ = *that.dZ; } void Layer::init_weights(Layer next) diff --git a/src/bpnn.hpp b/src/bpnn.hpp @@ -31,7 +31,6 @@ public: Layer(int rows, int columns, float a=0); Layer(float* vals, int rows, int columns); - Layer(const Layer& that); void operator=(const Layer& that); void init_weights(Layer next); }; @@ -98,7 +97,7 @@ public: float get_val_cost() {return val_cost;} }; -void checks(Network net); +void checks(); void demo(int total_epochs); int prep_file(char* path, char* out_path); int split_file(char* path, int lines, float ratio); diff --git a/src/checks.cpp b/src/checks.cpp @@ -3,174 +3,188 @@ // Jacobian // // Created by David Freifeld -// Copyright © 2020 David Freifeld. All rights reserved. // -void checks(Network net) +Network explicit_copy(Network src) { - int sanity_passed = 0; - std::cout << "\u001b[4m\u001b[1mSANITY CHECKS:\u001b[0m\n"; - // Check if regularization strength increases loss (as it should). - std::cout << "Regularization sanity check..."; + Network dst ("./data_banknote_authentication.txt", 16, 0.0155, 0.03, 2, 0, 0.9); + dst.layers = src.layers; + assert(src.layers.size() == dst.layers.size()); + for (int i = 0; i < src.layers.size(); i++) { + dst.layers[i] = src.layers[i]; + } + return src; +} + +void checks() +{ + Network net ("./data_banknote_authentication.txt", 16, 0.0155, 0.03, 2, 0, 0.9); + net.add_layer(4, "linear"); + net.add_layer(5, "lecun_tanh"); + net.add_layer(2, "linear"); + net.initialize(); + int sanity_passed = 0; + std::cout << "\u001b[4m\u001b[1mSANITY CHECKS:\u001b[0m\n"; + // Check if regularization strength increases loss (as it should). + std::cout << "Regularization sanity check..."; - net.list_net(); - Network copy1 = net; - Network copy2 = net; - copy1.lambda += 1; - copy1.next_batch(); - copy1.feedforward(); + net.list_net(); + Network copy1 = explicit_copy(net); + Network copy2 = explicit_copy(net); + copy1.next_batch(); + copy1.feedforward(); - copy2.next_batch(); - copy2.feedforward(); - net.list_net(); - if (copy1.cost() > copy2.cost()) { - std::cout << " \u001b[32mPassed!\n\u001b[37m"; - sanity_passed++; - } - else std::cout << " \u001b[31mFailed.\n\u001b[37m"; + copy2.next_batch(); + copy2.feedforward(); + net.list_net(); + if (copy1.cost() > copy2.cost()) { + std::cout << " \u001b[32mPassed!\n\u001b[37m"; + sanity_passed++; + } + else std::cout << " \u001b[31mFailed.\n\u001b[37m"; - // // net.list_net(); + // // net.list_net(); - // // Check if zero cost is achievable on a batch - // std::cout << "Zero-cost sanity check..."; - // Network copy3 ("./data_banknote_authentication.txt", 16, 0.05, 0.03, 0, 0.9); - // copy3.lambda = 0; - // copy3.next_batch(); - // float finalcost; - // for (int i = 0; i < 10000; i++) { - // copy3.feedforward(); - // copy3.backpropagate(); - // finalcost = copy3.cost(); - // if (finalcost <= ZERO_THRESHOLD) { - // break; - // } - // } - // if (finalcost <= ZERO_THRESHOLD) { - // std::cout << " \u001b[32mPassed!\n\u001b[37m"; - // sanity_passed++; - // } - // else std::cout << " \u001b[31mFailed.\n\u001b[37m"; + // // Check if zero cost is achievable on a batch + // std::cout << "Zero-cost sanity check..."; + // Network copy3 ("./data_banknote_authentication.txt", 16, 0.05, 0.03, 0, 0.9); + // copy3.lambda = 0; + // copy3.next_batch(); + // float finalcost; + // for (int i = 0; i < 10000; i++) { + // copy3.feedforward(); + // copy3.backpropagate(); + // finalcost = copy3.cost(); + // if (finalcost <= ZERO_THRESHOLD) { + // break; + // } + // } + // if (finalcost <= ZERO_THRESHOLD) { + // std::cout << " \u001b[32mPassed!\n\u001b[37m"; + // sanity_passed++; + // } + // else std::cout << " \u001b[31mFailed.\n\u001b[37m"; - // // list_net(); + // // list_net(); - // std::cout << "Gradient floating-point sanity check..."; - // Network copy4 ("./data_banknote_authentication.txt", 16, 0.05, 0.03, 0, 0.9); - // copy4.next_batch(); - // copy4.feedforward(); - // std::vector<Eigen::MatrixXf> gradients; - // std::vector<Eigen::MatrixXf> deltas; - // Eigen::MatrixXf error = ((*copy4.layers[copy4.length-1].contents) - (*copy1.labels)); - // gradients.push_back(error.cwiseProduct(*copy4.layers[copy4.length-1].dZ)); - // deltas.push_back((*copy4.layers[copy4.length-2].contents).transpose() * gradients[0]); - // int counter = 1; - // for (int i = copy4.length-2; i >= 1; i--) { - // gradients.push_back((gradients[counter-1] * copy4.layers[i].weights->transpose()).cwiseProduct(*copy4.layers[i].dZ)); - // deltas.push_back(copy4.layers[i-1].contents->transpose() * gradients[counter]); - // counter++; - // } - // auto check_gradients = [](std::vector<Eigen::MatrixXf> vec) -> bool { - // for (Eigen::MatrixXf i : vec) { - // for (int j = 0; j < i.rows(); j++) { - // for (int k = 0; k < i.cols(); k++) { - // if (i(j,k) == -0 || i(j,k) == INFINITY || i(j,k) == NAN || i(j,k) == -INFINITY) { - // return true; - // } - // } - // } - // } - // return false; - // }; - // if (check_gradients(gradients) == false && check_gradients(deltas) == false) { - // std::cout << " \u001b[32mPassed!\n\u001b[37m"; - // sanity_passed++; - // } - // else std::cout << " \u001b[31mFailed.\n\u001b[37m"; + // std::cout << "Gradient floating-point sanity check..."; + // Network copy4 ("./data_banknote_authentication.txt", 16, 0.05, 0.03, 0, 0.9); + // copy4.next_batch(); + // copy4.feedforward(); + // std::vector<Eigen::MatrixXf> gradients; + // std::vector<Eigen::MatrixXf> deltas; + // Eigen::MatrixXf error = ((*copy4.layers[copy4.length-1].contents) - (*copy1.labels)); + // gradients.push_back(error.cwiseProduct(*copy4.layers[copy4.length-1].dZ)); + // deltas.push_back((*copy4.layers[copy4.length-2].contents).transpose() * gradients[0]); + // int counter = 1; + // for (int i = copy4.length-2; i >= 1; i--) { + // gradients.push_back((gradients[counter-1] * copy4.layers[i].weights->transpose()).cwiseProduct(*copy4.layers[i].dZ)); + // deltas.push_back(copy4.layers[i-1].contents->transpose() * gradients[counter]); + // counter++; + // } + // auto check_gradients = [](std::vector<Eigen::MatrixXf> vec) -> bool { + // for (Eigen::MatrixXf i : vec) { + // for (int j = 0; j < i.rows(); j++) { + // for (int k = 0; k < i.cols(); k++) { + // if (i(j,k) == -0 || i(j,k) == INFINITY || i(j,k) == NAN || i(j,k) == -INFINITY) { + // return true; + // } + // } + // } + // } + // return false; + // }; + // if (check_gradients(gradients) == false && check_gradients(deltas) == false) { + // std::cout << " \u001b[32mPassed!\n\u001b[37m"; + // sanity_passed++; + // } + // else std::cout << " \u001b[31mFailed.\n\u001b[37m"; - // // list_net(); + // // list_net(); - // std::cout << "Expected loss sanity check..."; + // std::cout << "Expected loss sanity check..."; - // Network copy5 ("./data_banknote_authentication.txt", 16, 0.05, 0.03, 0, 0.9); - // copy5.next_batch(); - // copy5.feedforward(); - // if (copy5.cost() <= 1) { - // std::cout << " \u001b[32mPassed!\n\u001b[37m"; - // sanity_passed++; - // } - // else std::cout << " \u001b[31mFailed.\n\u001b[37m"; + // Network copy5 ("./data_banknote_authentication.txt", 16, 0.05, 0.03, 0, 0.9); + // copy5.next_batch(); + // copy5.feedforward(); + // if (copy5.cost() <= 1) { + // std::cout << " \u001b[32mPassed!\n\u001b[37m"; + // sanity_passed++; + // } + // else std::cout << " \u001b[31mFailed.\n\u001b[37m"; - // // list_net(); + // // list_net(); - // std::cout << "Layer updates sanity check..."; - // Network copy6 ("./data_banknote_authentication.txt", 16, 0.05, 0.03, 0, 0.9); - // Network copy7 ("./data_banknote_authentication.txt", 16, 0.05, 0.03, 0, 0.9); - // //copy2.list_net(); - // //copy1.list_net(); - // int passed; - // for (int i = 0; i < copy1.layers.size()-1; i++) { - // if (*copy1.layers[i].weights == *copy2.layers[i].weights) { - // // std::cout << *copy2.layers[i].weights <<"uninitweight\n\n"; - // // std::cout << *copy1.layers[i].weights << " "<<i<<"weight\n\n"; - // passed = -1; - // } - // } - // for (int i = 1; i < copy1.layers.size(); i++) { - // if (*copy1.layers[i].bias == *copy2.layers[i].bias) { - // // std::cout << *copy2.layers[i].bias <<"uninitbias\n\n"; - // // std::cout << *copy1.layers[i].bias <<" " << i << "bias\n\n"; - // passed = -1; - // } - // } - // if (passed == 1) { - // std::cout << " \u001b[32mPassed!\n\u001b[37m"; - // sanity_passed++; - // } - // else std::cout << " \u001b[31mFailed.\n\u001b[37m"; + // std::cout << "Layer updates sanity check..."; + // Network copy6 ("./data_banknote_authentication.txt", 16, 0.05, 0.03, 0, 0.9); + // Network copy7 ("./data_banknote_authentication.txt", 16, 0.05, 0.03, 0, 0.9); + // //copy2.list_net(); + // //copy1.list_net(); + // int passed; + // for (int i = 0; i < copy1.layers.size()-1; i++) { + // if (*copy1.layers[i].weights == *copy2.layers[i].weights) { + // // std::cout << *copy2.layers[i].weights <<"uninitweight\n\n"; + // // std::cout << *copy1.layers[i].weights << " "<<i<<"weight\n\n"; + // passed = -1; + // } + // } + // for (int i = 1; i < copy1.layers.size(); i++) { + // if (*copy1.layers[i].bias == *copy2.layers[i].bias) { + // // std::cout << *copy2.layers[i].bias <<"uninitbias\n\n"; + // // std::cout << *copy1.layers[i].bias <<" " << i << "bias\n\n"; + // passed = -1; + // } + // } + // if (passed == 1) { + // std::cout << " \u001b[32mPassed!\n\u001b[37m"; + // sanity_passed++; + // } + // else std::cout << " \u001b[31mFailed.\n\u001b[37m"; - // std::cout << "Side effects sanity check..."; + // std::cout << "Side effects sanity check..."; - // if (net == original) { - // std::cout << " \u001b[32mPassed!\n\u001b[37m"; - // sanity_passed++; - // } - // else std::cout << " \u001b[31mFailed.\n\u001b[37m"; + // if (net == original) { + // std::cout << " \u001b[32mPassed!\n\u001b[37m"; + // sanity_passed++; + // } + // else std::cout << " \u001b[31mFailed.\n\u001b[37m"; - std::cout << "\u001b[1m\nPassed " << sanity_passed << "/6" <<" sanity checks.\u001b[0m\n\n\n"; + std::cout << "\u001b[1m\nPassed " << sanity_passed << "/6" <<" sanity checks.\u001b[0m\n\n\n"; - // net.list_net(); + // net.list_net(); - // float epsilon = 0.0001; - // Network copy = *this; - // std::vector<Eigen::MatrixXf> approx_gradients; - // for (int i = 0; i < copy.layers.size()-1; i++) { - // Eigen::MatrixXf current_approx = *copy.layers[i].weights; - // for (int j = 0; i < copy.layers[i].weights->rows(); i++) { - // for (int k = 0; i < copy.layers[i].weights->cols(); i++) { - // Network sim1 = copy; - // (*sim1.layers[i].contents)(j,k) += epsilon; - // sim1.feedforward(); - // Network sim2 = copy; - // (*sim2.layers[i].contents)(j,k) -= epsilon; - // sim2.feedforward(); - // current_approx(j,k) = (sim1.cost() - sim2.cost())/(2*epsilon); - // } - // } - // approx_gradients.push_back(current_approx); - // } - // for (Eigen::MatrixXf i : approx_gradients) { - // std::cout << i << "\n\n"; - // } - // std::vector<Eigen::MatrixXf> gradients; - // std::vector<Eigen::MatrixXf> deltas; - // Eigen::MatrixXf error = ((*layers[length-1].contents) - (*labels)); - // gradients.push_back(error.cwiseProduct(*layers[length-1].dZ)); - // deltas.push_back((*layers[length-2].contents).transpose() * gradients[0]); - // int counter = 1; - // for (int i = length-2; i >= 1; i--) { - // gradients.push_back((gradients[counter-1] * layers[i].weights->transpose()).cwiseProduct(*layers[i].dZ)); - // deltas.push_back(layers[i-1].contents->transpose() * gradients[counter]); - // counter++; - // } - //printf("Beginning train on %i instances for %i epochs...\n", instances, total_epochs); + // float epsilon = 0.0001; + // Network copy = *this; + // std::vector<Eigen::MatrixXf> approx_gradients; + // for (int i = 0; i < copy.layers.size()-1; i++) { + // Eigen::MatrixXf current_approx = *copy.layers[i].weights; + // for (int j = 0; i < copy.layers[i].weights->rows(); i++) { + // for (int k = 0; i < copy.layers[i].weights->cols(); i++) { + // Network sim1 = copy; + // (*sim1.layers[i].contents)(j,k) += epsilon; + // sim1.feedforward(); + // Network sim2 = copy; + // (*sim2.layers[i].contents)(j,k) -= epsilon; + // sim2.feedforward(); + // current_approx(j,k) = (sim1.cost() - sim2.cost())/(2*epsilon); + // } + // } + // approx_gradients.push_back(current_approx); + // } + // for (Eigen::MatrixXf i : approx_gradients) { + // std::cout << i << "\n\n"; + // } + // std::vector<Eigen::MatrixXf> gradients; + // std::vector<Eigen::MatrixXf> deltas; + // Eigen::MatrixXf error = ((*layers[length-1].contents) - (*labels)); + // gradients.push_back(error.cwiseProduct(*layers[length-1].dZ)); + // deltas.push_back((*layers[length-2].contents).transpose() * gradients[0]); + // int counter = 1; + // for (int i = length-2; i >= 1; i--) { + // gradients.push_back((gradients[counter-1] * layers[i].weights->transpose()).cwiseProduct(*layers[i].dZ)); + // deltas.push_back(layers[i-1].contents->transpose() * gradients[counter]); + // counter++; + // } + //printf("Beginning train on %i instances for %i epochs...\n", instances, total_epochs); }