diff --git a/apps/DemoGenannXOR/MODULES b/apps/DemoGenannXOR/MODULES new file mode 100644 index 00000000..6a8f3ac8 --- /dev/null +++ b/apps/DemoGenannXOR/MODULES @@ -0,0 +1 @@ +ln_core genann diff --git a/apps/DemoGenannXOR/README b/apps/DemoGenannXOR/README new file mode 100644 index 00000000..a25340d4 --- /dev/null +++ b/apps/DemoGenannXOR/README @@ -0,0 +1,84 @@ +;create a new genann instance +;returns a genann object +;(genann-init number-of-inputs number-of-hidden-layers number-of-neurons-per-hidden-layer number-of-output-neurons) + +;free the genann object +;call this when you are done with the object +;(genann-free) + +;save the genann object to a file +;(genann-save ann "ann.net") + +;load a genann object into memory from a file +;(genann-load "ann.net") +;use it like this +;(set! ann (genann-load "ann.net")) + +;randomize the weights in the neural network +;(genann-randomize ann) +;dont forget to call (random-seed!) before to make it more random + +;copy the genann object to a new object +;useful for genetic algorithms when doing parent to child and then mutating the weights +;use it like this +;(set !annn (genann-copy ann)) + +;get the number of inputs +;use it like this +;(set! n (get-n-inputs ann)) + +;get the number of hidden layers +;use it like this +;(set! n (get-n-hidden-layers ann)) + +;get the number of neurons per hidden layer +;use it like this +;(set! n (get-n-hidden ann)) + +;get the number of outputs +;use it like this +;(set! n (get-n-outputs ann)) + +;get the total number of weights in the neural network +;use it like this +;(set! n (get-n-total-weights ann)) + +;get the number of total neurons in the network +;use it like this +;(set! n (get-n-total-neurons ann)) + +;get a vector of all the weights in the network +;use it like this +;(set! weights (get-weights ann)) + +;get a vector of the last output of the network +;use it like this +;(set! outputs (get-output ann)) + +;get a vector of the delta of all the neurons of the network +;use it like this +;(set! delta (get-delta ann)) + +;set a random seed with which genann-randomize will be used to initiate the weights +;this is how its set in C srand(time(0)) + +;train the neural network +;this is where the main work is done +;it takes two vectors, the first is inputs and second is expected outputs +;last is rate, which determines how fast the network will learn +;use it like this +;(genann-train ann (vector 0 0) (vector 0 1) 0.1) +;or +;(genann-train ann training-input expected-output rate) + +;run some inputs through the network and get an output +;use it like this +;(set! output (genann-run input)) +;or +;(set! output (genann-run (vector 1 1 4))) + +;update weight in the network +;use it like this +;(update-weight ann index value) +;or +;(update-weight ann 4 24.5) diff --git a/apps/DemoGenannXOR/VERSION b/apps/DemoGenannXOR/VERSION new file mode 100644 index 00000000..d3827e75 --- /dev/null +++ b/apps/DemoGenannXOR/VERSION @@ -0,0 +1 @@ +1.0 diff --git a/apps/DemoGenannXOR/main.scm b/apps/DemoGenannXOR/main.scm new file mode 100644 index 00000000..3704b4c2 --- /dev/null +++ b/apps/DemoGenannXOR/main.scm @@ -0,0 +1,41 @@ +;This program is to test the integration of the genann library into the lambdanative framework +;Do with it as you see fit +(display "Genann XOR Test")(newline) +(set! net (genann-init 2 1 2 1)) +;(display net) +(random-seed!) +(genann-randomize net) +;(genann-save net "neural.net") +;(define net2 (genann-copy net)) +;(genann-save net2 "neural2.net") +(genann-test) +(newline) (newline) (newline) +;;xor trial training +(display "BEFORE TRAINING") +(newline) +(display "0 0 => ") +(display (round (vector-ref (genann-run net (vector 0 0)) 0))) (newline) +(display "0 1 => ") +(display (round (vector-ref (genann-run net (vector 0 1)) 0))) (newline) +(display "1 0 => ") +(display (round (vector-ref (genann-run net (vector 1 0)) 0))) (newline) +(display "1 1 => ") +(display (round (vector-ref (genann-run net (vector 1 1)) 0))) (newline) (newline) +(display "Training for 10000 loops!...") (newline) (newline) +(display "AFTER TRAINING") (newline) +(let loop ((i 0)) + (when (< i 10000) + (genann-train net (vector 0 0) (vector 0) .3) + (genann-train net (vector 0 1) (vector 1) .3) + (genann-train net (vector 1 0) (vector 1) .3) + (genann-train net (vector 1 1) (vector 0) .3) +(loop (+ i 1)))) (newline) +(display "0 0 => ") +(display (round (vector-ref (genann-run net (vector 0 0)) 0))) (newline) +(display "0 1 => ") +(display (round (vector-ref (genann-run net (vector 0 1)) 0))) (newline) +(display "1 0 => ") +(display (round (vector-ref (genann-run net (vector 1 0)) 0))) (newline) +(display "1 1 => ") +(display (round (vector-ref (genann-run net (vector 1 1)) 0))) (newline) +(genann-free net) diff --git a/libraries/libgenann/make.sh b/libraries/libgenann/make.sh new file mode 100644 index 00000000..5dd44155 --- /dev/null +++ b/libraries/libgenann/make.sh @@ -0,0 +1,11 @@ +PKGURL=https://github.com/codeplea/genann.git + +package_download $PKGURL + +rm *.o 2> /dev/null +veval "$SYS_CC -c genann.c genann.o" +asserterror $? "compilation failed" +veval "$SYS_AR rcs $SYS_PREFIX/lib/libgenann.a genann.o" +asserterror $? "ar failed" + +cp genann.h $SYS_PREFIX/include diff --git a/modules/genann/LIBRARIES b/modules/genann/LIBRARIES new file mode 100644 index 00000000..5f656617 --- /dev/null +++ b/modules/genann/LIBRARIES @@ -0,0 +1 @@ +libgenann diff --git a/modules/genann/genann.scm b/modules/genann/genann.scm new file mode 100644 index 00000000..cf9dfe6a --- /dev/null +++ b/modules/genann/genann.scm @@ -0,0 +1,204 @@ +(c-declare "#include ") +(c-declare "#include ") +(c-declare "#include ") +(c-declare "#include \"helpers.h\"") + +(define genann-init + (c-lambda (int int int int) (pointer void) "genann_init") +) + +(define genann-free + (c-lambda ((pointer void)) void "genann_free") +) + +(define genannRun + (c-lambda ((pointer void) (pointer double)) (pointer double) "genannRun") +) + +(define genannTrain + (c-lambda ((pointer void) (pointer double) int (pointer double) int double) void "genannTrain") +) + +(define arrayPeek + (c-lambda((pointer double) int) double "peek") +) + +(define arrayFree + (c-lambda ((pointer double)) int "arrayFree") +) + +(define newArray + (c-lambda (int) (pointer double) "newArray") +) + +(define array-insert + (c-lambda ((pointer double) int double) int "arrayInsert") +) + +(define genann-save + (c-lambda ((pointer void) char-string) int "genannSave") +) + +(define genann-load + (c-lambda (char-string) (pointer void) "genannLoad") +) + +(define genann-randomize + (c-lambda ((pointer void)) int "genannRandomize") +) + +(define genann-free + (c-lambda ((pointer void)) int "genannFree") +) + +(define genann-copy + (c-lambda ((pointer void)) (pointer void) "genannCopy") +) + +(define show-array + (c-lambda ((pointer double) int) int "showArray") +) + +(define get-n-inputs + (c-lambda ((pointer void)) int "getNInputs") +) + +(define get-n-hidden-layers + (c-lambda ((pointer void)) int "getNHiddenLayers") +) + +(define get-n-hidden + (c-lambda ((pointer void)) int "getNHidden") +) + +(define get-n-outputs + (c-lambda ((pointer void)) int "getNOutputs") +) + +(define get-n-total-weights + (c-lambda ((pointer void)) int "getNTotalWeights") +) + +(define get-n-total-neurons + (c-lambda ((pointer void)) int "getNTotalNeurons") +) + +(define pseudo-get-weights + (c-lambda ((pointer void)) (pointer double) "getWeights") +) + +(define update-weight(lambda(net index value) + (set! weights (pseudo-get-weights net)) + (array-insert weights index (/ value 1.)) +)) + +(define get-weights(lambda(net) + (set! weights (pseudo-get-weights net)) + (set! weightsLen (get-n-total-weights net)) + (set! ret (make-vector weightsLen)) + (let loop ((i 0)) + (when (< i weightsLen) + (vector-set! ret i (arrayPeek weights i)) + (loop (+ i 1))) ret) +)) + +(define pseudo-get-output + (c-lambda ((pointer void)) (pointer double) "getOutput") +) + +(define get-output(lambda(net) + (set! outputs (pseudo-get-output net)) + (set! outputsLen (get-n-total-neurons net)) + (set! ret (make-vector outputsLen)) + (let loop ((i 0)) + (when (< i outputsLen) + (vector-set! ret i (arrayPeek outputs i)) + (loop (+ i 1))) ret) +)) + +(define pseudo-get-delta + (c-lambda ((pointer void)) (pointer double) "getDelta") +) + +(define get-delta(lambda(net) + (set! delta (pseudo-get-delta net)) + (set! deltaLen (- (get-n-total-neurons net) (get-n-inputs net))) + (set! ret (make-vector deltaLen)) + (let loop ((i 0)) + (when (< i deltaLen) + (vector-set! ret i (arrayPeek delta i)) + (loop (+ i 1))) ret) +)) + +(define random-seed! + (c-lambda () int "randomSeed") +) + +(define genann-train(lambda(net inputs outputs rate) + (set! iLen (vector-length inputs)) + (set! inputArr (newArray iLen)) + (let loop ((i 0)) + (when (< i iLen) + (array-insert inputArr i (/ (vector-ref inputs i) 1. )) + (loop (+ i 1)))) + (set! oLen (vector-length outputs)) + (set! outputArr (newArray oLen)) + (let loop ((i 0)) + (when (< i oLen) + (array-insert outputArr i (/ (vector-ref outputs i) 1. )) + (loop (+ i 1)))) + (show-array inputArr iLen) + (show-array outputArr oLen) + (genannTrain net inputArr iLen outputArr oLen (/ rate 1.)) + (arrayFree inputArr) + (arrayFree outputArr) +)) + +(define genann-run (lambda(net inputs) + (define len (vector-length inputs)) + (define arr (newArray len)) + (let loop ((i 0)) + (when (< i len) + (array-insert arr i (/ (vector-ref inputs i) 1.)) + (loop (+ i 1)))) + (set! outputs (genannRun net arr)) + (arrayFree arr) + (set! outputsLen (get-n-outputs net)) + (set! ret (make-vector outputsLen)) + (let loop ((i 0)) + (when (< i outputsLen) + (vector-set! ret i (arrayPeek outputs i)) + (loop (+ i 1))) ret) +)) + +(define train-to-test(lambda(net output) + (set! len (vector-length output)) + (set! percentage 0) + (let loop ((i 0)) + (when (< i 100000) + (genann-train net (vector 0 0) (vector (vector-ref output 0)) .1) + (genann-train net (vector 0 1) (vector (vector-ref output 1)) .1) + (genann-train net (vector 1 0) (vector (vector-ref output 2)) .1) + (genann-train net (vector 1 1) (vector (vector-ref output 3)) .1) + (loop (+ i 1)))) + (if (= (round (vector-ref (genann-run net (vector 0 0)) 0)) (vector-ref output 0)) (set! percentage (+ percentage 1))) + (if (= (round (vector-ref (genann-run net (vector 0 1)) 0)) (vector-ref output 1)) (set! percentage (+ percentage 1))) + (if (= (round (vector-ref (genann-run net (vector 1 0)) 0)) (vector-ref output 2)) (set! percentage (+ percentage 1))) + (if (= (round (vector-ref (genann-run net (vector 1 1)) 0)) (vector-ref output 3)) (set! percentage (+ percentage 1))) + (display (round (vector-ref (genann-run net (vector 0 0)) 0))) (newline) + (display (round (vector-ref (genann-run net (vector 0 1)) 0))) (newline) + (display (round (vector-ref (genann-run net (vector 1 0)) 0))) (newline) + (display (round (vector-ref (genann-run net (vector 1 1)) 0))) (newline) + (display (* (/ percentage len) 100)) (display "% PASS!") (newline) +)) + +(define genann-test(lambda() + (define net (genann-init 2 1 2 1)) + (display "--XOR Test--\n") + (train-to-test net (vector 0. 1. 1. 0.)) + (display "--OR Test--\n") + (train-to-test net (vector 0. 1. 1. 1.)) + (display "--AND Test--\n") + (train-to-test net (vector 0. 0. 0. 1.)) + (genann-free net) +)) \ No newline at end of file diff --git a/modules/genann/helpers.h b/modules/genann/helpers.h new file mode 100644 index 00000000..d2662a20 --- /dev/null +++ b/modules/genann/helpers.h @@ -0,0 +1,139 @@ +double *newArray(int sz){ + double *ptr = malloc(sizeof(double)*sz); + if (ptr != 0){ + return (void *)ptr; + } else { + return 0; + } +} + +int arrayInsert(double *arr, int index, double val){ + //puts("entered array insert"); + if (arr != 0){ + arr[index] = val; + //printf("%p inserted %f at %d\n",arr,arr[index],index); + }; + //puts("exiting array insert"); + return 0; +} + +int genannSave(genann *ann,const char *fn){ + FILE *f = fopen(fn,"w"); + if (f){ + genann_write(ann,f); + fclose(f); + } else { + puts("Error opening file!"); + } + return 0; +} + +genann *genannLoad(const char *fn){ + FILE *f = fopen(fn,"r"); + if (f){ + genann *ann = genann_read(f); + fclose(f); + return (void *)ann; + } + return 0; +} + +genann *genannCopy(genann *ann){ + genann *g = genann_copy(ann); + if (g){ + return (void *)g; + } + return 0; +} + +int genannRandomize(genann *ann){ + genann_randomize(ann); + return 0; +} + +int genannFree(genann *ann){ + genann_free(ann); + return 0; +} + +double *genannRun(genann *ann,double const *inputs){ + const double *r = genann_run(ann,inputs); + return (double *)r; +} + +int arrayFree(double *arr){ + free(arr); + return 0; +} + +double peek(double *arr, int i){ + if (i < sizeof(arr)){ + return arr[i]; + } return 0; +} + +int showArray(double *arr, int len){ + //printf("The size of the array is %d\n",len); + for (int i = 0; i < len; ++i){ + //printf("%p %d %f %d\n",arr,i,arr[i],len); + } + return 0; +} + +int genannTrain(genann *ann, double *inputs, int iLen, double *outputs, int oLen, double rate){ + //printf("Got %d inputs and %d outputs at rate %f\n",iLen,oLen,rate); + //puts("Inputs"); + for (int i = 0; i < iLen; ++i){ + //printf("%d %f\n",i,inputs[i]); + } + //puts("Outputs"); + for (int i = 0; i < oLen; ++i){ + //printf("%d %f\n",i,outputs[i]); + } + genann_train(ann,inputs,outputs,rate); + return 0; +} + +int getNInputs(genann *ann){ + return ann->inputs; +} + +int getNHiddenLayers(genann *ann){ + return ann->hidden_layers; +} + +int getNHidden(genann *ann){ + return ann->hidden; +} + +int getNOutputs(genann *ann){ + return ann->outputs; +} + +int getNTotalWeights(genann *ann){ + return ann->total_weights; +} + +int getNTotalNeurons(genann *ann){ + return ann->total_neurons; +} + +double *getWeights(genann *ann){ + return ann->weight; +} + +double *getOutput(genann *ann){ + return ann->output; +} + +double *getDelta(genann *ann){ + return ann->delta; +} + +int randomSeed(){ + srand(time(0)); + return 0; +} + +//dont forget to allow to set weights in scm +