Sunday, July 10, 2011

Porting lib FANN to Flash using Alchemy

Test Environment: OS: Windows XP, Alchemy: Alchemy Toolkit Preview, Flash SDK: 3.2, Flash Player 10, FANN: 2.1.0, Cygwin,

Lib FANN(Fast Artificial Neural Network Library) is a free open source neural network library written in C. In this tutorial I will show you how to use Adobe Alchemy to port FANN to Flash, step by step.

1. Download the FANN library: http://leenissen.dk/fann/wp/download/ (fann-2.1.0beta.zip)

2. Unzip the source code to some folder("F:\alchemy\FANN\fann-2.1.0")

3. Run "Cygwin" and do the config for the source code:

cd /cygdrive/f/alchemy/FANN/fann-2.1.0
./configure
Now you should find the Makefile created in "F:\alchemy\FANN\fann-2.1.0\src"

4. First of all, as a simple test, let's compile the source code of FANN to exe:
cd src
make
ar rc libFANNLib.a doublefann.o fixedfann.o floatfann.o
ranlib libFANNLib.a
Copy the files "xor.data, xor_train.c, xor_test.c" from "examples" folder to "src" folder.

gcc -o xor_train xor_train.c -Iinclude libFANNLib.a
gcc -o xor_test xor_test.c -Iinclude libFANNLib.a
Now you can find the compiled exe "xor_train.exe, xor_test.exe" in the src folder.
Copy "cygwin1.dll"  and click to run "xor_train.exe", it  will created files "xor_fixed.data, xor_fixed.net, xor_float.net". Using the cmd to run "xor_test.exe": Windows Start -> run -> cmd -> cd F:\alchemy\FANN\fann-2.1.0\src
F:
xor_test.exe
And you will see the result.

5. Now let compile the lib using alchemy:
source /cygdrive/f/alchemy/alchemy-setup
alc-on
make

6. A quick test to compile  "xor_test.c" to swfs:
(Since ar rc libFANNLib.a doublefann.o fixedfann.o floatfann.o will throw link errors"$ gcc xor_test.c -Iinclude libFANNLibfx.a libFANNLibfl.a libFANNLibdb.a -swf -O3 -Wall -o xor_test.swf
llvm-ld: error: Cannot link file 'FANNLibfl.l.bc': Linking globals named 'fann_default_error_log': symbol multiply defined!", 

I will do it this way:)
ar rc libFANNLibfx.a fixedfann.o
ranlib libFANNLibfx.a
gcc xor_train.c -Iinclude libFANNLibfx.a -swf -O3 -Wall -o xor_train_fx.swf
gcc xor_test.c -Iinclude libFANNLibfx.a -swf -O3 -Wall -o xor_test_fx.swf

ar rc libFANNLibfl.a floatfann.o
ranlib libFANNLibfl.a
gcc xor_train.c -Iinclude libFANNLibfl.a -swf -O3 -Wall -o xor_train_fl.swf
gcc xor_test.c -Iinclude libFANNLibfl.a -swf -O3 -Wall -o xor_test_fl.swf

ar rc libFANNLibdb.a doublefann.o
ranlib libFANNLibdb.a
gcc xor_train.c -Iinclude libFANNLibdb.a -swf -O3 -Wall -o xor_train_db.swf
gcc xor_test.c -Iinclude libFANNLibdb.a -swf -O3 -Wall -o xor_test_db.swf

Now make sure the compiled swfs and the files "xor.data, xor_fixed.data, xor_fixed.net, xor_float.net" are in the same folder.
run the xor_train_fx.swf, the result:
FANN Error 2: Unable to open configuration file "xor_float.net" for writing.
FANN Error 2: Unable to open configuration file "xor_fixed.net" for writing.
FANN Error 8: Unable to open train data file "xor_fixed.data" for writing.
Creating network.
Training network.
Testing network. 0.000000
XOR test (nan,nan) -> 0.000000, should be nan, difference=nan
XOR test (nan,0.000000) -> 0.000000, should be 0.000000, difference=0.000000
XOR test (0.000000,nan) -> 0.000000, should be 0.000000, difference=0.000000
XOR test (0.000000,0.000000) -> 0.000000, should be nan, difference=nan
Saving network.
Cleaning up.


