jacobian

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

commit 27782f158e1d58d64e02623f3880407ad5f54574
parent 673085cac2b11077699adb8bc35967cb24832817
Author: David Freifeld <freifeld.david@gmail.com>
Date:   Tue, 16 Jun 2020 18:43:44 -0700

Restructuring, strange malloc bug

Diffstat:
Mbpnn.c | 143++++---------------------------------------------------------------------------
Abpnn.cpp | 263+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amr_bpnn_1.cpp | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dtest.cpp | 396-------------------------------------------------------------------------------
Dtest.hpp | 15---------------
5 files changed, 359 insertions(+), 547 deletions(-)

diff --git a/bpnn.c b/bpnn.c @@ -1,145 +1,16 @@ -#include <stdio.h> #include <stdlib.h> -#include <math.h> - -/* #include "../mapreduce/mapreduce.h" */ -/* #include "../mapreduce/server.h" */ -/* #include "../mapreduce/worker.h" */ - -#define BUFSIZE 2048 - -struct node; - -struct edge { - struct node * source; - struct node * target; - double weight; -}; - -struct node { - struct edge* incoming; - struct edge* outgoing; - float activation; -}; +#include <stdio.h> -struct layer { - struct node* nodes; - int length; -}; +typedef struct { + int** rows; +}Matrix; struct network { - struct layer* layers; - int length; -}; - -double activate (double value) { - // Sigmoid - return 1/(1+pow(M_E, -value)); -} - -struct network initialize (char* path, int inputs, int neurons, int hidden, int outputs) { - // Read from CSV - FILE* fptr = fopen(path, "r"); - double data[inputs]; - fscanf(fptr, "%d,%d,%d,%d,*d", &data[0], &data[1], &data[2], &data[3]); - - // Initialize network - struct network net; - net.layers = malloc((hidden + 2) * sizeof(struct layer)); - net.length = hidden + 2; - // Initialize input nodes - net.layers[0].nodes = malloc(inputs * sizeof(struct node)); - for (int i = 0; i < inputs; i++) { - net.layers[0].nodes[i].activation = activate(data[i]); - } - net.layers[0].length = inputs; - - /* // Init hidden layer nodes and output nodes to 0 (will be replaced by feedforward) */ - for (int i = 1; i <= hidden; i++) { - net.layers[i].nodes = malloc(neurons * sizeof(struct node)); - for (int j = 0; j < neurons; j++) { - net.layers[i].nodes[j].activation = 0; - } - net.layers[i].length = neurons; - printf("inside %i\n", net.layers[i].length); - } - printf("outsidee %i\n", net.layers[0].length); - net.layers[hidden-1].nodes = malloc(outputs * sizeof(struct node)); - for (int i = 0; i < outputs; i++) { - net.layers[hidden-1].nodes[i].activation = 0; - } - net.layers[hidden+1].length = outputs; - - // Init edges between layers with random numbers TODO make a function to initialize edges between two layers for the love of God - for (int i = 0; i < inputs; i++) { - net.layers[0].nodes[i].outgoing = malloc(neurons * sizeof(struct edge)); - for (int j = 0; j < neurons; j++) { - net.layers[1].nodes[j].incoming = malloc(inputs * sizeof(struct edge)); - struct edge connection = {&net.layers[0].nodes[i], &net.layers[1].nodes[j], rand()}; - net.layers[0].nodes[i].outgoing[j] = connection; - net.layers[1].nodes[j].incoming[i] = connection; - } - } - for (int i = 1; i <= hidden; i++) { - for (int j = 0; j < neurons; j++) { - net.layers[i].nodes[j].outgoing = malloc(neurons * sizeof(struct edge)); - for (int k = 0; k < neurons; k++) { - printf("CHECKCHECKCHECK!?\n"); - net.layers[i+1].nodes[k].outgoing = malloc(neurons * sizeof(struct edge)); - printf("Checkcheck1\n"); - struct edge connection = {&net.layers[i].nodes[j], &net.layers[i+1].nodes[k], rand()}; - printf("Checkcheck2\n"); - net.layers[i].nodes[j].outgoing[k] = connection; - printf("Checkcheck3\n"); - net.layers[i+1].nodes[k].incoming[j] = connection; - } - } - } - /* for (int i = 0; i < neurons; i++) { */ - /* net.layers[hidden].nodes[i].outgoing = malloc(outputs * sizeof(struct edge)); */ - /* for (int j = 0; j < outputs; j++) { */ - /* net.layers[hidden+1].nodes[j].incoming = 204892141; //malloc(neurons * sizeof(struct edge)); */ - /* struct edge connection = {&net.layers[0].nodes[0], &net.layers[1].nodes[0], rand()}; */ - /* net.layers[hidden].nodes[i].outgoing[j] = connection; */ - /* net.layers[hidden+1].nodes[j].incoming[i] = connection; */ - /* } */ - /* } */ - /* Epic, everything's initialized TODO add biases! */ - return net; -} +}; -void feedforward(struct network net) +int main() { - /* printf("Checkcheck\n"); */ - for (int i = 1; i < net.length; i++) { - /* printf("%i\n", net.layers[i].length); */ - for (int j = 0; j < net.layers[i].length; j++) { - double sum = 0; - for (int k = 0; k < net.layers[i-1].length; k++) { - sum += net.layers[i].nodes[j].incoming->source->activation * net.layers[i].nodes[j].incoming->weight; - } - printf("%f\n", sum); - net.layers[i].nodes[j].activation = activate(sum); - printf("Node %i in layer %i has activation %f\n", j, i, net.layers[i].nodes[j].activation); - } - } -} - -/* struct int_pair* map (struct str_pair file) */ -/* { */ -/* struct network neuralnet = initialize("./data_banknote_authentication.txt", 4, 5, 2, 2); */ -/* feedforward(neuralnet); */ -/* } */ -/* struct int_pair* reduce (struct int_pair* input) */ -/* { */ - -/* } */ - -int main(int argc, char** argv) -{ - struct network neuralnet = initialize("./data_banknote_authentication.txt", 4, 5, 2, 2); - feedforward(neuralnet); - /* mapreduce(argv[3], map, reduce, strtol(argv[2], NULL, 10), 50, strtol(argv[1], NULL, 10), 1); */ + return 0; } diff --git a/bpnn.cpp b/bpnn.cpp @@ -0,0 +1,263 @@ +#include "bpnn.hpp" + +Layer::Layer(float* vals, int batch_sz, int nodes) +{ + contents = new Eigen::MatrixXd (batch_sz, nodes); + int datalen = batch_sz*nodes; + for (int i = 0; i < datalen; i++) { + (*contents)((int)i / nodes,i%nodes) = vals[i]; + } + bias = new Eigen::MatrixXd (1, nodes); + for (int i = 0; i < nodes; i++) { + (*bias)(0,i) = 0.001; + } +} + +Layer::Layer(int batch_sz, int nodes) +{ + contents = new Eigen::MatrixXd (batch_sz, nodes); + int datalen = batch_sz*nodes; + for (int i = 0; i < datalen; i++) { + (*contents)((int)i / nodes,i%nodes) = 0; + } + bias = new Eigen::MatrixXd (1, nodes); + for (int i = 0; i < nodes; i++) { + (*bias)(0,i) = 0.001; + } + dZ = new Eigen::MatrixXd (batch_sz, nodes); +} + +void Layer::initWeights(Layer next) +{ + weights = new Eigen::MatrixXd (contents->cols(), next.contents->cols()); + int nodes = weights->cols(); + for (int i = 0; i < (weights->rows()*weights->cols()); i++) { + (*weights)((int)i / nodes, i%nodes) = rand() / double(RAND_MAX); + } +} + +Network::Network(char* path, int inputs, int hidden, int outputs, int neurons, int batch_sz, float rate) +{ + learning_rate = rate; + fpath = path; + length = hidden + 2; + batch_size = batch_sz; + FILE* fptr = fopen(path, "r"); + int datalen = batch_sz*inputs; + float batch[datalen]; + labels = new Eigen::MatrixXd (batch_sz, 1); + int label; + char line[1024] = {' '}; + for (int i = 0; i < batch_sz; i++) { + fgets(line, 1024, fptr); + sscanf(line, "%f,%f,%f,%f,%i", &batch[0+(i*inputs)], &batch[1+(i*inputs)], &batch[2+(i*inputs)], &batch[3+(i*inputs)], &label); + (*labels)(i,0) = label; + } + float* batchptr = batch; + layers.emplace_back(batchptr, batch_sz, inputs); + for (int i = 0; i < hidden; i++) { + layers.emplace_back(batch_sz, neurons); + } + layers.emplace_back(batch_sz, outputs); + for (int i = 0; i < hidden+1; i++) { + layers[i].initWeights(layers[i+1]); + } +} + +Eigen::MatrixXd Network::activate(Eigen::MatrixXd matrix) +{ + int nodes = matrix.cols(); + for (int i = 0; i < (matrix.rows()*matrix.cols()); i++) { + (matrix)((float)i / nodes, i%nodes) = 1.0/(1+exp(-(matrix)((float)i / nodes, i%nodes))); + } + return matrix; +} + +Eigen::MatrixXd Network::activate_deriv(Eigen::MatrixXd matrix) +{ + int nodes = matrix.cols(); + for (int i = 0; i < (matrix.rows()*matrix.cols()); i++) { + (matrix)((float)i / nodes, i%nodes) = 1.0/(1+exp(-(matrix)((float)i / nodes, i%nodes))) * (1 - 1.0/(1+exp(-(matrix)((float)i / nodes, i%nodes)))); + } + return matrix; +} + +void Network::feedforward() +{ + for (int i = 0; i < length-1; i++) { + *layers[i+1].contents = (*layers[i].contents) * (*layers[i].weights); + for (int j = 0; j < layers[i+1].contents->rows(); j++) { + // layers[i+1].contents->row(j) += *layers[i+1].bias; TODO ADD ME BACK! + } + // if (i != length-2) { + *layers[i+1].contents = activate(*layers[i+1].contents); + *layers[i+1].dZ = activate_deriv(*layers[i+1].contents); + // } + // else { + // *layers[i + 1].dZ = (layers[i + 1].dZ->array() + 1).matrix(); + // } + // list_net(); + } +} + +void Network::list_net() +{ + for (int i = 0; i < length-1; i++) { + std::cout << " LAYER " << i << "\n\n" << *layers[i].contents << "\n\n AND BIAS\n" << *layers[i].bias << "\n\n W/ WEIGHTS \n" << *layers[i].weights << "\n\n\n"; + } + std::cout << " LAYER " << length-1 << "\n\n" << *layers[length-1].contents << "\n\n AND BIAS\n" << *layers[length-1].bias << "\n\n\n"; +} + +float Network::cost() +{ + float sum = 0; + for (int i = 0; i < layers[length-1].contents->rows(); i++) { + sum += pow((*labels)(i, 0)*100 - (*layers[length-1].contents)(i, 0)*100,2); + } + return (1.0/batch_size) * sum; +} + +void Network::backpropagate() +{ + // std::cout << "\nROUND\n\n\n\n\n\n"; + std::vector<Eigen::MatrixXd> gradients; + std::vector<Eigen::MatrixXd> deltas; + gradients.push_back(((*layers[length-1].contents) - (*labels)).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--) { + // std::cout << gradients[counter-1] << "\n\nTHAT WAS GRADIENT\n\n" <<*layers[i].weights << "\n\nTHAT WAS WEIGHTS\n" + gradients.push_back((gradients[counter-1] * layers[i].weights->transpose()).cwiseProduct(*layers[i].dZ)); + deltas.push_back((*layers[i-1].contents).transpose() * gradients[counter]); + // std::cout << gradients[counter] << "\n\nand\n\n" << *layers[i-1].weights << "\n\nweights\n\n" << deltas[counter] << "\n\ndelta above\n\n\n\n\n"; + counter++; + } + for (int i = 1; i < gradients.size(); i++) { + Eigen::MatrixXd gradient = gradients[i]; + *layers[length-2-i].weights -= learning_rate * (deltas[i]); + } +} + +void Network::update_layer(float* vals, int datalen, int index) +{ + for (int i = 0; i < datalen; i++) { + (*layers[index].contents)((int)i / layers[index].contents->cols(),i%layers[index].contents->cols()) = vals[i]; + } +} + +int Network::next_batch() +{ + FILE* fptr = fopen(fpath, "r"); + char line[1024] = {' '}; + int inputs = layers[0].contents->cols(); + int datalen = batch_size * inputs; + float batch[datalen]; + int label = 100; + for (int i = 0; i < batch_size*batches + 1; i++) { + if (fgets(line, 1024, fptr)==NULL) { + break; + } + if (i >= batches) { + for (int j = 0; j < batch_size; j++) { + fgets(line, 1024, fptr); + sscanf(line, "%f,%f,%f,%f,%i", &batch[0 + (j * inputs)], + &batch[1 + (j * inputs)], &batch[2 + (j * inputs)], + &batch[3 + (j * inputs)], &label); + (*labels)(j, 0) = label; + } + } + } + float* batchptr = batch; + update_layer(batchptr, datalen, 0); + fclose(fptr); + return 0; +} + +int prep_file(char* path) +{ + FILE* rptr = fopen(path, "r"); + char line[1024]; + std::vector<std::string> lines; + int count = 0; + while (fgets(line, 1024, rptr) != NULL) { + lines.emplace_back(line); + count++; + } + std::random_device rd; + std::mt19937 g(rd()); + std::shuffle(lines.begin(), lines.end(), g); + fclose(rptr); + std::ofstream out("./shuffled.txt"); + for (int i = 0; i < lines.size(); i++) { + out << lines[i]; + } + return count; +} + +void Network::test(char* path) +{ + int rounds = 1; + int exit = 0; + float totalcost = -1; + int linecount = prep_file(path); + while (exit == 0) { + FILE* fptr = fopen(fpath, "r"); + char line[1024] = {' '}; + int inputs = layers[0].contents->cols(); + int datalen = batch_size * inputs; + float batch[datalen]; + for (int i = 0; i < batch_size*rounds + 1; i++) { + if (fgets(line, 1024, fptr)==NULL) { + exit = -1; + } + if (i >= rounds) { + for (int j = 0; j < batch_size; j++) { + fgets(line, 1024, fptr); + sscanf(line, "%f,%f,%f,%f,*i", &batch[0 + (j * inputs)], &batch[1 + (j * inputs)], &batch[2 + (j * inputs)], &batch[3 + (j * inputs)]); + } + } + } + float *batchptr = batch; + update_layer(batchptr, datalen, 0); + fclose(fptr); + feedforward(); + list_net(); + // std::cout << *layers[length-1].contents << "\n\nvs\n\n" << *labels << "\n\n"; + totalcost += cost(); + rounds++; + } + std::cout << "TEST COST: " << 1.0/((float) linecount) * totalcost << "\n"; +} + +void demo() +{ + // std::cout << "\n\n\n"; + int linecount = prep_file("./data_banknote_authentication.txt"); + Network net ("./shuffled.txt", 4, 2, 1, 5, 10, 1); + float epoch_cost = 1000; + int epochs = 0; + net.batches= 1; + // net.feedforward(); + // net.backpropagate(); + // std::cout << net.cost() << "\n"; + + while (epochs < 500) { + int linecount = prep_file("./data_banknote_authentication.txt"); + float cost_sum = 0; + for (int i = 0; i < linecount-net.batch_size; i+=net.batch_size) { + net.feedforward(); + net.backpropagate(); + cost_sum += net.cost(); + // std::cout << net.cost() << " as it is " << net.labels[0] << " vs " << *net.layers[net.length-1].contents << "\n"; + net.batches++; + int exit = net.next_batch(); + if (exit == -1) { + break; + } + } + net.batches=1; + epoch_cost = 1.0/((float) linecount) * cost_sum; + printf("EPOCH %i: Cost is %f for %i instances.\n", epochs, epoch_cost, linecount); + epochs++; + } +} diff --git a/mr_bpnn_1.cpp b/mr_bpnn_1.cpp @@ -0,0 +1,89 @@ +#include "bpnn.hpp" + +struct int_pair* map (struct str_pair input_pair) +{ + int_pair* output_pairs = new int_pair[1024]; + int linecount = prep_file("./data_banknote_authentication.txt"); + Network net ("./shuffled.txt", 4, 2, 1, 5, 1, 1); + float epoch_cost = 1000; + int epochs = 0; + net.batches= 1; + + while (epochs < 1) { + int linecount = prep_file("./data_banknote_authentication.txt"); + float cost_sum = 0; + for (int i = 0; i < linecount-net.batch_size; i+=net.batch_size) { + net.feedforward(); + net.backpropagate(); + cost_sum += net.cost(); + net.batches++; + int exit = net.next_batch(); + if (exit == -1) { + break; + } + } + net.batches=1; + epoch_cost = 1.0/((float) linecount) * cost_sum; + printf("EPOCH %i: Cost is %f for %i instances.\n", epochs, epoch_cost, linecount); + epochs++; + } + int rounds = 1; + int exit = 0; + float totalcost = -1; + while (exit == 0) { + FILE* fptr = fopen(input_pair.key, "r"); + char line[1024] = {' '}; + int inputs = net.layers[0].contents->cols(); + int datalen = net.batch_size * inputs; + float batch[datalen]; + for (int i = 0; i < net.batch_size*rounds + 1; i++) { + if (fgets(line, 1024, fptr)==NULL) { + exit = -1; + } + if (i >= rounds) { + for (int j = 0; j < net.batch_size; j++) { + fgets(line, 1024, fptr); + sscanf(line, "%f,%f,%f,%f,%lf", &batch[0 + (j * inputs)], &batch[1 + (j * inputs)], &batch[2 + (j * inputs)], &batch[3 + (j * inputs)], &(*net.labels)(j)); + } + } + } + float *batchptr = batch; + net.update_layer(batchptr, datalen, 0); + net.feedforward(); + for (int i = 0; i < net.batch_size; i++) { + char key[1024]; + sprintf(key, "%i", net.batch_size); + output_pairs[i].key = key; + output_pairs[i].value = net.cost(); + } + totalcost += net.cost(); + rounds++; + } + return output_pairs; +} + +int_pair* reduce (int_pair* input_pairs) +{ + int_pair* output_pairs = new int_pair[2]; + int keysum = 0; + int valsum = 0; + for (int i = 0; input_pairs[i].key != NULL; i++) { + printf("CHECKPOINT\n"); + printf("%s\n", input_pairs[i].key); + keysum += strtol(input_pairs[i].key, NULL, 10); + valsum += input_pairs[i].value; + } + char key[1024]; + std::cout << keysum << " and " << valsum << " are SUMS\n"; + sprintf(key, "%d", keysum); + output_pairs[0].key = key; + output_pairs[0].value = valsum; + output_pairs[1].key = (char*) '\0'; + output_pairs[1].value = -1; + return output_pairs; +} + +int main(int argc, char** argv) +{ + begin(argv[2], map, reduce, strtol(argv[1], NULL, 10), 1, argv[3]); +} diff --git a/test.cpp b/test.cpp @@ -1,396 +0,0 @@ -// extern "C" void C_library_function(int x, int y); -#include "test.hpp" - -extern "C" { - #include "../mapreduce/mapreduce.h" -} - -class Layer { -public: - Eigen::MatrixXd* contents; - Eigen::MatrixXd* weights; - Eigen::MatrixXd* bias; - Eigen::MatrixXd* dZ; - - Layer(float* vals, int rows, int columns); - Layer(int rows, int columns); - void initWeights(Layer next); -}; - -Layer::Layer(float* vals, int batch_sz, int nodes) -{ - contents = new Eigen::MatrixXd (batch_sz, nodes); - int datalen = batch_sz*nodes; - for (int i = 0; i < datalen; i++) { - (*contents)((int)i / nodes,i%nodes) = vals[i]; - } - bias = new Eigen::MatrixXd (1, nodes); - for (int i = 0; i < nodes; i++) { - (*bias)(0,i) = 0.001; - } -} - -Layer::Layer(int batch_sz, int nodes) -{ - contents = new Eigen::MatrixXd (batch_sz, nodes); - int datalen = batch_sz*nodes; - for (int i = 0; i < datalen; i++) { - (*contents)((int)i / nodes,i%nodes) = 0; - } - bias = new Eigen::MatrixXd (1, nodes); - for (int i = 0; i < nodes; i++) { - (*bias)(0,i) = 0.001; - } - dZ = new Eigen::MatrixXd (batch_sz, nodes); -} - -void Layer::initWeights(Layer next) -{ - weights = new Eigen::MatrixXd (contents->cols(), next.contents->cols()); - int nodes = weights->cols(); - for (int i = 0; i < (weights->rows()*weights->cols()); i++) { - (*weights)((int)i / nodes, i%nodes) = rand() / double(RAND_MAX); - } -} - -class Network { -public: - char* fpath; - - std::vector<Layer> layers; - int length; - - float learning_rate; - int batch_size; - int batches; - Eigen::MatrixXd* labels; - - Network(char* path, int inputs, int hidden, int outputs, int neurons, int batch_sz, float rate); - void update_layer(float* vals, int datalen, int index); - - Eigen::MatrixXd activate(Eigen::MatrixXd matrix); - Eigen::MatrixXd activate_deriv(Eigen::MatrixXd matrix); - void feedforward(); - void list_net(); - - float cost(); - float gradient(int mode, int layer, int node); - void backpropagate(); - int next_batch(); - void test(char* path); -}; - -Network::Network(char* path, int inputs, int hidden, int outputs, int neurons, int batch_sz, float rate) -{ - learning_rate = rate; - fpath = path; - length = hidden + 2; - batch_size = batch_sz; - FILE* fptr = fopen(path, "r"); - int datalen = batch_sz*inputs; - float batch[datalen]; - labels = new Eigen::MatrixXd (batch_sz, 1); - int label; - char line[1024] = {' '}; - for (int i = 0; i < batch_sz; i++) { - fgets(line, 1024, fptr); - sscanf(line, "%f,%f,%f,%f,%i", &batch[0+(i*inputs)], &batch[1+(i*inputs)], &batch[2+(i*inputs)], &batch[3+(i*inputs)], &label); - (*labels)(i,0) = label; - } - float* batchptr = batch; - layers.emplace_back(batchptr, batch_sz, inputs); - for (int i = 0; i < hidden; i++) { - layers.emplace_back(batch_sz, neurons); - } - layers.emplace_back(batch_sz, outputs); - for (int i = 0; i < hidden+1; i++) { - layers[i].initWeights(layers[i+1]); - } -} - -Eigen::MatrixXd Network::activate(Eigen::MatrixXd matrix) -{ - int nodes = matrix.cols(); - for (int i = 0; i < (matrix.rows()*matrix.cols()); i++) { - (matrix)((float)i / nodes, i%nodes) = 1.0/(1+exp(-(matrix)((float)i / nodes, i%nodes))); - } - return matrix; -} - -Eigen::MatrixXd Network::activate_deriv(Eigen::MatrixXd matrix) -{ - int nodes = matrix.cols(); - for (int i = 0; i < (matrix.rows()*matrix.cols()); i++) { - (matrix)((float)i / nodes, i%nodes) = 1.0/(1+exp(-(matrix)((float)i / nodes, i%nodes))) * (1 - 1.0/(1+exp(-(matrix)((float)i / nodes, i%nodes)))); - } - return matrix; -} - -void Network::feedforward() -{ - for (int i = 0; i < length-1; i++) { - *layers[i+1].contents = (*layers[i].contents) * (*layers[i].weights); - for (int j = 0; j < layers[i+1].contents->rows(); j++) { - // layers[i+1].contents->row(j) += *layers[i+1].bias; TODO ADD ME BACK! - } - // if (i != length-2) { - *layers[i+1].contents = activate(*layers[i+1].contents); - *layers[i+1].dZ = activate_deriv(*layers[i+1].contents); - // } - // else { - // *layers[i + 1].dZ = (layers[i + 1].dZ->array() + 1).matrix(); - // } - // list_net(); - } -} - -void Network::list_net() -{ - for (int i = 0; i < length-1; i++) { - std::cout << " LAYER " << i << "\n\n" << *layers[i].contents << "\n\n AND BIAS\n" << *layers[i].bias << "\n\n W/ WEIGHTS \n" << *layers[i].weights << "\n\n\n"; - } - std::cout << " LAYER " << length-1 << "\n\n" << *layers[length-1].contents << "\n\n AND BIAS\n" << *layers[length-1].bias << "\n\n\n"; -} - -float Network::cost() -{ - float sum = 0; - for (int i = 0; i < layers[length-1].contents->rows(); i++) { - sum += pow((*labels)(i, 0)*100 - (*layers[length-1].contents)(i, 0)*100,2); - } - return (1.0/batch_size) * sum; -} - -void Network::backpropagate() -{ - // std::cout << "\nROUND\n\n\n\n\n\n"; - std::vector<Eigen::MatrixXd> gradients; - std::vector<Eigen::MatrixXd> deltas; - gradients.push_back(((*layers[length-1].contents) - (*labels)).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--) { - // std::cout << gradients[counter-1] << "\n\nTHAT WAS GRADIENT\n\n" <<*layers[i].weights << "\n\nTHAT WAS WEIGHTS\n" - gradients.push_back((gradients[counter-1] * layers[i].weights->transpose()).cwiseProduct(*layers[i].dZ)); - deltas.push_back((*layers[i-1].contents).transpose() * gradients[counter]); - // std::cout << gradients[counter] << "\n\nand\n\n" << *layers[i-1].weights << "\n\nweights\n\n" << deltas[counter] << "\n\ndelta above\n\n\n\n\n"; - counter++; - } - for (int i = 1; i < gradients.size(); i++) { - Eigen::MatrixXd gradient = gradients[i]; - *layers[length-2-i].weights -= learning_rate * (deltas[i]); - } -} - -void Network::update_layer(float* vals, int datalen, int index) -{ - for (int i = 0; i < datalen; i++) { - (*layers[index].contents)((int)i / layers[index].contents->cols(),i%layers[index].contents->cols()) = vals[i]; - } -} - -int Network::next_batch() -{ - FILE* fptr = fopen(fpath, "r"); - char line[1024] = {' '}; - int inputs = layers[0].contents->cols(); - int datalen = batch_size * inputs; - float batch[datalen]; - int label = 100; - for (int i = 0; i < batch_size*batches + 1; i++) { - if (fgets(line, 1024, fptr)==NULL) { - break; - } - if (i >= batches) { - for (int j = 0; j < batch_size; j++) { - fgets(line, 1024, fptr); - sscanf(line, "%f,%f,%f,%f,%i", &batch[0 + (j * inputs)], - &batch[1 + (j * inputs)], &batch[2 + (j * inputs)], - &batch[3 + (j * inputs)], &label); - (*labels)(j, 0) = label; - } - } - } - float* batchptr = batch; - update_layer(batchptr, datalen, 0); - fclose(fptr); - return 0; -} - -int prep_file(char* path) -{ - FILE* rptr = fopen(path, "r"); - char line[1024]; - std::vector<std::string> lines; - int count = 0; - while (fgets(line, 1024, rptr) != NULL) { - lines.emplace_back(line); - count++; - } - std::random_device rd; - std::mt19937 g(rd()); - std::shuffle(lines.begin(), lines.end(), g); - fclose(rptr); - std::ofstream out("./shuffled.txt"); - for (int i = 0; i < lines.size(); i++) { - out << lines[i]; - } - return count; -} - -void Network::test(char* path) -{ - int rounds = 1; - int exit = 0; - float totalcost = -1; - int linecount = prep_file(path); - while (exit == 0) { - FILE* fptr = fopen(fpath, "r"); - char line[1024] = {' '}; - int inputs = layers[0].contents->cols(); - int datalen = batch_size * inputs; - float batch[datalen]; - for (int i = 0; i < batch_size*rounds + 1; i++) { - if (fgets(line, 1024, fptr)==NULL) { - exit = -1; - } - if (i >= rounds) { - for (int j = 0; j < batch_size; j++) { - fgets(line, 1024, fptr); - sscanf(line, "%f,%f,%f,%f,*i", &batch[0 + (j * inputs)], &batch[1 + (j * inputs)], &batch[2 + (j * inputs)], &batch[3 + (j * inputs)]); - } - } - } - float *batchptr = batch; - update_layer(batchptr, datalen, 0); - fclose(fptr); - feedforward(); - list_net(); - // std::cout << *layers[length-1].contents << "\n\nvs\n\n" << *labels << "\n\n"; - totalcost += cost(); - rounds++; - } - std::cout << "TEST COST: " << 1.0/((float) linecount) * totalcost << "\n"; -} - -void demo() -{ - // std::cout << "\n\n\n"; - int linecount = prep_file("./data_banknote_authentication.txt"); - Network net ("./shuffled.txt", 4, 2, 1, 5, 10, 1); - float epoch_cost = 1000; - int epochs = 0; - net.batches= 1; - // net.feedforward(); - // net.backpropagate(); - // std::cout << net.cost() << "\n"; - - while (epochs < 500) { - int linecount = prep_file("./data_banknote_authentication.txt"); - float cost_sum = 0; - for (int i = 0; i < linecount-net.batch_size; i+=net.batch_size) { - net.feedforward(); - net.backpropagate(); - cost_sum += net.cost(); - // std::cout << net.cost() << " as it is " << net.labels[0] << " vs " << *net.layers[net.length-1].contents << "\n"; - net.batches++; - int exit = net.next_batch(); - if (exit == -1) { - break; - } - } - net.batches=1; - epoch_cost = 1.0/((float) linecount) * cost_sum; - printf("EPOCH %i: Cost is %f for %i instances.\n", epochs, epoch_cost, linecount); - epochs++; - } -} - -struct int_pair* map (struct str_pair input_pair) -{ - int_pair* output_pairs = new int_pair[1024]; - int linecount = prep_file("./data_banknote_authentication.txt"); - Network net ("./shuffled.txt", 4, 2, 1, 5, 1, 1); - float epoch_cost = 1000; - int epochs = 0; - net.batches= 1; - - while (epochs < 10) { - int linecount = prep_file("./data_banknote_authentication.txt"); - float cost_sum = 0; - for (int i = 0; i < linecount-net.batch_size; i+=net.batch_size) { - net.feedforward(); - net.backpropagate(); - cost_sum += net.cost(); - net.batches++; - int exit = net.next_batch(); - if (exit == -1) { - break; - } - } - net.batches=1; - epoch_cost = 1.0/((float) linecount) * cost_sum; - printf("EPOCH %i: Cost is %f for %i instances.\n", epochs, epoch_cost, linecount); - epochs++; - } - int rounds = 1; - int exit = 0; - float totalcost = -1; - while (exit == 0) { - FILE* fptr = fopen(input_pair.key, "r"); - char line[1024] = {' '}; - int inputs = net.layers[0].contents->cols(); - int datalen = net.batch_size * inputs; - float batch[datalen]; - for (int i = 0; i < net.batch_size*rounds + 1; i++) { - if (fgets(line, 1024, fptr)==NULL) { - exit = -1; - } - if (i >= rounds) { - for (int j = 0; j < net.batch_size; j++) { - fgets(line, 1024, fptr); - sscanf(line, "%f,%f,%f,%f,%lf", &batch[0 + (j * inputs)], &batch[1 + (j * inputs)], &batch[2 + (j * inputs)], &batch[3 + (j * inputs)], &(*net.labels)(j)); - } - } - } - float *batchptr = batch; - net.update_layer(batchptr, datalen, 0); - net.feedforward(); - for (int i = 0; i < net.batch_size; i++) { - char key[1024]; - sprintf(key, "%i", net.batch_size); - output_pairs[i].key = key; - output_pairs[i].value = net.cost(); - } - output_pairs[net.batch_size].key = (char*)'\0'; - output_pairs[net.batch_size].value = -1; - totalcost += net.cost(); - rounds++; - } - return output_pairs; -} - -int_pair* reduce (int_pair* input_pairs) -{ - int_pair* output_pairs = new int_pair[2]; - int keysum = 0; - int valsum = 0; - for (int i = 0; i < 2; i++) { - std::cout << input_pairs[i].key << " and " << strtol(input_pairs[i].key, NULL, 10) << "\n"; - keysum += strtol(input_pairs[i].key, NULL, 10); - valsum += input_pairs[i].value; - } - char* key; - std::cout << keysum << " and " << valsum << " are SUMS\n"; - sprintf(key, "%d", keysum); - output_pairs[0].key = key; - output_pairs[0].value = valsum; - output_pairs[1].key = (char*) '\0'; - output_pairs[1].value = -1; - return output_pairs; -} - -int main(int argc, char** argv) -{ - begin(argv[2], map, reduce, strtol(argv[1], NULL, 10), 2, argv[3]); -} diff --git a/test.hpp b/test.hpp @@ -1,15 +0,0 @@ -#include "/Users/davidfreifeld/Downloads/eigen-3.3.7/Eigen/Dense" - -// extern "C" -// { -// #include "/Users/davidfreifeld/projects/mapreduce/mapreduce.h" -// } - -#include <vector> -#include <array> -#include <iostream> -#include <string> -#include <cstdio> -#include <fstream> -#include <random> -#include <algorithm>