jacobian

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

commit 96ab9f361a59f9226fd4e3e7cd5cd240f13cce37
parent ab211064394b589cf87f7762180739673cb9770d
Author: David Freifeld <freifeld.david@gmail.com>
Date:   Thu, 25 Jun 2020 20:51:09 -0700

Added plenty of activation functions

Diffstat:
Mbpnn.cpp | 18+++++++++++++++++-
Mexample.cpp | 10----------
Mexample.py | 6------
Mutils.cpp | 42++++++++++++++++++++++++------------------
Mutils.hpp | 8++++++++
5 files changed, 49 insertions(+), 35 deletions(-)

diff --git a/bpnn.cpp b/bpnn.cpp @@ -57,6 +57,22 @@ void Network::add_layer(int nodes, char* name) layers[length-1].activation = linear; layers[length-1].activation_deriv = linear_deriv; } + if (strcmp(name, "step") == 0) { + layers[length-1].activation = step; + layers[length-1].activation_deriv = step_deriv; + } + if (strcmp(name, "bipolar") == 0) { + layers[length-1].activation = bipolar; + layers[length-1].activation_deriv = bipolar_deriv; + } + if (strcmp(name, "lecun_tanh") == 0) { + layers[length-1].activation = lecun_tanh; + layers[length-1].activation_deriv = lecun_tanh_deriv; + } + if (strcmp(name, "logit") == 0) { + layers[length-1].activation = logit; + layers[length-1].activation_deriv = logit_deriv; + } else if (strcmp(name, "relu") == 0) { layers[length-1].activation = rectifier(linear); layers[length-1].activation_deriv = rectifier(linear_deriv); @@ -300,7 +316,7 @@ void Network::train(int total_epochs) 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]); + printf("Time spent across epoch: %lf on next batch, %lf on feedforward, %lf on backprop, %lf on cost, %lf on acc.\n\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.cpp b/example.cpp @@ -1,16 +1,6 @@ #include "bpnn.hpp" #include "utils.hpp" -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); -} - int main() { Network net ("./data_banknote_authentication.txt", 10, 0.01, 0.001); diff --git a/example.py b/example.py @@ -2,12 +2,6 @@ import mrbpnn import numpy import time -def lecun_tanh(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 - init = time.time() net = mrbpnn.Network("./data_banknote_authentication.txt", 10, 0.0155, 0.0155); net.add_layer(4, "linear"); diff --git a/utils.cpp b/utils.cpp @@ -8,31 +8,37 @@ #include <unistd.h> #include <sys/stat.h> -double sigmoid(double x) -{ - return 1.0/(1+exp(-x)); -} +// 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 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 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 linear(double x) +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 tanh(double x) {return tanh(x);} // For sake of symmetry. +double tanh_deriv(double x) {return pow(1.0/cosh(x),2);} + +double logit(double x) {return log(x/(1-x));} +double logit_deriv(double x) {return 1/(pow(x,2)-x);} + +double step(double x) { - return x; + if (x > 0) return 1; + else return 0; } +double step_deriv(double x) {return 0;} -double linear_deriv(double x) +double bipolar(double x) { - return 1; + if (x > 0) return 1; + else 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 bipolar_deriv(double x) {return 0;} std::function<double(double)> rectifier(double (*activation)(double)) { diff --git a/utils.hpp b/utils.hpp @@ -7,6 +7,14 @@ double sigmoid(double x); double sigmoid_deriv(double x); double linear(double x); double linear_deriv(double x); +double step(double x); +double step_deriv(double x); +double bipolar(double x); +double bipolar_deriv(double x); +double logit(double x); +double logit_deriv(double x); +double lecun_tanh(double x); +double lecun_tanh_deriv(double x); std::function<double(double)> rectifier(double (*activation)(double)); #endif /* MODULE_H */