jacobian

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

commit 6eb4a187ae222308c607f40972ba7a8587b61638
parent b4c6b1e53371a289374da1d2fd1261e7ccb7ec8f
Author: David Freifeld <freifeld.david@gmail.com>
Date:   Fri, 10 Jul 2020 20:09:51 -0700

Reorganized directory.

Diffstat:
MMakefile | 23+++++++++++------------
Dbenchmark.py | 33---------------------------------
Dbpnn.hpp | 82-------------------------------------------------------------------------------
Dcnn.cpp | 250-------------------------------------------------------------------------------
Mexample.cpp | 4++--
Dexample.py | 39---------------------------------------
Dmr_bpnn.cpp | 93-------------------------------------------------------------------------------
Ascripts/benchmark.py | 33+++++++++++++++++++++++++++++++++
Ascripts/example.py | 36++++++++++++++++++++++++++++++++++++
Rkerasdemo.py -> scripts/kerasdemo.py | 0
Ascripts/sweep.yaml | 36++++++++++++++++++++++++++++++++++++
Rbpnn.cpp -> src/bpnn.cpp | 0
Asrc/bpnn.hpp | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rchecks.cpp -> src/checks.cpp | 0
Asrc/cnn.cpp | 250+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/mr_bpnn.cpp | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rmr_bpnn_1.cpp -> src/mr_bpnn_1.cpp | 0
Rmr_bpnn_2.cpp -> src/mr_bpnn_2.cpp | 0
Asrc/utils.cpp | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rutils.hpp -> src/utils.hpp | 0
Dsweep.yaml | 36------------------------------------
Dutils.cpp | 59-----------------------------------------------------------
22 files changed, 603 insertions(+), 606 deletions(-)

