commit 6eb4a187ae222308c607f40972ba7a8587b61638
parent b4c6b1e53371a289374da1d2fd1261e7ccb7ec8f
Author: David Freifeld <freifeld.david@gmail.com>
Date: Fri, 10 Jul 2020 20:09:51 -0700
Reorganized directory.
Diffstat:
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;
-}
-