diff --git a/README.md b/README.md index 17326c3..24a5beb 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,27 @@ Tinn (Tiny Neural Network) is a dependency free ANSI-C neural network library. + #include "Tinn.h" + #include + + #define len(a) ((int) (sizeof(a) / sizeof(*a))) + + int main(void) + { + double in[] = { 0.05, 0.10 }; + double tg[] = { 0.01, 0.99 }; + /* Two hidden nuerons */ + const Tinn tinn = xtbuild(len(in), 2, len(tg)); + int i; + for(i = 0; i < 10000; i++) + { + double error = xttrain(tinn, in, tg, 0.5); + printf("%.12f\n", error); + } + xtfree(tinn); + return 0; + } + Run the sample: make; ./tinn diff --git a/Tinn.c b/Tinn.c index b300c91..3af70fa 100644 --- a/Tinn.c +++ b/Tinn.c @@ -2,6 +2,7 @@ #include #include +#include static double error(Tinn t, double* tg) { @@ -49,9 +50,13 @@ static double act(double net) return 1.0 / (1.0 + exp(-net)); } +static double frand(void) +{ + return rand() / (double) RAND_MAX; +} + static void forewards(Tinn t, double* in) { - const double bias[] = { 0.35, 0.60 }; double* x = t.w + t.nhid * t.nips; int i; for(i = 0; i < t.nhid; i++) @@ -64,7 +69,7 @@ static void forewards(Tinn t, double* in) double b = t.w[i * t.nips + j]; sum += a * b; } - t.h[i] = act(sum + bias[0]); + t.h[i] = act(sum + t.b[0]); } for(i = 0; i < t.nops; i++) { @@ -76,53 +81,16 @@ static void forewards(Tinn t, double* in) double b = x[i * t.nhid + j]; sum += a * b; } - t.o[i] = act(sum + bias[1]); + t.o[i] = act(sum + t.b[1]); } } static void twrand(Tinn t) { -#if 0 - /* 2 2 2 */ - t.w[0] = 0.15; - t.w[1] = 0.20; - t.w[2] = 0.25; - t.w[3] = 0.30; - - t.w[4] = 0.40; - t.w[5] = 0.45; - t.w[6] = 0.50; - t.w[7] = 0.55; -#endif -#if 0 - /* 2 3 2 */ - t.w[0] = 0.15; - t.w[1] = 0.20; - t.w[2] = 0.25; - t.w[3] = 0.30; - t.w[4] = 0.30; - t.w[5] = 0.30; - - t.w[6] = 0.40; - t.w[7] = 0.45; - t.w[8] = 0.50; - t.w[9] = 0.55; - t.w[10] = 0.55; - t.w[11] = 0.55; -#endif - /* 2 3 1 */ -#if 1 - t.w[0] = 0.15; - t.w[1] = 0.20; - t.w[2] = 0.25; - t.w[3] = 0.30; - t.w[4] = 0.30; - t.w[5] = 0.30; - - t.w[6] = 0.40; - t.w[7] = 0.45; - t.w[8] = 0.50; -#endif + const int wgts = t.nhid * (t.nips + t.nops); + int i; + for(i = 0; i < wgts; i++) t.w[i] = frand(); + for(i = 0; i < t.nb; i++) t.b[i] = frand(); } double xttrain(Tinn t, double* in, double* tg, double rate) @@ -132,15 +100,18 @@ double xttrain(Tinn t, double* in, double* tg, double rate) return error(t, tg); } -Tinn xtbuild(int nips, int nops, int nhid) +Tinn xtbuild(int nips, int nhid, int nops) { Tinn t; - t.o = (double*) calloc(nops, sizeof(*t.o)); - t.h = (double*) calloc(nhid, sizeof(*t.h)); + t.nb = 2; t.w = (double*) calloc(nhid * (nips + nops), sizeof(*t.w)); - t.nops = nops; - t.nhid = nhid; + t.b = (double*) calloc(t.nb, sizeof(*t.b)); + t.h = (double*) calloc(nhid, sizeof(*t.h)); + t.o = (double*) calloc(nops, sizeof(*t.o)); t.nips = nips; + t.nhid = nhid; + t.nops = nops; + srand(time(0)); twrand(t); return t; } diff --git a/Tinn.h b/Tinn.h index afa42ba..c084331 100644 --- a/Tinn.h +++ b/Tinn.h @@ -3,18 +3,20 @@ typedef struct { - double* o; - double* h; double* w; - int nops; - int nhid; + double* b; + double* h; + double* o; + int nb; int nips; + int nhid; + int nops; } Tinn; extern double xttrain(Tinn, double* in, double* tg, double rate); -extern Tinn xtbuild(int nips, int nops, int nhid); +extern Tinn xtbuild(int nips, int nhid, int nops); extern void xtfree(Tinn); diff --git a/test.c b/test.c index 0c8fa10..16423eb 100644 --- a/test.c +++ b/test.c @@ -1,37 +1,20 @@ #include "Tinn.h" - #include -#include -static double* inload(int nips) -{ - double* in = (double*) calloc(nips, sizeof(*in)); - in[0] = 0.05; - in[1] = 0.10; - return in; -} +#define len(a) ((int) (sizeof(a) / sizeof(*a))) -static double* tgload(int nops) +int main(void) { - double* tg = (double*) calloc(nops, sizeof(*tg)); - tg[0] = 0.01; - /* tg[1] = 0.99; */ - return tg; -} - -int main() -{ - int nips = 2; - int nhid = 3; - int nops = 1; - double* in = inload(nips); - double* tg = tgload(nops); - Tinn tinn = xtbuild(nips, nops, nhid); + double in[] = { 0.05, 0.10 }; + double tg[] = { 0.01, 0.99 }; + /* Two hidden nuerons */ + const Tinn tinn = xtbuild(len(in), 2, len(tg)); int i; - for(i = 0; i <= 10000; i++) - printf("%.18f\n", xttrain(tinn, in, tg, 0.5)); + for(i = 0; i < 10000; i++) + { + double error = xttrain(tinn, in, tg, 0.5); + printf("%.12f\n", error); + } xtfree(tinn); - free(in); - free(tg); return 0; }