commit ab211064394b589cf87f7762180739673cb9770d
parent bd4cc67f67316aeab18ab7770fbc6d3ad9e53f99
Author: David Freifeld <freifeld.david@gmail.com>
Date: Thu, 25 Jun 2020 20:05:31 -0700
Benchmarking in hopes of speedup
Diffstat:
5 files changed, 38 insertions(+), 8 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,6 +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 utils.cpp mapreduce.a -o mrbpnn`python3-config --extension-suffix`
+ g++ -w -O2 -shared -std=c++11 -undefined dynamic_lookup `python3 -m pybind11 --includes` mr_bpnn_2.cpp bpnn.cpp utils.cpp mapreduce.a -o mrbpnn`python3-config --extension-suffix`
clean:
$(RM) mrbpnn
diff --git a/bpnn.cpp b/bpnn.cpp
@@ -87,16 +87,19 @@ void Network::set_activation(int index, std::function<double(double)> custom, st
void Network::feedforward()
{
+ //auto early_activ_begin = std::chrono::high_resolution_clock::now();
for (int j = 0; j < layers[0].contents->rows(); j++) {
for (int k = 0; k < layers[0].contents->cols(); k++) {
(*layers[0].dZ)(j,k) = layers[0].activation_deriv((*layers[0].contents)(j,k));
(*layers[0].contents)(j,k) = layers[0].activation((*layers[0].contents)(j,k));
}
}
+ //auto mul_begin = std::chrono::high_resolution_clock::now();
for (int i = 0; i < length-1; i++) {
*layers[i+1].contents = (*layers[i].contents) * (*layers[i].weights);
*layers[i+1].contents += *layers[i+1].bias;
}
+ //auto activ_begin = std::chrono::high_resolution_clock::now();
for (int i = 1; i < length; i++) {
for (int j = 0; j < layers[i].contents->rows(); j++) {
for (int k = 0; k < layers[i].contents->cols(); k++) {
@@ -105,6 +108,11 @@ void Network::feedforward()
}
}
}
+ //auto feed_end = std::chrono::high_resolution_clock::now();
+ //double early_activ = std::chrono::duration_cast<std::chrono::nanoseconds>(mul_begin - early_activ_begin).count() / pow(10,9);
+ //double mul = std::chrono::duration_cast<std::chrono::nanoseconds>(activ_begin - mul_begin).count() / pow(10,9);
+ //double activ = std::chrono::duration_cast<std::chrono::nanoseconds>(feed_end - activ_begin).count() / pow(10,9);
+ //printf("%lf on early activation, %lf on multiply, %lf on rest of activation\n", early_activ, mul, activ);
}
void Network::list_net()
@@ -264,14 +272,26 @@ void Network::train(int total_epochs)
auto ep_begin = std::chrono::high_resolution_clock::now();
float cost_sum = 0;
float acc_sum = 0;
+ double times[5] = {0};
for (int i = 0; i <= instances-batch_size; i+=batch_size) {
+ auto batch_begin = std::chrono::high_resolution_clock::now();
if (i != instances-batch_size) { // Don't try to advance batch on final batch.
next_batch();
}
+ auto feed_begin = std::chrono::high_resolution_clock::now();
feedforward();
+ auto back_begin = std::chrono::high_resolution_clock::now();
backpropagate();
+ auto cost_begin = std::chrono::high_resolution_clock::now();
cost_sum += cost();
+ auto acc_begin = std::chrono::high_resolution_clock::now();
acc_sum += accuracy();
+ auto loop_end = std::chrono::high_resolution_clock::now();
+ times[0] += std::chrono::duration_cast<std::chrono::nanoseconds>(feed_begin - batch_begin).count() / pow(10,9);
+ times[1] += std::chrono::duration_cast<std::chrono::nanoseconds>(back_begin - feed_begin).count() / pow(10,9);
+ times[2] += std::chrono::duration_cast<std::chrono::nanoseconds>(cost_begin - back_begin).count() / pow(10,9);
+ times[3] += std::chrono::duration_cast<std::chrono::nanoseconds>(acc_begin - cost_begin).count() / pow(10,9);
+ times[4] += std::chrono::duration_cast<std::chrono::nanoseconds>(loop_end - acc_begin).count() / pow(10,9);
batches++;
}
epoch_accuracy = 1.0/((float) instances/batch_size) * acc_sum;
@@ -279,6 +299,8 @@ void Network::train(int total_epochs)
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);
+ printf("Avg time spent across %i batches: %lf on next batch, %lf on feedforward, %lf on backprop, %lf on cost, %lf on acc.\n", batches, times[0]/batches, times[1]/batches, times[2]/batches, times[3]/batches, times[4]/batches);
+ printf("Time spent across epoch: %lf on next batch, %lf on feedforward, %lf on backprop, %lf on cost, %lf on acc.\n", times[0], times[1], times[2], times[3], times[4], epochtime-times[0]-times[1]-times[2]-times[3]-times[4]);
batches=1;
epochs++;
rewind(data);
diff --git a/example.py b/example.py
@@ -3,19 +3,20 @@ import numpy
import time
def lecun_tanh(x):
- return 1.7159 * numpy.tanh((2.0/3) * x)
+ return 1.7159 * numpy.tanh((2.0/3) * x)
def lecun_tanh_deriv(x):
- return 1.14393 * (1.0/numpy.cosh(2.0/3 * x))**2
+ return 1.14393 * (1.0/numpy.cosh(2.0/3 * x))**2
init = time.time()
-net = mrbpnn.Network("./data_banknote_authentication.txt", 10, 0.01, 0.001);
+net = mrbpnn.Network("./data_banknote_authentication.txt", 10, 0.0155, 0.0155);
net.add_layer(4, "linear");
net.add_layer(5, "sigmoid");
net.set_activation(1, lecun_tanh, lecun_tanh_deriv);
net.add_layer(1, "sigmoid");
net.initialize();
+initend = time.time()
net.train(50);
end = time.time()
-print(end-init)
+print("%s: init %s" % (end-init, initend-init))
diff --git a/kerasdemo.py b/kerasdemo.py
@@ -36,9 +36,10 @@ model.add(Dense(1, activation='sigmoid'))
opt = keras.optimizers.SGD(lr=0.01)
model.compile(loss='mse', optimizer=opt, metrics=['accuracy'])
# fit the keras model on the dataset
+initend = time.time()
model.fit(X, y, epochs=50, batch_size=10)
# evaluate the keras model
-_, accuracy = model.evaluate(X, y)
-print('Accuracy: %.2f' % (accuracy*100))
+#_, accuracy = model.evaluate(X, y)
+#print('Accuracy: %.2f' % (accuracy*100))
end = time.time()
-print(end-init)
+print("%s: init %s" % (end-init, initend-init))
diff --git a/utils.cpp b/utils.cpp
@@ -28,6 +28,12 @@ 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);
+//}
+
std::function<double(double)> rectifier(double (*activation)(double))
{
auto rectified = [activation](double x) -> double