run the xor_test_fx.swf, the result:
FANN Error 3: Wrong version of configuration file, aborting read of configuration file "xor_float.net".
Creating network.
Error creating ann --- ABORTING.


run the xor_train_fl.swf, the result:
FANN Error 2: Unable to open configuration file "xor_float.net" for writing.
FANN Error 2: Unable to open configuration file "xor_fixed.net" for writing.
FANN Error 8: Unable to open train data file "xor_fixed.data" for writing.
Creating network.
Training network.
Max epochs     1000. Desired error: 0.0000000000.
Epochs            1. Current error: 0.2960163057. Bit fail 4.
Epochs           10. Current error: 0.0559476353. Bit fail 4.
Epochs           20. Current error: 0.0005034587. Bit fail 3.
Epochs           28. Current error: 0.0000435168. Bit fail 0.
Testing network. 0.000031
XOR test (-1.000000,-1.000000) -> -0.995960, should be -1.000000, difference=0.004040
XOR test (-1.000000,1.000000) -> 0.982892, should be 1.000000, difference=0.017108
XOR test (1.000000,-1.000000) -> 0.988707, should be 1.000000, difference=0.011293
XOR test (1.000000,1.000000) -> -0.992229, should be -1.000000, difference=0.007771
Saving network.
Cleaning up.


run the xor_test_fl.swf, the result:
Creating network.
Layer / Neuron 0123456
L   1 / N    4 ZZZ....
L   1 / N    5 ZZZ....
L   1 / N    6 .......
L   2 / N    7 ...ZZZZ
L   2 / N    8 .......
Input layer                          :   2 neurons, 1 bias
  Hidden layer                       :   3 neurons, 1 bias
Output layer                         :   1 neurons
Total neurons and biases             :   8
Total connections                    :  13
Connection rate                      :   1.000
Network type                         :   FANN_NETTYPE_LAYER
Training algorithm                   :   FANN_TRAIN_RPROP
Training error function              :   FANN_ERRORFUNC_TANH
Training stop function               :   FANN_STOPFUNC_BIT
Bit fail limit                       :   0.000
Learning rate                        :   0.700
Learning momentum                    :   0.000
Quickprop decay                      :  -0.000100
Quickprop mu                         :   1.750
RPROP increase factor                :   1.200
RPROP decrease factor                :   0.500
RPROP delta min                      :   0.000
RPROP delta max                      :  50.000
Cascade output change fraction       :   0.010000
Cascade candidate change fraction    :   0.010000
Cascade output stagnation epochs     :  12
Cascade candidate stagnation epochs  :  12
Cascade max output epochs            : 150
Cascade max candidate epochs         : 150
Cascade weight multiplier            :   0.400
Cascade candidate limit              :1000.000
Cascade activation functions[0]      :   FANN_SIGMOID
Cascade activation functions[1]      :   FANN_SIGMOID_SYMMETRIC
Cascade activation functions[2]      :   FANN_GAUSSIAN
Cascade activation functions[3]      :   FANN_GAUSSIAN_SYMMETRIC
Cascade activation functions[4]      :   FANN_ELLIOT
Cascade activation functions[5]      :   FANN_ELLIOT_SYMMETRIC
Cascade activation functions[6]      :   FANN_SIN_SYMMETRIC
Cascade activation functions[7]      :   FANN_COS_SYMMETRIC
Cascade activation functions[8]      :   FANN_SIN
Cascade activation functions[9]      :   FANN_COS
Cascade activation steepnesses[0]    :   0.250
Cascade activation steepnesses[1]    :   0.500
Cascade activation steepnesses[2]    :   0.750
Cascade activation steepnesses[3]    :   1.000
Cascade candidate groups             :   2
Cascade no. of candidates            :  80
Testing network.
XOR test (-1.000000, -1.000000) -> 0.000000, should be -1.000000, difference=1.000000
XOR test (-1.000000, 1.000000) -> 0.000000, should be 1.000000, difference=1.000000
XOR test (1.000000, -1.000000) -> 0.000000, should be 1.000000, difference=1.000000
XOR test (1.000000, 1.000000) -> 0.000000, should be -1.000000, difference=1.000000
Cleaning up.


