/// Save the ANN to a C file handle. int SaveANN(ANN* ann, FILE* f) { if (f==NULL) { return -1; } StringBuffer* rtag = NewStringBuffer (256); WriteToken("VSOUND_ANN", f); fwrite(&ann->n_inputs, sizeof(int), 1, f); fwrite(&ann->n_outputs, sizeof(int), 1, f); WriteToken("Layer Data", f); int n_layers = 0; LISTITEM* list_item = FirstListItem(ann->c); while (list_item) { n_layers++; list_item = NextListItem (ann->c); } fwrite(&n_layers, sizeof(int), 1, f); list_item = FirstListItem(ann->c); for (int i=0; i<n_layers-1; i++) { Layer* l = (Layer*) list_item->obj; int layer_type = 0; WriteToken("TYPE", f); fwrite(&layer_type, sizeof(int), 1, f); int nhu = l->n_outputs; WriteToken("UNITS", f); fwrite(&nhu, sizeof(int), 1, f); list_item = NextListItem (ann->c); } WriteToken("Output Type", f); { int layer_type = 0; LISTITEM *c; c = LastListItem(ann->c); if (c) { Layer *l = (Layer *) c->obj; if (l->f==&linear) { layer_type = 0; } else { layer_type = 1; } } fwrite(&layer_type, sizeof(int), 1, f); } list_item = FirstListItem(ann->c); while(list_item) { Layer* l = (Layer*) list_item->obj; WriteToken("Connections", f); int size = (l->n_inputs + 1 /*bias*/) * l->n_outputs; fwrite(l->c, size, sizeof(Connection), f); list_item = NextListItem(ann->c); } WriteToken("END", f); FreeStringBuffer (&rtag); return 0; }
//========================================================== // ANN_BatchAdapt //---------------------------------------------------------- /// Adapt the parameters after a series of patterns has been seen. void ANN_BatchAdapt(ANN * ann) { LISTITEM *c; c = FirstListItem(ann->c); while (c) { Layer *l = (Layer *) c->obj; ANN_LayerBatchAdapt(l); c = NextListItem(ann->c); } }
//========================================================== // ANN_ShowInputs() //---------------------------------------------------------- /// Dump inputs to all layers on stdout. real ANN_ShowInputs(ANN * ann) { LISTITEM *c; real sum = 0.0f; c = FirstListItem(ann->c); while (c) { Layer *l = (Layer *) c->obj; sum += ANN_LayerShowInputs(l); c = NextListItem(ann->c); } return sum; }
//========================================================== // ANN_SetBatchMode //---------------------------------------------------------- /// Set batch updates. void ANN_SetBatchMode(ANN * ann, bool batch) { LISTITEM *c; ann->batch_mode = batch; c = FirstListItem(ann->c); while (c) { Layer *l = (Layer *) c->obj; l->batch_mode = batch; c = NextListItem(ann->c); } }
//========================================================== // ANN_SetZeta() //---------------------------------------------------------- /// Set zeta, parameter variance smoothing. Useful for /// ANN_StochasticInput() void ANN_SetZeta(ANN * ann, real zeta) { LISTITEM *c; ann->zeta = zeta; c = FirstListItem(ann->c); while (c) { Layer *l = (Layer *) c->obj; l->zeta = zeta; c = NextListItem(ann->c); } }
//========================================================== // ANN_SetLambda() //---------------------------------------------------------- /// Set lambda, eligibility decay. void ANN_SetLambda(ANN * ann, real lambda) { LISTITEM *c; ann->lambda = lambda; c = FirstListItem(ann->c); while (c) { Layer *l = (Layer *) c->obj; l->lambda = lambda; c = NextListItem(ann->c); } }
//========================================================== // ANN_SetLearningRate() //---------------------------------------------------------- /// Set the learning rate to a void ANN_SetLearningRate(ANN * ann, real a) { LISTITEM *c; ann->a = a; c = FirstListItem(ann->c); while (c) { Layer *l = (Layer *) c->obj; l->a = a; c = NextListItem(ann->c); } }
/// Load the ANN from a C file handle. ANN* LoadANN(FILE* f) { if (f==NULL) { return NULL; } StringBuffer* rtag = NewStringBuffer (256); CheckMatchingToken("VSOUND_ANN", rtag, f); int n_inputs; int n_outputs; fread(&n_inputs, sizeof(int), 1, f); fread(&n_outputs, sizeof(int), 1, f); ANN* ann = NewANN (n_inputs, n_outputs); CheckMatchingToken("Layer Data", rtag, f); int n_layers; fread(&n_layers, sizeof(int), 1, f); for (int i=0; i<n_layers-1; i++) { int layer_type; CheckMatchingToken("TYPE", rtag, f); fread(&layer_type, sizeof(int), 1, f); int nhu; CheckMatchingToken("UNITS", rtag, f); fread(&nhu, sizeof(int), 1, f); if (layer_type==0) { ANN_AddHiddenLayer(ann, nhu); } else { ANN_AddRBFHiddenLayer(ann, nhu); } } { int layer_type =0; ANN_Init(ann); CheckMatchingToken("Output Type", rtag, f); fread(&layer_type, sizeof(int), 1, f); if (layer_type==0) { ANN_SetOutputsToLinear(ann); } else { ANN_SetOutputsToTanH(ann); } } LISTITEM* list_item = FirstListItem(ann->c); while (list_item) { Layer* l = (Layer*) list_item->obj; CheckMatchingToken("Connections", rtag, f); int size = (l->n_inputs + 1 /*bias*/) * l->n_outputs; fread(l->c, size, sizeof(Connection), f); list_item = NextListItem (ann->c); } CheckMatchingToken("END", rtag, f); FreeStringBuffer (&rtag); return ann; }
//========================================================== // ANN_StochasticInput() //---------------------------------------------------------- /// Stochastically generate an output, depending on parameter /// distributions. /// This is an option for people that understand what they /// are doing. real ANN_StochasticInput(ANN * ann, real * x) { LISTITEM *p = FirstListItem(ann->c); Layer *first_layer = (Layer *) p->obj; ann->x = x; first_layer->x = x; // Setup input of first layer // printf ("II: %f\n", ann->x[0]); while (p) { Layer *current_layer = (Layer *) p->obj; // printf ("\tIII: %f\n", current_layer->x[0]); current_layer->forward(current_layer, true); p = NextListItem(ann->c); } return 0.0f; }
//========================================================== // ANN_Reset() //---------------------------------------------------------- /// Resets the eligbility traces and batch updates. void ANN_Reset(ANN * ann) { LISTITEM *p = FirstListItem(ann->c); while (p) { Layer *l = (Layer *) p->obj; for (int i = 0; i < l->n_inputs + 1 /* bias */; i++) { Connection *c = &l->c[i * l->n_outputs]; for (int j = 0; j < l->n_outputs; j++) { c->e = 0.0; c->dw = 0.0; c++; } } p = NextListItem (ann->c); } }