//========================================================== // ANN_AddLayer() //---------------------------------------------------------- /// Low-level code to add a weighted sum layer Layer *ANN_AddLayer(ANN * ann, int n_inputs, int n_outputs, real * x) { Layer *l = NULL; if ((x == NULL) && (ann->c->n)) { Swarning ("Layer connects to null but layer list is not empty\n"); } if (!(l = AllocM(Layer, 1))) { Serror("Could not allocate layer structure\n"); return NULL; } assert(n_inputs > 0); assert(n_outputs > 0); l->n_inputs = n_inputs; l->n_outputs = n_outputs; l->x = x; l->a = ann->a; l->zeta = ann->zeta; l->lambda = ann->lambda; l->forward = &ANN_CalculateLayerOutputs; l->backward = &ANN_Backpropagate; l->f = &htan; l->f_d = &htan_d; //l->f = &dtan; // l->f_d = &dtan_d; l->batch_mode = false; if (!(l->y = AllocM(real, n_outputs))) { Serror("Could not allocate layer outputs\n"); ANN_FreeLayer(l); return NULL; } int i; for (i=0; i<n_outputs; i++) { l->y[i] = 0.0; } if (!(l->z = AllocM(real, n_outputs))) { Serror("Could not allocate layer activations\n"); ANN_FreeLayer(l); return NULL; } for (i=0; i<n_outputs; i++) { l->z[i] = 0.0; } if (!(l->d = AllocM(real, n_inputs + 1 /*bias */ ))) { Serror("Could not allocate layer outputs\n"); ANN_FreeLayer(l); return NULL; } for (i=0; i<n_inputs+1; i++) { l->d[i] = 0.0; } if (! (l->c = AllocM(Connection, (n_inputs + 1 /*bias */ ) * n_outputs))) { Serror("Could not allocate connections\n"); ANN_FreeLayer(l); return NULL; } l->rbf = NULL; real bound = 2.0f / sqrt((real) n_inputs); for (i = 0; i < n_inputs + 1 /*bias */ ; i++) { Connection *c = &l->c[i * n_outputs]; for (int j = 0; j < n_outputs; j++) { c->w = (urandom() - 0.5f)* bound;; c->c = 1; c->e = 0.0f; c->dw = 0.0f; c->v = 1.0; c++; } } ListAppend(ann->c, (void *) l, &ANN_FreeLayer); return l; }
//========================================================== // ANN_AddRBFLayer() //---------------------------------------------------------- /// Low-level code to add an RBF layer Layer *ANN_AddRBFLayer(ANN * ann, int n_inputs, int n_outputs, real * x) { Layer *l = NULL; if ((x == NULL) && (ann->c->n)) { Swarning ("Layer connects to null and layer list not empty\n"); } if (!(l = AllocM(Layer, 1))) { Serror("Could not allocate layer structure\n"); return NULL; } assert(n_inputs > 0); assert(n_outputs > 0); l->n_inputs = n_inputs; l->n_outputs = n_outputs; l->x = x; l->a = ann->a; l->forward = &ANN_RBFCalculateLayerOutputs; l->backward = &ANN_RBFBackpropagate; l->f = &Exp; l->f_d = &Exp_d; l->batch_mode = false; if (!(l->y = AllocM(real, n_outputs))) { Serror("Could not allocate layer outputs\n"); ANN_FreeLayer(l); return NULL; } if (!(l->z = AllocM(real, n_outputs))) { Serror("Could not allocate layer activations\n"); ANN_FreeLayer(l); return NULL; } if (!(l->d = AllocM(real, n_inputs + 1 /*bias */ ))) { Serror("Could not allocate layer outputs\n"); ANN_FreeLayer(l); return NULL; } if (! (l->rbf = AllocM(RBFConnection, (n_inputs + 1 /*bias */ ) * n_outputs))) { Serror("Could not allocate connections\n"); ANN_FreeLayer(l); return NULL; } l->c = NULL; real bound = 2.0f / sqrt((real) n_inputs); for (int i = 0; i < n_inputs + 1 /*bias */ ; i++) { RBFConnection *c = &l->rbf[i * n_outputs]; for (int j = 0; j < n_outputs; j++) { c->w = (urandom() - 0.5f) * bound;; c->m = (urandom() - 0.5f) * 2.0f; c++; } } ListAppend(ann->c, (void *) l, &ANN_FreeLayer); return l; }