diff --git a/Makefile b/Makefile @@ -5,25 +5,24 @@ GEN_FLAGS = -fpic -CXXFLAGS = -shared -std=c++2a -undefined dynamic_lookup `python3 -m pybind11 --includes` mr_bpnn_2.cpp bpnn.cpp utils.cpp mapreduce.a -o mrbpnn`python3-config --extension-suffix` -all: build +CXXFLAGS = -shared -std=c++2a -undefined dynamic_lookup `python3 -m pybind11 --includes` ./src/mr_bpnn_2.cpp ./src/bpnn.cpp ./src/utils.cpp mapreduce.a -o mrbpnn`python3-config --extension-suffix` + +all: compile debug: $(GEN_FLAGS) = -Wall -U NDEBUG -debug: - ls fast: CXXFLAGS += $(GEN_FLAGS) -O3 -fast: build +fast: compile -faster: CXXFLAGS = -shared -std=c++2a -undefined dynamic_lookup `python3 -m pybind11 --includes` mr_bpnn_2.cpp bpnn.cpp utils.cpp mapreduce.a ${MKLROOT}/lib/libmkl_intel_ilp64.a ${MKLROOT}/lib/libmkl_intel_thread.a ${MKLROOT}/lib/libmkl_core.a -liomp5 -lpthread -lm -ldl -o mrbpnn`python3-config --extension-suffix` -O3 -mavx -mfma -march=native -mfpmath=sse -fno-pic -DMKL_ILP64 -I${MKLROOT}/include -D EIGEN_USE_MKL_ALL -D NDEBUG -faster: build +faster: CXXFLAGS = -shared -std=c++2a -undefined dynamic_lookup `python3 -m pybind11 --includes` ./src/mr_bpnn_2.cpp ./src/bpnn.cpp ./src/utils.cpp mapreduce.a ${MKLROOT}/lib/libmkl_intel_ilp64.a ${MKLROOT}/lib/libmkl_intel_thread.a ${MKLROOT}/lib/libmkl_core.a -liomp5 -lpthread -lm -ldl -o mrbpnn`python3-config --extension-suffix` -O3 -mavx -mfma -march=native -mfpmath=sse -fno-pic -DMKL_ILP64 -I${MKLROOT}/include -D EIGEN_USE_MKL_ALL -D NDEBUG +faster: compile -tradeoffs: CXXFLAGS = -shared -std=c++2a -undefined dynamic_lookup `python3 -m pybind11 --includes` mr_bpnn_2.cpp bpnn.cpp utils.cpp mapreduce.a ${MKLROOT}/lib/libmkl_intel_ilp64.a ${MKLROOT}/lib/libmkl_intel_thread.a ${MKLROOT}/lib/libmkl_core.a -liomp5 -lpthread -lm -ldl -o mrbpnn`python3-config --extension-suffix` -O3 -mavx -mfma -march=native -mfpmath=sse -DMKL_ILP64 -I${MKLROOT}/include -qopenmp -fno-pic -qopt-calloc -qopt-prefetch -unroll-aggressive -qopt-calloc -use-intel-optimized-headers -ffast-math -no-prec-div -no-prec-sqrt -fimf-precision=low -fast-transcendentals -D EIGEN_USE_MKL_ALL -D NDEBUG #-qopt-report=5 -qopt-report-file=report -tradeoffs: build +tradeoffs: CXXFLAGS = -shared -std=c++2a -undefined dynamic_lookup `python3 -m pybind11 --includes` ./src/mr_bpnn_2.cpp ./src/bpnn.cpp ./src/utils.cpp mapreduce.a ${MKLROOT}/lib/libmkl_intel_ilp64.a ${MKLROOT}/lib/libmkl_intel_thread.a ${MKLROOT}/lib/libmkl_core.a -liomp5 -lpthread -lm -ldl -o mrbpnn`python3-config --extension-suffix` -O3 -mavx -mfma -march=native -mfpmath=sse -DMKL_ILP64 -I${MKLROOT}/include -qopenmp -fno-pic -qopt-calloc -qopt-prefetch -unroll-aggressive -qopt-calloc -use-intel-optimized-headers -ffast-math -no-prec-div -no-prec-sqrt -fimf-precision=low -fast-transcendentals -D EIGEN_USE_MKL_ALL -D NDEBUG #-qopt-report=5 -qopt-report-file=report +tradeoffs: compile reckless: CXXFLAGS = -O3 -reckless: build +reckless: compile -build: - g++ $(CXXFLAGS) +compile: + g++ $(CXXFLAGS) && rm ./mrbpnn/mrbpnn.cpython-37m-darwin.so ; cp ./mrbpnn.cpython-37m-darwin.so ./mrbpnn/mrbpnn.cpython-37m-darwin.s ; rm ./scripts/mrbpnn.cpython-37m-darwin.so ; cp ./mrbpnn.cpython-37m-darwin.so ./scripts/mrbpnn.cpython-37m-darwin.so diff --git a/benchmark.py b/benchmark.py @@ -1,33 +0,0 @@ -import mrbpnn -import matplotlib.pyplot as plt -import numpy -import time - -def bench(batch_sz, layers): - init = time.time() - net = mrbpnn.Network("./data_banknote_authentication.txt", batch_sz, 0.0155, 0.03, 0.1, 0.9) - net.add_layer(4, "linear") - for i in range(layers): - net.add_layer(5, "relu") - net.add_layer(1, "resig") - net.initialize() - initend = time.time() - for i in range(1): - net.train() - end = time.time() - return (end-init) - -x = [] -y = [] -i = 1 -while(i < 125): - print(i) - y.append(bench(i, 1)) - x.append(i) - i+=1; -plt.plot(x,y, label = "Jacobian (Sequential)") - -# plt.plot(otherlist, [2.3994078636169434, 1.2735769748687744, 1.0030598640441895, 0.8972160816192627, 0.801548957824707, 0.752018928527832, 0.7073678970336914, 0.6857280731201172, 0.6707980632781982, 0.6421489715576172, 0.6614980697631836, 0.6403779983520508, 0.7251319885253906, 0.6796879768371582, 0.6601080894470215, 0.6711599826812744, 0.6432759761810303, 0.6491389274597168, 0.6762490272521973, 0.6859049797058105, 0.7067179679870605, 0.7142889499664307, 0.7258059978485107, 0.7868969440460205, 0.7326970100402832, 0.7365641593933105, 0.7576079368591309, 0.7772500514984131, 0.8062641620635986, 0.7768490314483643, 0.8253629207611084, 0.8264601230621338, 0.8459320068359375, 0.9670729637145996, 0.8388969898223877, 0.9129719734191895, 0.9009649753570557, 0.8916170597076416, 0.8926799297332764, 0.9171609878540039, 0.9242072105407715, 0.9534740447998047, 0.947465181350708, 0.9723358154296875, 1.018247127532959, 1.1208629608154297, 1.014026165008545, 1.034980058670044, 1.0626468658447266, 1.080394983291626, 1.0627479553222656, 1.0839190483093262, 1.0938241481781006, 1.127730131149292, 1.1265759468078613, 1.136888027191162, 1.140428066253662, 1.1712510585784912, 1.206390142440796, 1.2087180614471436, 1.4066569805145264, 1.2425589561462402, 1.280066967010498, 1.2891559600830078, 1.3243582248687744, 1.3152379989624023], label="Keras") -plt.legend() -plt.show() -print(y) diff --git a/bpnn.hpp b/bpnn.hpp @@ -1,82 +0,0 @@ -#ifndef BPNN_H -#define BPNN_H - -#include <Eigen/Dense> - -#include "../mapreduce/mapreduce.hpp" - -#include <vector> -#include <array> -#include <iostream> -#include <string> -#include <cstdio> -#include <fstream> -#include <random> -#include <algorithm> - -class Layer { -public: - Eigen::MatrixXf* contents; - Eigen::MatrixXf* weights; - Eigen::MatrixXf* bias; - Eigen::MatrixXf* dZ; - std::vector<Eigen::MatrixXf> prev_updates; - std::function<float(float)> activation; - std::function<float(float)> activation_deriv; - char activation_str[1024]; - - Layer(int rows, int columns); - Layer(float* vals, int rows, int columns); - void init_weights(Layer next); -}; - -class Network { -public: - FILE* data; - int instances; - int test_instances; - - std::vector<Layer> layers; - int length; - int t; - - float epoch_acc; - float epoch_cost; - float val_acc; - float val_cost; - float learning_rate; - float bias_lr; - float lambda; - int batch_size; - int batches; - - Eigen::MatrixXf* labels; - - Network(char* path, int batch_sz, float learn_rate, float bias_rate, float l, float ratio); - void add_layer(int nodes, char* activation); - void initialize(); - void update_layer(float* vals, int datalen, int index); - void set_activation(int index, std::function<float(float)> custom, std::function<float(float)> custom_deriv); - - void feedforward(); - void list_net(); - - float cost(); - float accuracy(); - void backpropagate(); - int next_batch(); - float test(char* path); - void train(); - void checks(); - - float get_acc(); - float get_cost(); - float get_val_acc(); - float get_val_cost(); -}; - -void demo(int total_epochs); -int prep_file(char* path, char* out_path); -int split_file(char* path, int lines, float ratio); - -#endif /* MODULE_H */ diff --git a/cnn.cpp b/cnn.cpp @@ -1,250 +0,0 @@ -#include "bpnn.hpp" -#include "utils.hpp" - -#define LARGE_NUM 1000000 // Remove me. - -class ConvLayer -{ -public: - int stride_len; - int padding; - Eigen::MatrixXd* input; - Eigen::MatrixXd* kernel; - Eigen::MatrixXd* output; - double bias; - - ConvLayer(int x, int y, int stride, int kernel_size, int pad); - void convolute(); - void set_input(Eigen::MatrixXd* matrix); -}; - -ConvLayer::ConvLayer(int x, int y, int stride, int kern_size, int pad) -{ - padding = pad; - pad*=2; - stride_len = stride; - input = new Eigen::MatrixXd (x+pad,y+pad); - for (int i = 0; i < (x+pad)*(y+pad); i++) { - (*input)((int)i / (y+pad),i%(y+pad)) = 0; - } - kernel = new Eigen::MatrixXd (kern_size, kern_size); - for (int i = 0; i < kern_size*kern_size; i++) { - (*kernel)((int)i / kern_size,i%kern_size) = (double) rand() / RAND_MAX; - } - output = new Eigen::MatrixXd ((x-kern_size+1+pad/stride_len), (y-kern_size+1+pad/stride_len)); // We're using valid padding for now. - for (int i = 0; i < (x-kern_size+1+pad/stride_len)*(y-kern_size+1+pad/stride_len); i++) { - (*output)((int)i / (y-kern_size+1+pad/stride_len),i%(y-kern_size+1+pad/stride_len)) = 0; - } - bias = 0; -}; - -void ConvLayer::convolute() -{ - for (int i = 0; i < input->cols() - kernel->cols()+1; i+=stride_len) { - for (int j = 0; j < input->rows() - kernel->rows()+1; j+=stride_len) { - (*output)(j, i) = (*kernel * (input->block(j, i, kernel->rows(), kernel->cols()))).sum(); - } - } - *output = (output->array() + bias).matrix(); -} - -void ConvLayer::set_input(Eigen::MatrixXd* matrix) -{ - input->block(padding, padding, matrix->rows(), matrix->cols()) = *matrix; -} - -class PoolingLayer -{ -public: - int stride_len; - int padding; - Eigen::MatrixXd* input; - Eigen::MatrixXd* kernel; - Eigen::MatrixXd* output; - - void pool(); - PoolingLayer(int x, int y, int stride, int kern_size, int pad); -}; - -// Will eventually be different from ConvLayer -PoolingLayer::PoolingLayer(int x, int y, int stride, int kern_size, int pad) -{ - padding = pad; - stride_len = stride; - kernel = new Eigen::MatrixXd (kern_size, kern_size); - for (int i = 0; i < kern_size*kern_size; i++) { - (*kernel)((int)i / kern_size,i%kern_size) = (double) rand()/RAND_MAX; - } - output = new Eigen::MatrixXd (x-kern_size+1, y-kern_size+1); - for (int i = 0; i < (x-kern_size+1)*(y-kern_size+1); i++) { - (*output)((int)i / (y-kern_size+1),i%(y-kern_size+1)) = (double) rand()/RAND_MAX; - } -}; - -void PoolingLayer::pool() -{ - // It doesn't look like anything better than O(n^4) is doable for this as kernel needs to go through matrix and you need to index kernel. LOOK INTO ME!! - float maxnum = -LARGE_NUM; - for (int i = 0; i < input->cols() - kernel->cols(); i+=stride_len) { - for (int j = 0; j < input->rows() - kernel->rows(); j+=stride_len) { - for (int k = 0; k < kernel->cols(); k++) { - for (int l = 0; l < kernel->rows(); l++) { - if ((input->block(j, i, kernel->rows(), kernel->cols()))(l, k) > maxnum) { - maxnum = (input->block(j, i, kernel->rows(), kernel->cols()))(l, k); - } - } - } - } - } -} - -class ConvNet : public Network -{ -public: - int preprocess_length; - - std::vector<ConvLayer> conv_layers; - std::vector<PoolingLayer> pool_layers; - - ConvNet(char* path, int batch_sz, float learn_rate, float bias_rate, float ratio); - void list_net(); - void process(); // Runs the convolutional and pooling layers. - void backpropagate(); - void add_conv_layer(int x, int y, int stride, int kern_size, int pad); - void add_pool_layer(int x, int y, int stride, int kern_size, int pad); - void set_label(Eigen::MatrixXd newlabels); - void initialize(); -}; - -ConvNet::ConvNet(char* path, int batch_sz, float learn_rate, float bias_rate, float ratio) : Network(path, batch_sz, learn_rate, bias_rate, ratio) -{ - preprocess_length = 0; - labels = new Eigen::MatrixXd (batch_sz, 1); -} - -void ConvNet::add_conv_layer(int x, int y, int stride, int kern_size, int pad) -{ - preprocess_length+=1; - conv_layers.emplace_back(x,y,stride,kern_size,pad); -} - -// May make this inaccessible to user code and just have it called from add_conv_layer as pooling is basically always paired with conv. -void ConvNet::add_pool_layer(int x, int y, int stride, int kern_size, int pad) -{ - pool_layers.emplace_back(x,y,stride,kern_size,pad); -} - -void ConvNet::initialize() -{ - for (int i = 0; i < length-1; i++) { - layers[i].init_weights(layers[i+1]); - } -} - -void ConvNet::process() -{ - // std::cout << preprocess_length << "\n"; - // Assumes pooling is immediately after any conv layer. - for (int i = 0; i < preprocess_length-1; i++) { - conv_layers[i].convolute(); - pool_layers[i].input = conv_layers[i].output; - pool_layers[i].pool(); - conv_layers[i+1].input = pool_layers[i].output; - } - conv_layers[preprocess_length-1].convolute(); - //pool_layers[preprocess_length-1].input = conv_layers[preprocess_length-1].output; - //pool_layers[preprocess_length-1].pool(); - // std::cout << "Output:\n" << *pool_layers[preprocess_length-1].output << "\n\n"; - Eigen::Map<Eigen::RowVectorXd> flattened (conv_layers[preprocess_length-1].output->data(), conv_layers[preprocess_length-1].output->size()); - // std::cout << "Flattened:\n" << flattened << "\n\n"; - for (int i = 0; i < flattened.cols(); i++) { - (*layers[0].contents)(0, i) = flattened[i]; - } -} - -void ConvNet::set_label(Eigen::MatrixXd newlabels) -{ - *labels = newlabels; -} - -void ConvNet::list_net() -{ - for (int i = 0; i < preprocess_length; i++) { - std::cout << "-----------------------\nCONVOLUTIONAL LAYER " << i << "\n-----------------------\n\n\u001b[31mGENERAL INFO:\x1B[0;37m\nStride: " << conv_layers[i].stride_len << "\nPadding: " << conv_layers[i].padding << "\n\n\u001b[31mINPUT:\x1B[0;37m\n" << *conv_layers[i].input << "\n\n\u001b[31mKERNEL:\x1B[0;37m\n" << *conv_layers[i].kernel << "\n\n\u001b[31mOUTPUT:\x1B[0;37m\n" << *conv_layers[i].output << "\n\n\u001b[31mBIAS:\x1B[0;37m\n" << conv_layers[i].bias << "\n\n\n"; - //std::cout << "-----------------------\nPOOLING LAYER " << i << "\n-----------------------\n\n\u001b[31mGENERAL INFO:\x1B[0;37m\nStride: " << pool_layers[i].stride_len << "\nPadding: " << conv_layers[i].padding << "\n\n\u001b[31mINPUT:\x1B[0;37m\n" << *pool_layers[i].input << "\n\n\u001b[31mKERNEL:\x1B[0;37m\n-" << *pool_layers[i].kernel << "\n\n\u001b[31mOUTPUT:\x1B[0;37m\n" << *pool_layers[i].output << "\n\n\n"; - } - std::cout << "-----------------------\nINPUT LAYER (LAYER 0)\n-----------------------\n\n\u001b[31mGENERAL INFO:\x1B[0;37m\nActivation Function: " << layers[0].activation_str << "\n\n\u001b[31mACTIVATIONS:\x1B[0;37m\n" << *layers[0].contents << "\n\n\u001b[31mWEIGHTS:\x1B[0;37m\n" << *layers[0].weights << "\n\n\u001b[31mBIASES:\x1B[0;37m\n" << *layers[0].bias << "\n\n\n"; - 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"; -} - -void ConvNet::backpropagate() -{ - std::vector<Eigen::MatrixXd> gradients; - std::vector<Eigen::MatrixXd> deltas; - Eigen::MatrixXd 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--) { - //std::cout << "--GRAD---\n" << gradients[counter-1] << "\n\n" << layers[i].weights->transpose() << "\n\n" << *layers[i].dZ << "\n\n"; - gradients.push_back((gradients[counter-1] * layers[i].weights->transpose()).cwiseProduct(*layers[i].dZ)); - //std::cout << "---DELTA---\n" << gradients[counter] << "\n\n" << layers[i].weights->transpose() << "\n\n" << *layers[i].dZ << "\n\n"; - deltas.push_back(layers[i-1].contents->transpose() * gradients[counter]); - counter++; - } - gradients.push_back((gradients[gradients.size()-1] * layers[0].weights->transpose()).cwiseProduct(*layers[0].dZ)); - for (int i = 0; i < length-1; i++) { - *layers[length-2-i].weights -= learning_rate * deltas[i]; - *layers[length-1-i].bias -= bias_lr * gradients[i]; - } - // list_net(); - // std::cout << "GRADIENT LIST\n"; - // for (int i = 0; i < gradients.size(); i++) { - // std::cout << gradients[i] << "\n\n"; - // } - Eigen::Map<Eigen::MatrixXd> reshaped(gradients[gradients.size()-1].data(), conv_layers[conv_layers.size()-1].output->rows(),conv_layers[conv_layers.size()-1].output->cols()); - gradients[gradients.size()-1] = reshaped; - //std::cout << gradients[gradients.size()-1].cols() << " " << conv_layers[0].input->cols() << " " << conv_layers[0].input->cols() - gradients[length-1].cols()+1 << "\n"; - for (int i = 0; i < conv_layers[0].input->cols() - gradients[length-1].cols()+1; i+=conv_layers[0].stride_len) { - for (int j = 0; j < conv_layers[0].input->rows() - gradients[length-1].rows()+1; j+=conv_layers[0].stride_len) { - (*conv_layers[0].kernel)(j, i) -= (gradients[length-1] * (conv_layers[0].input->block(j, i, gradients[length-1].rows(), gradients[length-1].cols()))).sum(); - } - } - conv_layers[0].bias -= gradients[gradients.size()-1].sum(); -} - -int main() -{ - ConvNet net ("./data_banknote_authentication.txt", 1, 0.05, 0.01, 0.9); - Eigen::MatrixXd labels (1,1); - labels << 1; - net.set_label(labels); - net.add_conv_layer(8,8,1,4,0); - //net.add_pool_layer(5,5,1,2,0); - net.add_layer(25, "linear"); - net.add_layer(5, "relu"); - net.add_layer(1, "resig"); - net.initialize(); - Eigen::MatrixXd* input = new Eigen::MatrixXd (8,8); - *input << - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,1,1,1,1,0,0, - 0,0,1,1,1,1,0,0, - 0,0,1,1,1,1,0,0, - 0,0,1,1,1,1,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0; - net.conv_layers[0].set_input(input); - net.process(); - for (int i = 0; i < 10; i++) { - net.feedforward(); - net.backpropagate(); - std::cout << *net.layers[net.layers.size()-1].contents << " <--- ACTIVATION\n"; - } - net.list_net(); - // net.list_net(); -} diff --git a/example.cpp b/example.cpp @@ -1,5 +1,5 @@ -#include "bpnn.hpp" -#include "utils.hpp" +#include "./src/bpnn.hpp" +#include "./src/utils.hpp" #include "unistd.h" #include <ctime> diff --git a/example.py b/example.py @@ -1,39 +0,0 @@ -import sys -sys.path.append("/Users/davidfreifeld/projects/Jacobian/") -print(sys.path) -import mrbpnn -import numpy as np -import matplotlib.pyplot as plt -import numpy -import time -import wandb - -data_split = 0.75 - -hyperparameter_defaults = dict(batch_size = 10, - hidden_layers = 1, - epochs = 50, - learning_rate = 0.0155, - bias_lr = 0.03, - activation = "lecun_tanh", - neurons = 10, - l = 0.5) - -wandb.init(project="jacobian", config=hyperparameter_defaults) -config = wandb.config - -init = time.time() -net = mrbpnn.Network("./data_banknote_authentication.txt", config.batch_size, config.learning_rate, config.bias_lr, config.l, data_split) -net.add_layer(4, "linear") -for i in range(config.hidden_layers): - net.add_layer(config.neurons, config.activation) -net.add_layer(1, "resig") -net.initialize() - -for i in range(config.epochs): - net.train() - wandb.log({'accuracy': net.get_acc(), 'cost': net.get_cost(), 'val_accuracy': net.get_val_acc(), 'val_cost': net.get_val_cost()}) -end = time.time() - -wandb.run.summary["time"] = end-init -wandb.save('jacobian.h5') diff --git a/mr_bpnn.cpp b/mr_bpnn.cpp @@ -1,93 +0,0 @@ -#include "bpnn.hpp" -#include "utils.hpp" - -class NetworkArray -{ -public: - std::function<struct pair*(struct pair*)> map; - std::function<struct pair*(struct pair*)> reduce; - std::function<void(char*)> translate; - - NetworkArray(char* configuration, std::function<Network*(void)> setup, int epochs); - void start_array(char* data, int m, int length, char* ip, int r); -}; - -NetworkArray::NetworkArray(char* configuration, std::function<Network*(void)> setup, int epochs) -{ - map = [setup, epochs](struct pair* input_pair) -> struct pair* - { - printf("Recieved %p %p in form of %p\n", input_pair->key, input_pair->value, input_pair); - printf("%s %p\n", (char*)input_pair->key, input_pair->value); - char* path = new char[100]; - strcpy(path, (char*)input_pair->key); - //strcat(path, "_shuf"); - //int linecount = prep_file((char*)input_pair.key, path); - // Network* net = setup(); - // net->train(epochs); - struct pair* output = new struct pair; - //char* key = new char[100]; - //strcpy(key, path); - output[0].key = 0x0; - output[0].value = 0x0; - return output; - }; - reduce = [](struct pair* input_pairs) -> struct pair* - { - struct pair* output = new struct pair[6]; - for (int i = 0; input_pairs[i].key != 0x0; i++) { - float* acc = new float; - *acc = ((Network*)input_pairs[i].value)->test("./test.txt"); - output[i].key = input_pairs[i].key; - output[i].value = acc; - } - return output; - }; - translate = [](char* path) -> void - { - FILE* rptr = fopen(path, "r"); - FILE* wptr = fopen("./translated", "w"); - char* line = new char[MAXLINE]; - char* newline = new char[MAXLINE]; - while (fgets(line, MAXLINE, rptr) != NULL) { - void* addr1; - void* addr2; - sscanf(line, "%p %p", &addr1, &addr2); - sprintf(newline, "%s %f", (char*)addr1, *(float*)addr2); - int batch_num = strtol((char*)addr1, NULL, 10); - fprintf(wptr, "%s %f\n",(char*)addr1, *(float*)addr2); - } - fclose(rptr); - fclose(wptr); - free(newline); - free(line); - }; -} - -void NetworkArray::start_array(char* data, int m, int length, char* ip, int r) -{ - begin(data, map, reduce, translate, m, length, ip, r); -} - -Network* setup() -{ - Network* net = new Network ("./data_banknote_authentication.txt", 10, 0.01, 0.001, 0.9); - net->add_layer(4, "linear"); - net->add_layer(5, "sigmoid"); - net->set_activation(1, lecun_tanh, lecun_tanh_deriv); - net->add_layer(1, "resig"); - net->initialize(); - return net; -} - -int main() -{ - NetworkArray netarray ("Train", setup, 1); - // char* path = "./extra.txt"; - // char* msg = "junk"; - //struct pair testing = {(void*)path, (void*)msg}; - // printf("SENDING %p %p (part of %p)\n", testing.key, testing.value, &testing); - //netarray.map(testing); - netarray.start_array("./extra.txt", 5, 1, "98.33.105.140", 1); - return 0; -} - diff --git a/scripts/benchmark.py b/scripts/benchmark.py @@ -0,0 +1,33 @@ +import mrbpnn +import matplotlib.pyplot as plt +import numpy +import time + +def bench(batch_sz, layers): + init = time.time() + net = mrbpnn.Network("../data_banknote_authentication.txt", batch_sz, 0.0155, 0.03, 0, 0.9) + net.add_layer(4, "linear") + for i in range(layers): + net.add_layer(5, "relu") + net.add_layer(1, "resig") + net.initialize() + initend = time.time() + for i in range(1): + net.train() + end = time.time() + return (end-init) + +x = [] +y = [] +i = 1 +while(i < 125): + print(i) + y.append(bench(i, 1)) + x.append(i) + i+=1; +plt.plot(x,y, label = "Jacobian (Sequential)") + +# plt.plot(otherlist, [2.3994078636169434, 1.2735769748687744, 1.0030598640441895, 0.8972160816192627, 0.801548957824707, 0.752018928527832, 0.7073678970336914, 0.6857280731201172, 0.6707980632781982, 0.6421489715576172, 0.6614980697631836, 0.6403779983520508, 0.7251319885253906, 0.6796879768371582, 0.6601080894470215, 0.6711599826812744, 0.6432759761810303, 0.6491389274597168, 0.6762490272521973, 0.6859049797058105, 0.7067179679870605, 0.7142889499664307, 0.7258059978485107, 0.7868969440460205, 0.7326970100402832, 0.7365641593933105, 0.7576079368591309, 0.7772500514984131, 0.8062641620635986, 0.7768490314483643, 0.8253629207611084, 0.8264601230621338, 0.8459320068359375, 0.9670729637145996, 0.8388969898223877, 0.9129719734191895, 0.9009649753570557, 0.8916170597076416, 0.8926799297332764, 0.9171609878540039, 0.9242072105407715, 0.9534740447998047, 0.947465181350708, 0.9723358154296875, 1.018247127532959, 1.1208629608154297, 1.014026165008545, 1.034980058670044, 1.0626468658447266, 1.080394983291626, 1.0627479553222656, 1.0839190483093262, 1.0938241481781006, 1.127730131149292, 1.1265759468078613, 1.136888027191162, 1.140428066253662, 1.1712510585784912, 1.206390142440796, 1.2087180614471436, 1.4066569805145264, 1.2425589561462402, 1.280066967010498, 1.2891559600830078, 1.3243582248687744, 1.3152379989624023], label="Keras") +plt.legend() +plt.show() +print(y) diff --git a/scripts/example.py b/scripts/example.py @@ -0,0 +1,36 @@ +import mrbpnn +import numpy as np +import matplotlib.pyplot as plt +import numpy +import time +import wandb + +data_split = 0.75 + +hyperparameter_defaults = dict(batch_size = 10, + hidden_layers = 1, + epochs = 50, + learning_rate = 0.0155, + bias_lr = 0.03, + activation = "lecun_tanh", + neurons = 10, + l = 0) + +wandb.init(project="jacobian", config=hyperparameter_defaults) +config = wandb.config + +init = time.time() +net = mrbpnn.Network("../data_banknote_authentication.txt", config.batch_size, config.learning_rate, config.bias_lr, config.l, data_split) +net.add_layer(4, "linear") +for i in range(config.hidden_layers): + net.add_layer(config.neurons, config.activation) +net.add_layer(1, "resig") +net.initialize() + +for i in range(config.epochs): + net.train() + wandb.log({'accuracy': net.get_acc(), 'cost': net.get_cost(), 'val_accuracy': net.get_val_acc(), 'val_cost': net.get_val_cost()}) +end = time.time() + +wandb.run.summary["time"] = end-init +wandb.save('jacobian.h5') diff --git a/kerasdemo.py b/scripts/kerasdemo.py diff --git a/scripts/sweep.yaml b/scripts/sweep.yaml @@ -0,0 +1,36 @@ +program: example.py +method: bayes +metric: + name: val_cost + goal: minimize +parameters: + epochs: + distribution: int_uniform + min: 25 + max: 100 + batch_size: + distribution: int_uniform +p min: 5 + max: 200 + hidden_layers: + distribution: int_uniform + min: 1 + max: 6 + bias_lr: + distribution: uniform + min: 0.0015 + max: 0.06 + neurons: + distribution: int_uniform + min: 2 + max: 40 + activation: + distribution: categorical + values: + - lecun_tanh + - relu + - sigmoid + learning_rate: + distribution: uniform + min: 0.001 + max: 0.5 diff --git a/bpnn.cpp b/src/bpnn.cpp diff --git a/src/bpnn.hpp b/src/bpnn.hpp @@ -0,0 +1,82 @@ +#ifndef BPNN_H +#define BPNN_H + +#include <Eigen/Dense> + +#include "../../mapreduce/mapreduce.hpp" + +#include <vector> +#include <array> +#include <iostream> +#include <string> +#include <cstdio> +#include <fstream> +#include <random> +#include <algorithm> + +class Layer { +public: + Eigen::MatrixXf* contents; + Eigen::MatrixXf* weights; + Eigen::MatrixXf* bias; + Eigen::MatrixXf* dZ; + std::vector<Eigen::MatrixXf> prev_updates; + std::function<float(float)> activation; + std::function<float(float)> activation_deriv; + char activation_str[1024]; + + Layer(int rows, int columns); + Layer(float* vals, int rows, int columns); + void init_weights(Layer next); +}; + +class Network { +public: + FILE* data; + int instances; + int test_instances; + + std::vector<Layer> layers; + int length; + int t; + + float epoch_acc; + float epoch_cost; + float val_acc; + float val_cost; + float learning_rate; + float bias_lr; + float lambda; + int batch_size; + int batches; + + Eigen::MatrixXf* labels; + + Network(char* path, int batch_sz, float learn_rate, float bias_rate, float l, float ratio); + void add_layer(int nodes, char* activation); + void initialize(); + void update_layer(float* vals, int datalen, int index); + void set_activation(int index, std::function<float(float)> custom, std::function<float(float)> custom_deriv); + + void feedforward(); + void list_net(); + + float cost(); + float accuracy(); + void backpropagate(); + int next_batch(); + float test(char* path); + void train(); + void checks(); + + float get_acc(); + float get_cost(); + float get_val_acc(); + float get_val_cost(); +}; + +void demo(int total_epochs); +int prep_file(char* path, char* out_path); +int split_file(char* path, int lines, float ratio); + +#endif /* MODULE_H */ diff --git a/checks.cpp b/src/checks.cpp diff --git a/src/cnn.cpp b/src/cnn.cpp @@ -0,0 +1,250 @@ +#include "bpnn.hpp" +#include "utils.hpp" + +#define LARGE_NUM 1000000 // Remove me. + +class ConvLayer +{ +public: + int stride_len; + int padding; + Eigen::MatrixXd* input; + Eigen::MatrixXd* kernel; + Eigen::MatrixXd* output; + double bias; + + ConvLayer(int x, int y, int stride, int kern_x, int kern_y, int pad); + void convolute(); + void set_input(Eigen::MatrixXd* matrix); +}; + +ConvLayer::ConvLayer(int x, int y, int stride, int kern_x, int kern_y, int pad) +{ + padding = pad; + pad*=2; + stride_len = stride; + input = new Eigen::MatrixXd (x+pad,y+pad); + for (int i = 0; i < (x+pad)*(y+pad); i++) { + (*input)((int)i / (y+pad),i%(y+pad)) = 0; + } + kernel = new Eigen::MatrixXd (kern_size, kern_size); + for (int i = 0; i < kern_size*kern_size; i++) { + (*kernel)((int)i / kern_size,i%kern_size) = (double) rand() / RAND_MAX; + } + output = new Eigen::MatrixXd ((x-kern_size+1+pad/stride_len), (y-kern_size+1+pad/stride_len)); // We're using valid padding for now. + for (int i = 0; i < (x-kern_y+1+pad/stride_len)*(y-kern_x+1+pad/stride_len); i++) { + (*output)((int)i / (y-kern_y+1+pad/stride_len),i%(y-kern_y+1+pad/stride_len)) = 0; + } + bias = 0; +}; + +void ConvLayer::convolute() +{ + for (int i = 0; i < input->cols() - kernel->cols()+1; i+=stride_len) { + for (int j = 0; j < input->rows() - kernel->rows()+1; j+=stride_len) { + (*output)(j, i) = (*kernel * (input->block(j, i, kernel->rows(), kernel->cols()))).sum(); + } + } + *output = (output->array() + bias).matrix(); +} + +void ConvLayer::set_input(Eigen::MatrixXd* matrix) +{ + input->block(padding, padding, matrix->rows(), matrix->cols()) = *matrix; +} + +class PoolingLayer +{ +public: + int stride_len; + int padding; + Eigen::MatrixXd* input; + Eigen::MatrixXd* kernel; + Eigen::MatrixXd* output; + + void pool(); + PoolingLayer(int x, int y, int stride, int kern_size, int pad); +}; + +// Will eventually be different from ConvLayer +PoolingLayer::PoolingLayer(int x, int y, int stride, int kern_size, int pad) +{ + padding = pad; + stride_len = stride; + kernel = new Eigen::MatrixXd (kern_size, kern_size); + for (int i = 0; i < kern_size*kern_size; i++) { + (*kernel)((int)i / kern_size,i%kern_size) = (double) rand()/RAND_MAX; + } + output = new Eigen::MatrixXd (x-kern_size+1, y-kern_size+1); + for (int i = 0; i < (x-kern_size+1)*(y-kern_size+1); i++) { + (*output)((int)i / (y-kern_size+1),i%(y-kern_size+1)) = (double) rand()/RAND_MAX; + } +}; + +void PoolingLayer::pool() +{ + // It doesn't look like anything better than O(n^4) is doable for this as kernel needs to go through matrix and you need to index kernel. LOOK INTO ME!! + float maxnum = -LARGE_NUM; + for (int i = 0; i < input->cols() - kernel->cols(); i+=stride_len) { + for (int j = 0; j < input->rows() - kernel->rows(); j+=stride_len) { + for (int k = 0; k < kernel->cols(); k++) { + for (int l = 0; l < kernel->rows(); l++) { + if ((input->block(j, i, kernel->rows(), kernel->cols()))(l, k) > maxnum) { + maxnum = (input->block(j, i, kernel->rows(), kernel->cols()))(l, k); + } + } + } + } + } +} + +class ConvNet : public Network +{ +public: + int preprocess_length; + + std::vector<ConvLayer> conv_layers; + std::vector<PoolingLayer> pool_layers; + + ConvNet(char* path, int batch_sz, float learn_rate, float bias_rate, float ratio); + void list_net(); + void process(); // Runs the convolutional and pooling layers. + void backpropagate(); + void add_conv_layer(int x, int y, int stride, int kern_x, int kern_y int pad); + void add_pool_layer(int x, int y, int stride, int kern_x, int kern_y, int pad); + void set_label(Eigen::MatrixXd newlabels); + void initialize(); +}; + +ConvNet::ConvNet(char* path, int batch_sz, float learn_rate, float bias_rate, float ratio) : Network(path, batch_sz, learn_rate, bias_rate, ratio) +{ + preprocess_length = 0; + labels = new Eigen::MatrixXd (batch_sz, 1); +} + +void ConvNet::add_conv_layer(int x, int y, int stride, int kern_size, int pad) +{ + preprocess_length+=1; + conv_layers.emplace_back(x,y,stride,kern_size,pad); +} + +// May make this inaccessible to user code and just have it called from add_conv_layer as pooling is basically always paired with conv. +void ConvNet::add_pool_layer(int x, int y, int stride, int kern_size, int pad) +{ + pool_layers.emplace_back(x,y,stride,kern_size,pad); +} + +void ConvNet::initialize() +{ + for (int i = 0; i < length-1; i++) { + layers[i].init_weights(layers[i+1]); + } +} + +void ConvNet::process() +{ + // std::cout << preprocess_length << "\n"; + // Assumes pooling is immediately after any conv layer. + for (int i = 0; i < preprocess_length-1; i++) { + conv_layers[i].convolute(); + pool_layers[i].input = conv_layers[i].output; + pool_layers[i].pool(); + conv_layers[i+1].input = pool_layers[i].output; + } + conv_layers[preprocess_length-1].convolute(); + //pool_layers[preprocess_length-1].input = conv_layers[preprocess_length-1].output; + //pool_layers[preprocess_length-1].pool(); + // std::cout << "Output:\n" << *pool_layers[preprocess_length-1].output << "\n\n"; + Eigen::Map<Eigen::RowVectorXd> flattened (conv_layers[preprocess_length-1].output->data(), conv_layers[preprocess_length-1].output->size()); + // std::cout << "Flattened:\n" << flattened << "\n\n"; + for (int i = 0; i < flattened.cols(); i++) { + (*layers[0].contents)(0, i) = flattened[i]; + } +} + +void ConvNet::set_label(Eigen::MatrixXd newlabels) +{ + *labels = newlabels; +} + +void ConvNet::list_net() +{ + for (int i = 0; i < preprocess_length; i++) { + std::cout << "-----------------------\nCONVOLUTIONAL LAYER " << i << "\n-----------------------\n\n\u001b[31mGENERAL INFO:\x1B[0;37m\nStride: " << conv_layers[i].stride_len << "\nPadding: " << conv_layers[i].padding << "\n\n\u001b[31mINPUT:\x1B[0;37m\n" << *conv_layers[i].input << "\n\n\u001b[31mKERNEL:\x1B[0;37m\n" << *conv_layers[i].kernel << "\n\n\u001b[31mOUTPUT:\x1B[0;37m\n" << *conv_layers[i].output << "\n\n\u001b[31mBIAS:\x1B[0;37m\n" << conv_layers[i].bias << "\n\n\n"; + //std::cout << "-----------------------\nPOOLING LAYER " << i << "\n-----------------------\n\n\u001b[31mGENERAL INFO:\x1B[0;37m\nStride: " << pool_layers[i].stride_len << "\nPadding: " << conv_layers[i].padding << "\n\n\u001b[31mINPUT:\x1B[0;37m\n" << *pool_layers[i].input << "\n\n\u001b[31mKERNEL:\x1B[0;37m\n-" << *pool_layers[i].kernel << "\n\n\u001b[31mOUTPUT:\x1B[0;37m\n" << *pool_layers[i].output << "\n\n\n"; + } + std::cout << "-----------------------\nINPUT LAYER (LAYER 0)\n-----------------------\n\n\u001b[31mGENERAL INFO:\x1B[0;37m\nActivation Function: " << layers[0].activation_str << "\n\n\u001b[31mACTIVATIONS:\x1B[0;37m\n" << *layers[0].contents << "\n\n\u001b[31mWEIGHTS:\x1B[0;37m\n" << *layers[0].weights << "\n\n\u001b[31mBIASES:\x1B[0;37m\n" << *layers[0].bias << "\n\n\n"; + 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"; +} + +void ConvNet::backpropagate() +{ + std::vector<Eigen::MatrixXd> gradients; + std::vector<Eigen::MatrixXd> deltas; + Eigen::MatrixXd 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--) { + //std::cout << "--GRAD---\n" << gradients[counter-1] << "\n\n" << layers[i].weights->transpose() << "\n\n" << *layers[i].dZ << "\n\n"; + gradients.push_back((gradients[counter-1] * layers[i].weights->transpose()).cwiseProduct(*layers[i].dZ)); + //std::cout << "---DELTA---\n" << gradients[counter] << "\n\n" << layers[i].weights->transpose() << "\n\n" << *layers[i].dZ << "\n\n"; + deltas.push_back(layers[i-1].contents->transpose() * gradients[counter]); + counter++; + } + gradients.push_back((gradients[gradients.size()-1] * layers[0].weights->transpose()).cwiseProduct(*layers[0].dZ)); + for (int i = 0; i < length-1; i++) { + *layers[length-2-i].weights -= learning_rate * deltas[i]; + *layers[length-1-i].bias -= bias_lr * gradients[i]; + } + // list_net(); + // std::cout << "GRADIENT LIST\n"; + // for (int i = 0; i < gradients.size(); i++) { + // std::cout << gradients[i] << "\n\n"; + // } + Eigen::Map<Eigen::MatrixXd> reshaped(gradients[gradients.size()-1].data(), conv_layers[conv_layers.size()-1].output->rows(),conv_layers[conv_layers.size()-1].output->cols()); + gradients[gradients.size()-1] = reshaped; + //std::cout << gradients[gradients.size()-1].cols() << " " << conv_layers[0].input->cols() << " " << conv_layers[0].input->cols() - gradients[length-1].cols()+1 << "\n"; + for (int i = 0; i < conv_layers[0].input->cols() - gradients[length-1].cols()+1; i+=conv_layers[0].stride_len) { + for (int j = 0; j < conv_layers[0].input->rows() - gradients[length-1].rows()+1; j+=conv_layers[0].stride_len) { + (*conv_layers[0].kernel)(j, i) -= (gradients[length-1] * (conv_layers[0].input->block(j, i, gradients[length-1].rows(), gradients[length-1].cols()))).sum(); + } + } + conv_layers[0].bias -= gradients[gradients.size()-1].sum(); +} + +int main() +{ + ConvNet net ("./data_banknote_authentication.txt", 1, 0.05, 0.01, 0.9); + Eigen::MatrixXd labels (1,1); + labels << 1; + net.set_label(labels); + net.add_conv_layer(8,8,1,4,0); + //net.add_pool_layer(5,5,1,2,0); + net.add_layer(25, "linear"); + net.add_layer(5, "relu"); + net.add_layer(1, "resig"); + net.initialize(); + Eigen::MatrixXd* input = new Eigen::MatrixXd (8,8); + *input << + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,1,1,1,1,0,0, + 0,0,1,1,1,1,0,0, + 0,0,1,1,1,1,0,0, + 0,0,1,1,1,1,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0; + net.conv_layers[0].set_input(input); + net.process(); + for (int i = 0; i < 10; i++) { + net.feedforward(); + net.backpropagate(); + std::cout << *net.layers[net.layers.size()-1].contents << " <--- ACTIVATION\n"; + } + net.list_net(); + // net.list_net(); +} diff --git a/src/mr_bpnn.cpp b/src/mr_bpnn.cpp @@ -0,0 +1,94 @@ +#include "bpnn.hpp" +#include "utils.hpp" + +class NetworkArray +{ +public: + std::function<struct pair*(struct pair*)> map; + std::function<struct pair*(struct pair*)> reduce; + std::function<void(char*)> translate; + + NetworkArray(char* configuration, std::function<Network*(void)> setup, int epochs); + void start_array(char* data, int m, int length, char* ip, int r); +}; + +NetworkArray::NetworkArray(char* configuration, std::function<Network*(void)> setup, int epochs) +{ + map = [setup, epochs](struct pair* input_pair) -> struct pair* + { + //printf("Hello? %s\n", test.key); + printf("Recieved %p %p in form of %p (at %p)\n", input_pair->key, input_pair->value, input_pair, &input_pair); + printf("%s %p\n", (char*)input_pair->key, input_pair->value); + char* path = new char[100]; + strcpy(path, (char*)input_pair->key); + //strcat(path, "_shuf"); + //int linecount = prep_file((char*)input_pair.key, path); + // Network* net = setup(); + // net->train(epochs); + struct pair* output = new struct pair; + //char* key = new char[100]; + //strcpy(key, path); + output[0].key = 0x0; + output[0].value = 0x0; + return output; + }; + reduce = [](struct pair* input_pairs) -> struct pair* + { + struct pair* output = new struct pair[6]; + for (int i = 0; input_pairs[i].key != 0x0; i++) { + float* acc = new float; + *acc = ((Network*)input_pairs[i].value)->test("./test.txt"); + output[i].key = input_pairs[i].key; + output[i].value = acc; + } + return output; + }; + translate = [](char* path) -> void + { + FILE* rptr = fopen(path, "r"); + FILE* wptr = fopen("./translated", "w"); + char* line = new char[MAXLINE]; + char* newline = new char[MAXLINE]; + while (fgets(line, MAXLINE, rptr) != NULL) { + void* addr1; + void* addr2; + sscanf(line, "%p %p", &addr1, &addr2); + sprintf(newline, "%s %f", (char*)addr1, *(float*)addr2); + int batch_num = strtol((char*)addr1, NULL, 10); + fprintf(wptr, "%s %f\n",(char*)addr1, *(float*)addr2); + } + fclose(rptr); + fclose(wptr); + free(newline); + free(line); + }; +} + +void NetworkArray::start_array(char* data, int m, int length, char* ip, int r) +{ + begin(data, map, reduce, translate, m, length, ip, r); +} + +Network* setup() +{ + Network* net = new Network ("./data_banknote_authentication.txt", 10, 0.01, 0.001, 0.9); + net->add_layer(4, "linear"); + net->add_layer(5, "sigmoid"); + net->set_activation(1, lecun_tanh, lecun_tanh_deriv); + net->add_layer(1, "resig"); + net->initialize(); + return net; +} + +int main() +{ + NetworkArray netarray ("Train", setup, 1); + // char* path = "./extra.txt"; + // char* msg = "junk"; + //struct pair testing = {(void*)path, (void*)msg}; + // printf("SENDING %p %p (part of %p)\n", testing.key, testing.value, &testing); + //netarray.map(testing); + netarray.start_array("./extra.txt", 1, 1, "98.33.105.140", 1); + return 0; +} + diff --git a/mr_bpnn_1.cpp b/src/mr_bpnn_1.cpp diff --git a/mr_bpnn_2.cpp b/src/mr_bpnn_2.cpp diff --git a/src/utils.cpp b/src/utils.cpp @@ -0,0 +1,59 @@ +#include <iostream> +#include <fstream> +#include <cstdlib> +#include <ctime> +#include <cmath> +#include <cstdio> +#include <fcntl.h> +#include <unistd.h> +#include <sys/stat.h> +#include <Eigen/Dense> + +// A bunch of hardcoded activation functions. Avoids much of the slowness of custom functions. +// Although the std::function makes it not the fastest way, the functionality is worth it. +// Yes, these functions may be a frustrating to read but they're just equations and I want to conserve space. + +//float tanhapprox(float x) {return x - (1/3 * pow(x, 3)) + (2/15 * pow(x, 5)) - (17/315 * pow(x, 7));} + +float sigmoid(float x) {return 1.0/(1+exp(-x));} +float sigmoid_deriv(float x) {return 1.0/(1+exp(-x)) * (1 - 1.0/(1+exp(x)));} + +float linear(float x) {return x;} +float linear_deriv(float x) {return 1;} + +float lecun_tanh(float x) {return 1.7159 * tanh((2.0/3) * x);} +float lecun_tanh_deriv(float x) {return 1.14393 * pow(1.0/cosh(2.0/3 * x),2);} + +float inverse_logit(float x) {return (exp(x)/(exp(x)+1));} +float inverse_logit_deriv(float x) {return (exp(x)/pow(exp(x)+1, 2));} + +float softplus(float x) {return log(1+exp(x));} +float softplus_deriv(float x) {return exp(x)/(exp(x)+1);} + +float cloglog(float x) {return 1-exp(-exp(x));} +float cloglog_deriv(float x) {return exp(x-exp(x));} + +float step(float x) +{ + if (x > 0) return 1; + else return 0; +} +float step_deriv(float x) {return 0;} + +float bipolar(float x) +{ + if (x > 0) return 1; + else return -1; +} +float bipolar_deriv(float x) {return 0;} + +std::function<float(float)> rectifier(float (*activation)(float)) +{ + auto rectified = [activation](float x) -> float + { + if (x > 0) return (*activation)(x); + else return 0; + }; + return rectified; +} + diff --git a/utils.hpp b/src/utils.hpp diff --git a/sweep.yaml b/sweep.yaml @@ -1,36 +0,0 @@ -program: example.py -method: bayes -metric: - name: val_cost - goal: minimize -parameters: - epochs: - distribution: int_uniform - min: 25 - max: 100 - batch_size: - distribution: int_uniform - min: 5 - max: 200 - hidden_layers: - distribution: int_uniform - min: 1 - max: 6 - bias_lr: - distribution: uniform - min: 0.0015 - max: 0.06 - neurons: - distribution: int_uniform - min: 2 - max: 40 - activation: - distribution: categorical - values: - - lecun_tanh - - relu - - sigmoid - learning_rate: - distribution: uniform - min: 0.001 - max: 0.5 diff --git a/utils.cpp b/utils.cpp @@ -1,59 +0,0 @@ -#include <iostream> -#include <fstream> -#include <cstdlib> -#include <ctime> -#include <cmath> -#include <cstdio> -#include <fcntl.h> -#include <unistd.h> -#include <sys/stat.h> -#include <Eigen/Dense> - -// A bunch of hardcoded activation functions. Avoids much of the slowness of custom functions. -// Although the std::function makes it not the fastest way, the functionality is worth it. -// Yes, these functions may be a frustrating to read but they're just equations and I want to conserve space. - -//double tanhapprox(double x) {return x - (1/3 * pow(x, 3)) + (2/15 * pow(x, 5)) - (17/315 * pow(x, 7));} - -double sigmoid(double x) {return 1.0/(1+exp(-x));} -double sigmoid_deriv(double x) {return 1.0/(1+exp(-x)) * (1 - 1.0/(1+exp(x)));} - -double linear(double x) {return x;} -double linear_deriv(double x) {return 1;} - -double lecun_tanh(double x) {return 1.7159 * tanh((2.0/3) * x);} -double lecun_tanh_deriv(double x) {return 1.14393 * pow(1.0/cosh(2.0/3 * x),2);} - -double inverse_logit(double x) {return (exp(x)/(exp(x)+1));} -double inverse_logit_deriv(double x) {return (exp(x)/pow(exp(x)+1, 2));} - -double softplus(double x) {return log(1+exp(x));} -double softplus_deriv(double x) {return exp(x)/(exp(x)+1);} - -double cloglog(double x) {return 1-exp(-exp(x));} -double cloglog_deriv(double x) {return exp(x-exp(x));} - -double step(double x) -{ - if (x > 0) return 1; - else return 0; -} -double step_deriv(double x) {return 0;} - -double bipolar(double x) -{ - if (x > 0) return 1; - else return -1; -} -double bipolar_deriv(double x) {return 0;} - -std::function<double(double)> rectifier(double (*activation)(double)) -{ - auto rectified = [activation](double x) -> double - { - if (x > 0) return (*activation)(x); - else return 0; - }; - return rectified; -} -