commit 9d0599d64aba88854b603dbc39aadc7a262729d4
parent 4a6b792058ed03e8af210c63c421c7b32208549f
Author: David Freifeld <freifeld.david@gmail.com>
Date: Fri, 3 Jul 2020 22:57:37 -0700
Attempt to use strassen for feedforward
Diffstat:
3 files changed, 30 insertions(+), 5 deletions(-)
diff --git a/bpnn.cpp b/bpnn.cpp
@@ -124,7 +124,10 @@ void Network::feedforward()
}
}
for (int i = 0; i < length-1; i++) {
- *layers[i+1].contents = (*layers[i].contents) * (*layers[i].weights);
+ if (batch_size > 64 && batch_size % 4 == 0) {
+ *layers[i+1].contents = strassen_mul((*layers[i].contents),(*layers[i].weights));
+ }
+ else *layers[i+1].contents = (*layers[i].contents) * (*layers[i].weights);
*layers[i+1].contents += *layers[i+1].bias;
}
for (int i = 1; i < length; i++) {
@@ -316,8 +319,8 @@ void Network::train(int total_epochs)
}
epoch_acc = 1.0/((float) instances/batch_size) * acc_sum;
epoch_cost = 1.0/((float) instances/batch_size) * cost_sum;
- test(TEST_PATH);
- printf("Epoch %i/%i - cost %f - acc %f - val_cost %f - val_acc %f\n", epochs+1, total_epochs, epoch_cost, epoch_acc, val_cost, val_acc);
+ //test(TEST_PATH);
+ //printf("Epoch %i/%i - cost %f - acc %f - val_cost %f - val_acc %f\n", epochs+1, total_epochs, epoch_cost, epoch_acc, val_cost, val_acc);
batches=1;
epochs++;
rewind(data);
diff --git a/utils.cpp b/utils.cpp
@@ -7,6 +7,7 @@
#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.
@@ -55,3 +56,24 @@ std::function<double(double)> rectifier(double (*activation)(double))
};
return rectified;
}
+
+Eigen::MatrixXd strassen_mul(Eigen::MatrixXd a, Eigen::MatrixXd b)
+{
+ int block_len = a.rows()/2;
+ Eigen::MatrixXd result (a.rows(), a.cols());
+
+ Eigen::MatrixXd m1 = ((a.block(0,0, block_len, block_len)) + a.block(a.rows()-block_len,a.cols()-block_len, block_len, block_len)) * (b.block(0,0, block_len, block_len) + b.block(b.rows()-block_len,b.cols()-block_len, block_len, block_len));
+ Eigen::MatrixXd m2 = (a.block(a.rows()-block_len, 0, block_len, block_len) + a.block(a.rows()-block_len,a.cols()-block_len, block_len, block_len)) * (b.block(0,0, block_len, block_len));
+ Eigen::MatrixXd m3 = a.block(0,0, block_len, block_len) * (b.block(0,b.cols()-block_len, block_len, block_len) - b.block(b.rows()-block_len,b.cols()-block_len, block_len, block_len));
+ Eigen::MatrixXd m4 = a.block(a.rows()-block_len,a.cols()-block_len, block_len, block_len) * (b.block(b.rows()-block_len,0, block_len, block_len) - b.block(0,0, block_len, block_len));
+ Eigen::MatrixXd m5 = (a.block(0, 0, block_len, block_len) + a.block(0,a.cols()-block_len, block_len, block_len)) * (b.block(b.rows()-block_len,b.cols()-block_len, block_len, block_len));
+ Eigen::MatrixXd m6 = (a.block(a.rows()-block_len,0, block_len, block_len) - a.block(0,0, block_len, block_len)) * (b.block(0,0, block_len, block_len) + b.block(0,b.cols()-block_len, block_len, block_len));
+ Eigen::MatrixXd m7 = (a.block(0,a.cols()-block_len, block_len, block_len) - a.block(a.rows()-block_len,a.cols()-block_len, block_len, block_len)) * (b.block(a.rows()-block_len,0, block_len, block_len) + b.block(b.rows()-block_len,b.cols()-block_len, block_len, block_len));
+
+ result.block(0,0, block_len, block_len) = m1 + m4 - m5 + m7;
+ result.block(0,result.cols()-block_len, block_len, block_len) = m3 + m5;
+ result.block(result.rows()-block_len,0, block_len, block_len) = m2 + m4;
+ result.block(result.rows()-block_len,result.cols()-block_len, block_len, block_len) = m1 -m2 + m3 + m6;
+
+ return result;
+}
diff --git a/utils.hpp b/utils.hpp
@@ -24,6 +24,6 @@ double inverse_logit(double x);
double inverse_logit_deriv(double x);
std::function<double(double)> rectifier(double (*activation)(double));
-// Experimental fast file reading functions
-uintmax_t wc(char const *fname);
+Eigen::MatrixXd strassen_mul(Eigen::MatrixXd a, Eigen::MatrixXd b);
+
#endif /* MODULE_H */