run the xor_train_db.swf, the result:
FANN Error 2: Unable to open configuration file "xor_float.net" for writing.
FANN Error 2: Unable to open configuration file "xor_fixed.net" for writing.
FANN Error 8: Unable to open train data file "xor_fixed.data" for writing.
Creating network.
Training network.
Max epochs     1000. Desired error: 0.0000000000.
Epochs            1. Current error: 0.2960163057. Bit fail 4.
Epochs           10. Current error: 0.0559476353. Bit fail 4.
Epochs           20. Current error: 0.0005034586. Bit fail 3.
Epochs           28. Current error: 0.0000435167. Bit fail 0.
Testing network. 0.000031
XOR test (0.000000,-1.875000) -> 0.000000, should be 0.000000, difference=0.000000
XOR test (0.000000,-1.875000) -> 67114963815632994304.000000, should be 0.000000, difference=67114963815632994304.000000
XOR test (0.000000,1.875000) -> 0.000146, should be 0.000000, difference=0.000146
XOR test (0.000000,1.875000) -> 0.000000, should be 0.000000, difference=0.000000
Saving network.
Cleaning up.


run the xor_test_db.swf, the result:
Creating network.
Layer / Neuron 0123456
L   1 / N    3 ZZZ....
L   1 / N    4 ZZZ....
L   1 / N    5 ZZZ....
L   1 / N    6 .......
L   2 / N    7 ...ZZZZ
L   2 / N    8 .......
Input layer                          :   2 neurons, 1 bias
  Hidden layer                       :   3 neurons, 1 bias
Output layer                         :   1 neurons
Total neurons and biases             :   8
Total connections                    :  13
Connection rate                      :   1.000
Network type                         :   FANN_NETTYPE_LAYER
Training algorithm                   :   FANN_TRAIN_RPROP
Training error function              :   FANN_ERRORFUNC_TANH
Training stop function               :   FANN_STOPFUNC_BIT
Bit fail limit                       :   0.000
Learning rate                        :   0.700
Learning momentum                    :   0.000
Quickprop decay                      :  -0.000100
Quickprop mu                         :   1.750
RPROP increase factor                :   1.200
RPROP decrease factor                :   0.500
RPROP delta min                      :   0.000
RPROP delta max                      :  50.000
Cascade output change fraction       :   0.010000
Cascade candidate change fraction    :   0.010000
Cascade output stagnation epochs     :  12
Cascade candidate stagnation epochs  :  12
Cascade max output epochs            : 150
Cascade max candidate epochs         : 150
Cascade weight multiplier            :   0.400
Cascade candidate limit              :1000.000
Cascade activation functions[0]      :   FANN_SIGMOID
Cascade activation functions[1]      :   FANN_SIGMOID_SYMMETRIC
Cascade activation functions[2]      :   FANN_GAUSSIAN
Cascade activation functions[3]      :   FANN_GAUSSIAN_SYMMETRIC
Cascade activation functions[4]      :   FANN_ELLIOT
Cascade activation functions[5]      :   FANN_ELLIOT_SYMMETRIC
Cascade activation functions[6]      :   FANN_SIN_SYMMETRIC
Cascade activation functions[7]      :   FANN_COS_SYMMETRIC
Cascade activation functions[8]      :   FANN_SIN
Cascade activation functions[9]      :   FANN_COS
Cascade activation steepnesses[0]    :   0.250
Cascade activation steepnesses[1]    :   0.500
Cascade activation steepnesses[2]    :   0.750
Cascade activation steepnesses[3]    :   1.000
Cascade candidate groups             :   2
Cascade no. of candidates            :  80
Testing network.
XOR test (0.000000, -1.875000) -> 0.000000, should be 0.000000, difference=0.000000
XOR test (0.000000, -1.875000) -> 0.000000, should be 0.000000, difference=0.000000
XOR test (0.000000, 1.875000) -> 0.000000, should be 0.000000, difference=0.000000
XOR test (0.000000, 1.875000) -> 0.000000, should be 0.000000, difference=0.000000
Cleaning up.


Well, still buggy, but from the prints we see that the lib works. The errors are partially caused by that it can't find the needed files, and some linking errors, too. A better way to make the port useful is to write some wrapper functions using the Alchemy API and compile everything to a swc.

Finally, the Compiled SWFs: https://flaswf.googlecode.com/svn/trunk/flaswfblog/Tutorials/ALCFANN

Sponsors