commit 61136102bd994db2de3dad4329ee960e8093cd20
parent e92e36b5689829aae63b78a06e0e682ad808efaa
Author: David Freifeld <freifeld.david@gmail.com>
Date: Mon, 22 Jun 2020 17:46:53 -0700
Usability + minimal Makefile
Diffstat:
4 files changed, 48 insertions(+), 51 deletions(-)
diff --git a/Makefile b/Makefile
@@ -0,0 +1,6 @@
+
+all: mr_bpnn_2.cpp bpnn.cpp mapreduce.a
+ g++ -w -O2 -Wall -shared -std=c++11 -undefined dynamic_lookup `python3 -m pybind11 --includes` mr_bpnn_2.cpp bpnn.cpp mapreduce.a -o mrbpnn`python3-config --extension-suffix`
+
+clean:
+ $(RM) mrbpnn
diff --git a/bpnn.cpp b/bpnn.cpp
@@ -41,7 +41,8 @@ void Layer::initWeights(Layer next)
Network::Network(char* path, int inputs, int hidden, int outputs, int neurons, int batch_sz, float rate)
{
learning_rate = rate;
- fpath = path;
+ instances = prep_file(path, "./shuffled.txt");
+ fpath = "./shuffled.txt";
length = hidden + 2;
batch_size = batch_sz;
FILE* fptr = fopen(fpath, "r");
@@ -252,6 +253,35 @@ float Network::test(char* path)
return acc_sum/chunks;
}
+void Network::train(int total_epochs)
+{
+ float epoch_cost = 1000;
+ float epoch_accuracy = -1;
+ int epochs = 0;
+ printf("Beginning train on %i instances for %i epochs...\n", instances, total_epochs);
+ while (epochs < total_epochs) {
+ auto ep_begin = std::chrono::high_resolution_clock::now();
+ float cost_sum = 0;
+ float acc_sum = 0;
+ for (int i = 0; i <= instances-batch_size; i+=batch_size) {
+ feedforward();
+ backpropagate();
+ cost_sum += cost();
+ acc_sum += accuracy();
+ if (i != instances-batch_size) { // Don't try to advance batch on final batch.
+ next_batch(fpath);
+ } batches++;
+ }
+ epoch_accuracy = 1.0/((float) instances/batch_size) * acc_sum;
+ epoch_cost = 1.0/((float) instances/batch_size) * cost_sum;
+ auto ep_end = std::chrono::high_resolution_clock::now();
+ double epochtime = (double) std::chrono::duration_cast<std::chrono::nanoseconds>(ep_end-ep_begin).count() / pow(10,9);
+ printf("Epoch %i/%i - time %f - cost %f - acc %f\n", epochs+1, total_epochs, epochtime, epoch_cost, epoch_accuracy);
+ batches=1;
+ epochs++;
+ }
+}
+
void demo(int total_epochs)
{
int linecount = prep_file("./extra.txt", "./shuffled.txt");
diff --git a/bpnn.hpp b/bpnn.hpp
@@ -28,6 +28,7 @@ public:
class Network {
public:
char* fpath;
+ int instances;
std::vector<Layer> layers;
int length;
@@ -51,6 +52,7 @@ public:
void backpropagate();
int next_batch(char* path);
float test(char* path);
+ void train(int total_epochs);
};
void demo(int total_epochs);
diff --git a/mr_bpnn_2.cpp b/mr_bpnn_2.cpp
@@ -2,42 +2,20 @@
#include "bpnn.hpp"
namespace py = pybind11;
-class ParallelNetwork
-{
-public:
- Network* net;
- int total_epochs;
- int instances;
-
- ParallelNetwork(char* path, int inputs, int hidden, int outputs, int neurons, int batch_sz, float rate);
- struct pair* map (struct pair input_pair);
- struct pair* reduce (struct pair* input_pairs);
- void translate(char* path);
- double start();
-};
-
-ParallelNetwork::ParallelNetwork(char* path, int inputs, int hidden, int outputs, int neurons, int batch_sz, float rate, int epochs)
-{
- char* newpath = new char[100];
- strcpy(newpath, net->fpath);
- strcat(newpath, "_shuf");
- int linecount = prep_file(net->fpath, newpath);
- total_epochs = epochs;
- Network* net = new Network (path, inputs, hidden, outputs, neurons, batch_sz, rate);
-
-}
-
-struct pair* ParallelNetwork::map (struct pair input_pair)
+struct pair* map (struct pair input_pair)
{
char* path = new char[100];
strcpy(path, (char*)input_pair.key);
strcat(path, "_shuf");
+ printf("%s and %s\n", path, (char*)input_pair.key);
int linecount = prep_file((char*)input_pair.key, path);
+ Network* net = new Network (path, 4, 2, 1, 5, 10, 2);
auto begin = std::chrono::high_resolution_clock::now();
// std::cout << "\n\n\n";
float epoch_cost = 1000;
float epoch_accuracy = -1;
int epochs = 0;
+ int total_epochs = 50;
net->batches= 0;
// net.feedforward();
// net.backpropagate();
@@ -92,7 +70,7 @@ struct pair* ParallelNetwork::map (struct pair input_pair)
return output;
}
-struct pair* ParallelNetwork::reduce (struct pair* input_pairs)
+struct pair* reduce (struct pair* input_pairs)
{
struct pair* output = new struct pair[6];
for (int i = 0; input_pairs[i].key != 0x0; i++) {
@@ -105,7 +83,7 @@ struct pair* ParallelNetwork::reduce (struct pair* input_pairs)
return output;
}
-void ParallelNetwork::translate(char* path)
+void translate(char* path)
{
FILE* rptr = fopen(path, "r");
FILE* wptr = fopen("./translated", "w");
@@ -133,22 +111,11 @@ double benchmark(int epochs)
return std::chrono::duration_cast<std::chrono::nanoseconds>(prog_end-prog_begin).count();
}
-double ParalellNetwork::start(int mappers, int reducers, char* ip)
-{
- char* newpath = new char[100];
- strcpy(newpath, net->fpath);
- strcat(newpath, "_shuf");
- int linecount = prep_file(net->fpath, newpath);
- auto prog_begin = std::chrono::high_resolution_clock::now();
- begin("./shuffled", map, reduce, translate, mappers, 1, ip, reducers);
- auto prog_end = std::chrono::high_resolution_clock::now();
- return std::chrono::duration_cast<std::chrono::nanoseconds>(prog_end-prog_begin).count();
-}
PYBIND11_MODULE(mrbpnn, m) {
m.doc() = "pybind11 example plugin"; // optional module docstring
- m.def("benchmark", &benchmark, "A function which times the sequential BPNN", py::arg("epochs"));
+ m.def("benchmark", &benchmark, "A function which times the BPNN", py::arg("epochs"));
py::class_<Network>(m, "Network")
.def(py::init<char*, int, int, int, int, int, float>())
.def("feedforward", &Network::feedforward)
@@ -157,14 +124,6 @@ PYBIND11_MODULE(mrbpnn, m) {
.def("cost", &Network::cost)
.def("accuracy", &Network::accuracy)
.def("update_layer", &Network::update_layer, py::arg("vals"), py::arg("len"), py::arg("index"))
- .def("next_batch", &Network::next_batch, py::arg("path"));
- py::class_<ParalellNetwork>(m, "Network")
- .def(py::init<char*, int, int, int, int, int, float>())
- .def("feedforward", &Network::feedforward)
- .def("backpropagate", &Network::backpropagate)
- .def("list_net", &Network::list_net)
- .def("cost", &Network::cost)
- .def("accuracy", &Network::accuracy)
- .def("update_layer", &Network::update_layer, py::arg("vals"), py::arg("len"), py::arg("index"))
- .def("next_batch", &Network::next_batch, py::arg("path"));
+ .def("next_batch", &Network::next_batch, py::arg("path"))
+ .def("train", &Network::train, py::arg("epochs"));
}