jacobian

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

commit 2781f8c7de154e2e102c1fa6c87e462113d12c9c
parent 35b202dde0c7e0c1b9291fcdda44537eec9eca24
Author: David Freifeld <freifeld.david@gmail.com>
Date:   Mon, 13 Jul 2020 10:39:09 -0700

Working on more safety checks

Diffstat:
Mexample.cpp | 10+++++-----
Msrc/bpnn.cpp | 24+++++++++---------------
Msrc/checks.cpp | 16+++++++++++++---
3 files changed, 27 insertions(+), 23 deletions(-)

diff --git a/example.cpp b/example.cpp @@ -10,9 +10,9 @@ double bench(int batch_sz) net.add_layer(4, "linear"); net.add_layer(5, "relu"); net.add_layer(2, "linear"); - // net.init_decay("step", 1, 2); + net.init_decay("step", 1, 2); net.initialize(); - // checks(net); + // checks(net); // for (int i = 0; i < 10; i++) { // net.next_batch(); // net.feedforward(); @@ -20,12 +20,12 @@ double bench(int batch_sz) // net.backpropagate(); // std::cout << net.cost() << " " << net.accuracy() << "\n"; // } - for (int i = 0; i < 50; i++) { + for (int i = 0; i < 25; i++) { net.train(); // net.list_net(); } - std::cout << *net.layers[net.length-1].contents << "\n\n"; - std::cout << *net.labels << "\n"; + // std::cout << *net.layers[net.length-1].contents << "\n\n"; + // std::cout << *net.labels << "\n"; auto end = std::chrono::high_resolution_clock::now(); //net.list_net(); return std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count() / pow(10,9); diff --git a/src/bpnn.cpp b/src/bpnn.cpp @@ -10,7 +10,13 @@ #define MAXLINE 1024 #define ZERO_THRESHOLD pow(10, -8) // for checks +#if (!RECKLESS) #define checknan(x, loc) if(x==INFINITY || x==NAN || x == -INFINITY) throw ValueError("Detected NaN in operation", loc) +#else +#define checknan(x, loc) +#endif + +#include "checks.cpp" struct ValueError : public std::exception { @@ -177,31 +183,20 @@ void Network::feedforward() } } } - //std::cout << (*layers[length-1].contents) << "\n"; for (int i = 0; i < layers[length-1].contents->rows(); i++) { float sum = 0; Eigen::MatrixXf m = layers[length-1].contents->block(i,0,1,layers[length-1].contents->cols()); Eigen::MatrixXf::Index maxRow, maxCol; float max = m.maxCoeff(&maxRow, &maxCol); - // std::cout << m << "(before with max "<< max <<")\n"; m = (m.array() - max).matrix(); - // std::cout << m << "(after with max "<< max <<")\n"; for (int j = 0; j < layers[length-1].contents->cols(); j++) { -#ifndef RECKLESS checknan(m(0,j), "input to final layer"); -#endif - // if(m(0,j)==INFINITY || m(0,j)==NAN || m(0,j)== -INFINITY) throw ValueError("Detected NaN or inf value in layer", "input to final layer"); sum += exp(m(0,j)); -#ifndef RECKLESS checknan(sum, "sum in Softmax operation"); -#endif } for (int j = 0; j < layers[length-1].contents->cols(); j++) { - // std::cout << "(e^" << m(0,j) << ")/" << sum << " -> " << exp(m(0,j)) << "/" << sum << " -> " << exp((m(0,j)))/sum << "\n"; m(0,j) = exp(m(0,j))/sum; -#ifndef RECKLESS checknan(m(0,j), "output of Softmax operation"); -#endif } layers[length-1].contents->block(i,0,1,layers[length-1].contents->cols()) = m; } @@ -213,7 +208,7 @@ void Network::list_net() for (int i = 1; i < length-1; i++) { std::cout << "-----------------------\nLAYER " << i << "\n-----------------------\n\n\u001b[31mGENERAL INFO:\x1B[0;37m\nActivation Function: " << layers[i].activation_str << "\n\n\u001b[31mACTIVATIONS:\x1B[0;37m\n" << *layers[i].contents << "\n\n\u001b[31mBIASES:\x1B[0;37m\n" << *layers[i].bias << "\n\n\u001b[31mWEIGHTS:\x1B[0;37m\n" << *layers[i].weights << "\n\n\n"; } - std::cout << "-----------------------\nOUTPUT LAYER (LAYER " << length-1 << ")\n-----------------------\n\n\u001b[31mGENERAL INFO:\x1B[0;37m\nActivation Function: " << layers[length-1].activation_str <<"\n\n\u001b[31mACTIVATIONS:\x1B[0;37m\n" << *layers[length-1].contents << "\n\n\u001b[31mBIASES:\x1B[0;37m\n" << *layers[length-1].bias << "\n\n\n"; + std::cout << "-----------------------\nOUTPUT LAYER (LAYER " << length-1 << ")\n-----------------------\n\n\u001b[31mGENERAL INFO:\x1B[0;37m\nActivation Function: " << layers[length-1].activation_str <<"\n\n\u001b[31mACTIVATIONS:\x1B[0;37m\n" << *layers[length-1].contents << "\n\n\u001b[31BIASES:\x1B[0;37m\n" << *layers[length-1].bias << "\n\n\n"; } float Network::cost() @@ -269,6 +264,7 @@ void Network::backpropagate() if (j==(*labels)(i,0)) truth = 1; else truth = 0; error(i,j) = (*layers[length-1].contents)(i,j) - truth; + checknan(error(i,j), "gradient of final layer"); // std::cout << truth << "[as label is "<< (*labels)(i,0) <<"] - " << (*layers[length-1].contents)(i,j) << "[aka index " << i << " " << j << "] = " << error(i,j) << "\n"; } } @@ -405,15 +401,13 @@ float Network::test(char* path) return 0; } -#include "checks.cpp" - void Network::train() { rewind(data); float cost_sum = 0; float acc_sum = 0; for (int i = 0; i <= instances-batch_size; i+=batch_size) { - [[unlikely]] if (i != instances-batch_size) { // Don't try to advance batch on final batch. + if (i != instances-batch_size) { // Don't try to advance batch on final batch. next_batch(); } feedforward(); diff --git a/src/checks.cpp b/src/checks.cpp @@ -1,5 +1,6 @@ void checks(Network net) { + Network original = net; int sanity_passed = 0; std::cout << "\u001b[4m\u001b[1mSANITY CHECKS:\u001b[0m\n"; // Check if regularization strength increases loss (as it should). @@ -20,7 +21,7 @@ void checks(Network net) } else std::cout << " \u001b[31mFailed.\n\u001b[37m"; - // list_net(); + // net.list_net(); // Check if zero cost is achievable on a batch std::cout << "Zero-cost sanity check..."; @@ -121,10 +122,18 @@ void checks(Network net) sanity_passed++; } else std::cout << " \u001b[31mFailed.\n\u001b[37m"; + + // std::cout << "Side effects sanity check..."; - std::cout << "\u001b[1m\nPassed " << sanity_passed << "/5" <<" sanity checks.\u001b[0m\n\n\n"; + // if (net == original) { + // std::cout << " \u001b[32mPassed!\n\u001b[37m"; + // sanity_passed++; + // } + // else std::cout << " \u001b[31mFailed.\n\u001b[37m"; - net.list_net(); + std::cout << "\u001b[1m\nPassed " << sanity_passed << "/6" <<" sanity checks.\u001b[0m\n\n\n"; + + // net.list_net(); // float epsilon = 0.0001; // Network copy = *this; @@ -159,4 +168,5 @@ void checks(Network net) // counter++; // } //printf("Beginning train on %i instances for %i epochs...\n", instances, total_epochs); + }