[PD-cvs] externals/ann/src ann_mlp.c,1.8,1.9
Georg Holzmann
grholzi at users.sourceforge.net
Sat Jul 23 23:16:12 CEST 2005
- Previous message: [PD-cvs] externals/hcs/purepd delta.pd, NONE, 1.1 float_argument.pd, NONE, 1.1 inv.pd, NONE, 1.1 oneshot.pd, NONE, 1.1 symbol_argument.pd, NONE, 1.1 velocity.pd, NONE, 1.1
- Next message: [PD-cvs] externals/ann/src ann_mlp.c,1.9,1.10
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/pure-data/externals/ann/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17348
Modified Files:
ann_mlp.c
Log Message:
some bugfixes and changes ...
Index: ann_mlp.c
===================================================================
RCS file: /cvsroot/pure-data/externals/ann/src/ann_mlp.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** ann_mlp.c 29 Jun 2005 22:17:37 -0000 1.8
--- ann_mlp.c 23 Jul 2005 21:16:10 -0000 1.9
***************
*** 6,9 ****
--- 6,15 ----
this software is licensed under the GNU General Public License
*/
+
+ /*
+ hacked by Georg Holzmann for some additional methods, bug fixes, ...
+ 2005, grh at mur.at
+ */
+
#include <stdio.h>
#include <string.h>
***************
*** 22,28 ****
#define RUN 1
- #define MAXINPUT 1024
- #define MAXOUTPUT 256
-
static t_class *ann_mlp_class;
--- 28,31 ----
***************
*** 36,42 ****
--- 39,83 ----
unsigned int max_iterations;
unsigned int iterations_between_reports;
+ fann_type *input; // grh: storage for input
+ t_atom *output; // grh: storage for output (t_atom)
+ fann_type *out_float; // grh: storage for output (fann_type)
+ t_canvas *x_canvas;
t_outlet *l_out, *f_out;
} t_ann_mlp;
+ // allocation
+ static void ann_mlp_allocate_storage(t_ann_mlp *x)
+ {
+ int i;
+
+ if(!x->ann)
+ return;
+
+ x->input = (fann_type *)getbytes(x->ann->num_input*sizeof(fann_type));
+ x->output = (t_atom *)getbytes(x->ann->num_output*sizeof(t_atom));
+ x->out_float = (fann_type *)getbytes(x->ann->num_output*sizeof(fann_type));
+
+ // init storage with zeros
+ for (i=0; i<x->ann->num_input; i++)
+ x->input[i]=0;
+ for (i=0; i<x->ann->num_output; i++)
+ {
+ SETFLOAT(x->output+i, 0);
+ x->out_float[i]=0;
+ }
+ }
+
+ // deallocation
+ static void ann_mlp_free(t_ann_mlp *x)
+ {
+ if(!x->ann)
+ return;
+
+ freebytes(x->input, x->ann->num_input * sizeof(fann_type));
+ freebytes(x->output, x->ann->num_output * sizeof(t_atom));
+ freebytes(x->out_float, x->ann->num_output * sizeof(fann_type));
+ fann_destroy(x->ann);
+ }
+
static void ann_mlp_help(t_ann_mlp *x)
{
***************
*** 56,112 ****
unsigned int num_output = 1;
unsigned int num_layers = 3;
! unsigned int num_neurons_hidden = 3;
float connection_rate = 1;
float learning_rate = (float)0.7;
!
! if (argc>0)
num_input = atom_getint(argv++);
! if (argc>1)
num_output = atom_getint(argv++);
! if (argc>2)
! num_layers = atom_getint(argv++);
!
! if (argc>3)
! num_neurons_hidden = atom_getint(argv++);
!
! if (argc>4)
connection_rate = atom_getfloat(argv++);
! if (argc>5)
learning_rate = atom_getfloat(argv++);
! if (num_input>MAXINPUT)
! {
! error("too many inputs, maximum allowed is MAXINPUT");
! return;
! }
!
! if (num_output>MAXOUTPUT)
! {
! error("too many outputs, maximum allowed is MAXOUTPUT");
! return;
! }
!
! x->ann = fann_create(connection_rate, learning_rate, num_layers,
! num_input, num_neurons_hidden, num_output);
fann_set_activation_function_hidden(x->ann, FANN_SIGMOID_SYMMETRIC);
fann_set_activation_function_output(x->ann, FANN_SIGMOID_SYMMETRIC);
!
! if (x->ann == 0)
! {
! error("error creating the ann");
! } else
! {
! post("created ann with:");
! post("num_input = %i", num_input);
! post("num_output = %i", num_output);
! post("num_layers = %i", num_layers);
! post("num_neurons_hidden = %i", num_neurons_hidden);
! post("connection_rate = %f", connection_rate);
! post("learning_rate = %f", learning_rate);
! }
}
--- 97,188 ----
unsigned int num_output = 1;
unsigned int num_layers = 3;
! unsigned int *neurons_per_layer = NULL;
! int activated=0;
! int i, count_args = 0;
float connection_rate = 1;
float learning_rate = (float)0.7;
!
!
! // okay, start parsing init args ...
!
! if (argc > count_args++)
num_input = atom_getint(argv++);
! if (argc > count_args++)
num_output = atom_getint(argv++);
! if (argc > count_args++)
! {
! int hidden=0;
!
! num_layers = atom_getint(argv++);
! hidden = num_layers-2;
!
! neurons_per_layer = (unsigned int *)getbytes(num_layers*sizeof(unsigned int));
!
! neurons_per_layer[0] = num_input;
!
! // make standard initialization (if there are too few init args)
! for (i=1; i<hidden+1; i++)
! neurons_per_layer[i] = 3;
!
! // now check init args
! for (i=1; i<hidden+1; i++)
! {
! if (argc > count_args++)
! neurons_per_layer[i] = atom_getint(argv++);
! }
!
! neurons_per_layer[num_layers-1] = num_output;
!
! activated=1;
! }
!
! if (argc > count_args++)
connection_rate = atom_getfloat(argv++);
! if (argc > count_args++)
learning_rate = atom_getfloat(argv++);
! // make one hidden layer as standard, if there were too few init args
! if(!activated)
! {
! neurons_per_layer = (unsigned int *)getbytes(3*sizeof(unsigned int));
! neurons_per_layer[0] = num_input;
! neurons_per_layer[1] = 3;
! neurons_per_layer[2] = num_output;
! }
+ // ... end of parsing init args
+
+
+ if(x->ann)
+ ann_mlp_free(x);
+
+ x->ann = fann_create_array(connection_rate, learning_rate, num_layers, neurons_per_layer);
+
+ // deallocate helper array
+ freebytes(neurons_per_layer, num_layers * sizeof(unsigned int));
+
+ if(!x->ann)
+ {
+ error("error creating the ann");
+ return;
+ }
+
+ ann_mlp_allocate_storage(x);
fann_set_activation_function_hidden(x->ann, FANN_SIGMOID_SYMMETRIC);
fann_set_activation_function_output(x->ann, FANN_SIGMOID_SYMMETRIC);
!
! // set error log to stdout, so that you see it in the pd console
! //fann_set_error_log((struct fann_error*)x->ann, stdout);
! // unfortunately this doesn't work ... but it should do in a similar way !!
!
! post("created ann with:");
! post("num_input = %i", num_input);
! post("num_output = %i", num_output);
! post("num_layers = %i", num_layers);
! post("connection_rate = %f", connection_rate);
! post("learning_rate = %f", learning_rate);
}
***************
*** 150,157 ****
}
!
!
! static void ann_mlp_train_on_file(t_ann_mlp *x, t_symbol *sl, int argc, t_atom *argv)
{
if (x->ann == 0)
{
--- 226,235 ----
}
! static void ann_mlp_train_on_file(t_ann_mlp *x, t_symbol *s)
{
+ // make correct path
+ char patcher_path[MAXPDSTRING];
+ char filename[MAXPDSTRING];
+
if (x->ann == 0)
{
***************
*** 160,173 ****
}
! if (argc<1)
! {
! error("you must specify the filename with training data");
! return;
! } else
! {
! x->filenametrain = atom_gensym(argv);
! }
! //post("nn: starting training on file %s, please be patient and wait for my next message (it could take severeal minutes to complete training)", x->filenametrain->s_name);
fann_train_on_file(x->ann, x->filenametrain->s_name, x->max_iterations,
--- 238,250 ----
}
! // make correct path
! canvas_makefilename(x->x_canvas, s->s_name, patcher_path, MAXPDSTRING);
! sys_bashfilename(patcher_path, filename);
! x->filenametrain = gensym(filename);
! if(!x->filenametrain)
! return;
!
! post("nn: starting training on file %s, please be patient and wait ... (it could take severeal minutes to complete training)", x->filenametrain->s_name);
fann_train_on_file(x->ann, x->filenametrain->s_name, x->max_iterations,
***************
*** 221,235 ****
}
-
// run the ann using floats in list passed to the inlet as input values
// and send result to outlet as list of float
static void ann_mlp_run_the_net(t_ann_mlp *x, t_symbol *sl, int argc, t_atom *argv)
{
! int i=0;
! fann_type input[MAXINPUT];
fann_type *calc_out;
- t_atom lista[MAXOUTPUT];
- int quanti;
- float valoreTMP;
if (x->ann == 0)
--- 298,307 ----
}
// run the ann using floats in list passed to the inlet as input values
// and send result to outlet as list of float
static void ann_mlp_run_the_net(t_ann_mlp *x, t_symbol *sl, int argc, t_atom *argv)
{
! int i=0;
fann_type *calc_out;
if (x->ann == 0)
***************
*** 238,279 ****
return;
}
!
! quanti = x->ann->num_output;
!
! // fill input array with zeros
! for (i=0; i<MAXINPUT; i++)
! {
! input[i]=0;
! }
!
! // fill output array with zeros
! for (i=0; i<MAXOUTPUT; i++)
! {
! SETFLOAT(lista + i,0);
! }
// fill input array with actual data sent to inlet
! for (i=0;i<argc;i++)
{
! input[i] = atom_getfloat(argv++);
}
// run the ann
! calc_out = fann_run(x->ann, input);
// fill the output array with result from ann
! for (i=0;i<quanti;i++)
! {
! valoreTMP = calc_out[i];
! //post("calc_out[%i]=%f", i, calc_out[i]);
! SETFLOAT(lista+i, valoreTMP);
! }
// send output array to outlet
! outlet_anything(x->l_out,
! gensym("list") ,
! quanti,
! lista);
!
}
--- 310,336 ----
return;
}
!
! if(argc < x->ann->num_input)
! {
! error("ann_mlp: too few input values!!");
! return;
! }
// fill input array with actual data sent to inlet
! for (i=0;i<x->ann->num_input;i++)
{
! x->input[i] = atom_getfloat(argv++);
}
// run the ann
! calc_out = fann_run(x->ann, x->input);
// fill the output array with result from ann
! for (i=0;i<x->ann->num_output;i++)
! SETFLOAT(x->output+i, calc_out[i]);
// send output array to outlet
! outlet_anything(x->l_out, gensym("list"),
! x->ann->num_output, x->output);
}
***************
*** 281,290 ****
{
int i=0;
! fann_type input[MAXINPUT];
! fann_type output[MAXOUTPUT];
! //fann_type *calcMSE;
! //t_atom lista[MAXOUTPUT];
! int quantiINs;
! int quantiOUTs;
float mse;
--- 338,342 ----
{
int i=0;
! int quantiINs, quantiOUTs;
float mse;
***************
*** 304,338 ****
}
- // fill input array with zeros
- for (i=0; i<MAXINPUT; i++)
- {
- input[i]=0;
- }
- // fill input array with zeros
- for (i=0; i<MAXOUTPUT; i++)
- {
- output[i]=0;
- }
-
// fill input array with actual data sent to inlet
for (i=0;i<quantiINs;i++)
! {
! input[i] = atom_getfloat(argv++);
! }
for (i=0;i<quantiOUTs;i++)
! {
! output[i] = atom_getfloat(argv++);
! }
//fann_reset_MSE(x->ann);
! fann_train(x->ann, input, output);
mse = fann_get_MSE(x->ann);
outlet_float(x->f_out, mse);
-
-
}
--- 356,373 ----
}
// fill input array with actual data sent to inlet
for (i=0;i<quantiINs;i++)
! x->input[i] = atom_getfloat(argv++);
for (i=0;i<quantiOUTs;i++)
! x->out_float[i] = atom_getfloat(argv++);
//fann_reset_MSE(x->ann);
! fann_train(x->ann, x->input, x->out_float);
mse = fann_get_MSE(x->ann);
outlet_float(x->f_out, mse);
}
***************
*** 347,379 ****
}
! static void ann_mlp_set_filename(t_ann_mlp *x, t_symbol *sl, int argc, t_atom *argv)
{
! if (argc>0) {
! x->filename = atom_gensym(argv);
! } else
! {
! error("you must specify the filename");
! }
! post("nn:filename set to %s", x->filename->s_name);
}
! static void ann_mlp_load_ann_from_file(t_ann_mlp *x, t_symbol *sl, int argc, t_atom *argv)
{
! if (argc>0) {
! x->filename = atom_gensym(argv);
! }
! x->ann = fann_create_from_file(x->filename->s_name);
! if (x->ann == 0)
! error("error opening %s", x->filename->s_name);
! else
! post("nn:ann loaded fom file %s", x->filename->s_name);
}
! static void ann_mlp_save_ann_to_file(t_ann_mlp *x, t_symbol *sl, int argc, t_atom *argv)
{
! if (argc>0) {
! x->filename = atom_gensym(argv);
! }
! if (x->ann == 0)
{
error("ann is not initialized");
--- 382,436 ----
}
! static void ann_mlp_set_filename(t_ann_mlp *x, t_symbol *s)
{
! // make correct path
! char patcher_path[MAXPDSTRING];
! char filename[MAXPDSTRING];
!
! if(!s)
! return;
!
! // make correct path
! canvas_makefilename(x->x_canvas, s->s_name, patcher_path, MAXPDSTRING);
! sys_bashfilename(patcher_path, filename);
! x->filename = gensym(filename);
}
! static void ann_mlp_load_ann_from_file(t_ann_mlp *x, t_symbol *s)
{
! ann_mlp_set_filename(x,s);
!
! if(!x->filename)
! {
! error("ann: no filename !!!");
! return;
! }
!
! // deallocate storage
! if(x->ann)
! ann_mlp_free(x);
!
! x->ann = fann_create_from_file(x->filename->s_name);
!
! if (x->ann == 0)
! error("error opening %s", x->filename->s_name);
! else
! post("nn:ann loaded fom file %s", x->filename->s_name);
!
! // allocate storage
! ann_mlp_allocate_storage(x);
}
! static void ann_mlp_save_ann_to_file(t_ann_mlp *x, t_symbol *s)
{
! ann_mlp_set_filename(x,s);
!
! if(!x->filename)
! {
! error("ann: no filename !!!");
! return;
! }
!
! if (x->ann == 0)
{
error("ann is not initialized");
***************
*** 467,470 ****
--- 524,621 ----
}
+ static void ann_mlp_set_activation_function_hidden(t_ann_mlp *x, t_symbol *sl, int argc, t_atom *argv)
+ {
+ t_symbol *parametro = 0;
+ int funzione = 0;
+
+ if (x->ann == 0)
+ {
+ error("ann not initialized");
+ return;
+ }
+
+ if (argc>0) {
+ parametro = atom_gensym(argv);
+ if (strcmp(parametro->s_name, "FANN_THRESHOLD")==0)
+ funzione = FANN_THRESHOLD;
+ if (strcmp(parametro->s_name, "FANN_THRESHOLD_SYMMETRIC")==0)
+ funzione = FANN_THRESHOLD_SYMMETRIC;
+ if (strcmp(parametro->s_name, "FANN_LINEAR")==0)
+ funzione = FANN_LINEAR;
+ if (strcmp(parametro->s_name, "FANN_SIGMOID")==0)
+ funzione = FANN_SIGMOID;
+ if (strcmp(parametro->s_name, "FANN_SIGMOID_STEPWISE")==0)
+ funzione = FANN_SIGMOID_STEPWISE;
+ if (strcmp(parametro->s_name, "FANN_SIGMOID_SYMMETRIC")==0)
+ funzione = FANN_SIGMOID_SYMMETRIC;
+ if (strcmp(parametro->s_name, "FANN_SIGMOID_SYMMETRIC_STEPWISE")==0)
+ funzione = FANN_SIGMOID_SYMMETRIC_STEPWISE;
+ fann_set_activation_function_hidden(x->ann, funzione);
+ } else
+ {
+ error("you must specify the activation function");
+ }
+ post("nn:activation function set to %s (%i)", parametro->s_name, funzione);
+
+ }
+
+ static void ann_mlp_randomize_weights(t_ann_mlp *x, t_symbol *sl, int argc, t_atom *argv)
+ {
+ t_float min = -1;
+ t_float max = 1;
+
+ if(!x->ann)
+ {
+ post("ann_mlp: ann is not initialized");
+ return;
+ }
+
+ if (argc>0)
+ min = atom_getfloat(argv++);
+
+ if (argc>1)
+ max = atom_getfloat(argv++);
+
+ fann_randomize_weights(x->ann, min, max);
+ }
+
+ static void ann_mlp_learnrate(t_ann_mlp *x, t_float f)
+ {
+ int learnrate = 0;
+
+ if(!x->ann)
+ {
+ post("ann_mlp: ann is not initialized");
+ return;
+ }
+
+ learnrate = (f<0) ? 0 : f;
+ fann_set_learning_rate(x->ann, learnrate);
+ }
+
+ static void ann_mlp_set_activation_steepness_hidden(t_ann_mlp *x, t_float f)
+ {
+ if(!x->ann)
+ {
+ post("ann_mlp: ann is not initialized");
+ return;
+ }
+
+ fann_set_activation_steepness_hidden(x->ann, f);
+ }
+
+ static void ann_mlp_set_activation_steepness_output(t_ann_mlp *x, t_float f)
+ {
+ if(!x->ann)
+ {
+ post("ann_mlp: ann is not initialized");
+ return;
+ }
+
+ fann_set_activation_steepness_output(x->ann, f);
+ }
+
+ void fann_set_activation_steepness_hidden(struct fann * ann, fann_type steepness);
+
static void ann_mlp_print_ann_details(t_ann_mlp *x)
{
***************
*** 492,495 ****
--- 643,657 ----
}
+ static void ann_mlp_print_ann_print(t_ann_mlp *x)
+ {
+ if(!x->ann)
+ {
+ post("ann_mlp: ann is not initialized");
+ return;
+ }
+
+ fann_print_connections(x->ann);
+ fann_print_parameters(x->ann);
+ }
static void *ann_mlp_new(t_symbol *s, int argc, t_atom *argv)
***************
*** 503,510 ****
x->iterations_between_reports = 1000;
x->mode=RUN;
if (argc>0) {
x->filename = atom_gensym(argv);
! ann_mlp_load_ann_from_file(x, NULL , 0, NULL);
}
--- 665,679 ----
x->iterations_between_reports = 1000;
x->mode=RUN;
+ x->x_canvas = canvas_getcurrent();
+ x->filename = NULL;
+ x->filenametrain = NULL;
+ x->ann = NULL;
+ x->input = NULL;
+ x->output = NULL;
+ x->out_float = NULL;
if (argc>0) {
x->filename = atom_gensym(argv);
! ann_mlp_load_ann_from_file(x, NULL);
}
***************
*** 512,523 ****
}
- // free resources
- static void ann_mlp_free(t_ann_mlp *x)
- {
- struct fann *ann = x->ann;
- fann_destroy(ann);
- // TODO: free other resources!
- }
-
void ann_mlp_setup(void) {
post("");
--- 681,684 ----
***************
*** 539,548 ****
class_addmethod(ann_mlp_class, (t_method)ann_mlp_run, gensym("run"), 0);
class_addmethod(ann_mlp_class, (t_method)ann_mlp_set_mode, gensym("setmode"), A_GIMME, 0);
! class_addmethod(ann_mlp_class, (t_method)ann_mlp_train_on_file, gensym("train-on-file"), A_GIMME, 0);
class_addmethod(ann_mlp_class, (t_method)ann_mlp_manage_list, gensym("data"), A_GIMME, 0);
! class_addmethod(ann_mlp_class, (t_method)ann_mlp_set_filename, gensym("filename"), A_GIMME, 0);
! class_addmethod(ann_mlp_class, (t_method)ann_mlp_load_ann_from_file, gensym("load"),A_GIMME, 0);
! class_addmethod(ann_mlp_class, (t_method)ann_mlp_save_ann_to_file, gensym("save"),A_GIMME, 0);
class_addmethod(ann_mlp_class, (t_method)ann_mlp_print_ann_details, gensym("details"), 0);
// change training parameters
--- 700,710 ----
class_addmethod(ann_mlp_class, (t_method)ann_mlp_run, gensym("run"), 0);
class_addmethod(ann_mlp_class, (t_method)ann_mlp_set_mode, gensym("setmode"), A_GIMME, 0);
! class_addmethod(ann_mlp_class, (t_method)ann_mlp_train_on_file, gensym("train-on-file"), A_DEFSYMBOL, 0);
class_addmethod(ann_mlp_class, (t_method)ann_mlp_manage_list, gensym("data"), A_GIMME, 0);
! class_addmethod(ann_mlp_class, (t_method)ann_mlp_set_filename, gensym("filename"), A_DEFSYMBOL, 0);
! class_addmethod(ann_mlp_class, (t_method)ann_mlp_load_ann_from_file, gensym("load"),A_DEFSYMBOL, 0);
! class_addmethod(ann_mlp_class, (t_method)ann_mlp_save_ann_to_file, gensym("save"),A_DEFSYMBOL, 0);
class_addmethod(ann_mlp_class, (t_method)ann_mlp_print_ann_details, gensym("details"), 0);
+ class_addmethod(ann_mlp_class, (t_method)ann_mlp_print_ann_print, gensym("print"), 0);
// change training parameters
***************
*** 550,553 ****
--- 712,716 ----
class_addmethod(ann_mlp_class, (t_method)ann_mlp_set_max_iterations, gensym("max_iterations"),A_GIMME, 0);
class_addmethod(ann_mlp_class, (t_method)ann_mlp_set_iterations_between_reports, gensym("iterations_between_reports"),A_GIMME, 0);
+ class_addmethod(ann_mlp_class, (t_method)ann_mlp_learnrate, gensym("learnrate"), A_FLOAT, 0);
// change training and activation algorithms
***************
*** 557,561 ****
--- 720,730 ----
class_addmethod(ann_mlp_class, (t_method)ann_mlp_set_FANN_TRAIN_QUICKPROP, gensym("FANN_TRAIN_QUICKPROP"), 0);
class_addmethod(ann_mlp_class, (t_method)ann_mlp_set_activation_function_output, gensym("set_activation_function_output"),A_GIMME, 0);
+ class_addmethod(ann_mlp_class, (t_method)ann_mlp_set_activation_function_hidden, gensym("set_activation_function_hidden"),A_GIMME, 0);
+ class_addmethod(ann_mlp_class, (t_method)ann_mlp_set_activation_steepness_hidden, gensym("set_activation_steepness_hidden"), A_FLOAT, 0);
+ class_addmethod(ann_mlp_class, (t_method)ann_mlp_set_activation_steepness_output, gensym("set_activation_steepness_output"), A_FLOAT, 0);
+ // initialization:
+ class_addmethod(ann_mlp_class, (t_method)ann_mlp_randomize_weights, gensym("randomize_weights"),A_GIMME, 0);
+
// the most important one: running the ann
class_addlist(ann_mlp_class, (t_method)ann_mlp_manage_list);
- Previous message: [PD-cvs] externals/hcs/purepd delta.pd, NONE, 1.1 float_argument.pd, NONE, 1.1 inv.pd, NONE, 1.1 oneshot.pd, NONE, 1.1 symbol_argument.pd, NONE, 1.1 velocity.pd, NONE, 1.1
- Next message: [PD-cvs] externals/ann/src ann_mlp.c,1.9,1.10
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Pd-cvs
mailing list