mirror of
https://github.com/BlackLight/neuralpp.git
synced 2024-11-15 22:37:15 +01:00
Adding sources
This commit is contained in:
parent
d5ae063483
commit
9477b27154
7 changed files with 6435 additions and 0 deletions
1252
src/Doxyfile
Normal file
1252
src/Doxyfile
Normal file
File diff suppressed because it is too large
Load diff
4127
src/Markup.cpp
Normal file
4127
src/Markup.cpp
Normal file
File diff suppressed because it is too large
Load diff
102
src/layer.cpp
Normal file
102
src/layer.cpp
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
/**************************************************************************************************
|
||||||
|
* LibNeural++ v.0.2 - All-purpose library for managing neural networks *
|
||||||
|
* Copyright (C) 2009, BlackLight *
|
||||||
|
* *
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the *
|
||||||
|
* GNU General Public License as published by the Free Software Foundation, either version 3 of *
|
||||||
|
* the License, or (at your option) any later version. This program is distributed in the hope *
|
||||||
|
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
|
||||||
|
* more details. You should have received a copy of the GNU General Public License along with *
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
|
**************************************************************************************************/
|
||||||
|
|
||||||
|
#include "neural++.h"
|
||||||
|
using namespace neuralpp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
* @param sz Size of the layer
|
||||||
|
* @param a Activation function
|
||||||
|
* @param d Its derivate
|
||||||
|
*/
|
||||||
|
Layer::Layer (size_t sz, float(*a)(float), float(*d)(float)) {
|
||||||
|
for (size_t i=0; i<sz; i++) {
|
||||||
|
Neuron n(a,d);
|
||||||
|
elements.push_back(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
actv_f=a;
|
||||||
|
deriv=d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Alternative constructor. It directly gets a vector of neurons to build
|
||||||
|
* the layer
|
||||||
|
*/
|
||||||
|
Layer::Layer (vector< Neuron > &el, float (*a)(float), float(*d)(float)) {
|
||||||
|
elements=el;
|
||||||
|
actv_f=a;
|
||||||
|
deriv=d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Number of neurons in the layer
|
||||||
|
*/
|
||||||
|
size_t Layer::size() { return elements.size(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Redefinition for operator []. It gets the neuron at <i>i</i>
|
||||||
|
*/
|
||||||
|
Neuron& Layer::operator[] (size_t i) { return elements[i]; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It links a layer to another
|
||||||
|
* @param l Layer to connect to the current as input layer
|
||||||
|
*/
|
||||||
|
void Layer::link (Layer& l) {
|
||||||
|
srand ((unsigned) time(NULL));
|
||||||
|
|
||||||
|
for (size_t i=0; i<l.size(); i++) {
|
||||||
|
Neuron *n1 = &(l.elements[i]);
|
||||||
|
|
||||||
|
for (size_t j=0; j<size(); j++) {
|
||||||
|
Neuron *n2 = &(elements[j]);
|
||||||
|
Synapsis s(n1,n2,RAND,actv_f,deriv);
|
||||||
|
|
||||||
|
n1->push_out(s);
|
||||||
|
n2->push_in(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It sets a vector of propagation values to all its neurons
|
||||||
|
* @param v Vector of values to write as propagation values
|
||||||
|
*/
|
||||||
|
void Layer::setProp (vector<float> &v) {
|
||||||
|
for (size_t i=0; i<size(); i++)
|
||||||
|
elements[i].setProp(v[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It sets a vector of activation values to all its neurons
|
||||||
|
* @param v Vector of values to write as activation values
|
||||||
|
*/
|
||||||
|
void Layer::setActv (vector<float> &v) {
|
||||||
|
for (size_t i=0; i<size(); i++)
|
||||||
|
elements[i].setActv(v[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It propagates its activation values to the output layers
|
||||||
|
*/
|
||||||
|
void Layer::propagate() {
|
||||||
|
for (size_t i=0; i<size(); i++) {
|
||||||
|
Neuron *n = &(elements[i]);
|
||||||
|
|
||||||
|
n->setProp(n->propagate());
|
||||||
|
n->setActv( actv_f(n->getProp()) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
194
src/neural_doc.h
Normal file
194
src/neural_doc.h
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
/**************************************************************************************************
|
||||||
|
* LibNeural++ v.0.2 - All-purpose library for managing neural networks *
|
||||||
|
* Copyright (C) 2009, BlackLight *
|
||||||
|
* *
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the *
|
||||||
|
* GNU General Public License as published by the Free Software Foundation, either version 3 of *
|
||||||
|
* the License, or (at your option) any later version. This program is distributed in the hope *
|
||||||
|
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
|
||||||
|
* more details. You should have received a copy of the GNU General Public License along with *
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
|
**************************************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __NEURALPP
|
||||||
|
#define __NEURALPP
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <cmath>
|
||||||
|
#include <ctime>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace neuralpp {
|
||||||
|
//! Default rand value: |sin(rand)|, always >= 0 and <= 1
|
||||||
|
#define RAND ( (float) abs( sinf((float) rand()) ) )
|
||||||
|
|
||||||
|
class Synapsis;
|
||||||
|
class Neuron;
|
||||||
|
class Layer;
|
||||||
|
class NeuralNet;
|
||||||
|
class NetworkFileNotFoundException;
|
||||||
|
class InvalidXMLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class NetworkFileNotFoundException
|
||||||
|
* @brief Exception thrown when doing an attempt to load a network from an invalid file
|
||||||
|
*/
|
||||||
|
class NetworkFileNotFoundException : public exception {
|
||||||
|
public:
|
||||||
|
NetworkFileNotFoundException() {}
|
||||||
|
const char* what() const throw() { return strdup("Attempt to load a neural network from an invalid network file\n"); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class InvalidXMLException
|
||||||
|
* @brief Exception thrown when trying parsing an invalid XML
|
||||||
|
*/
|
||||||
|
class InvalidXMLException : public exception {
|
||||||
|
public:
|
||||||
|
InvalidXMLException() {}
|
||||||
|
const char* what() const throw() { return strdup("Attempt to load an invalid XML file\n"); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class NeuralNet
|
||||||
|
* @brief Main project's class. Use *ONLY* this class, unless you know what you're doing
|
||||||
|
*/
|
||||||
|
class NeuralNet {
|
||||||
|
int epochs;
|
||||||
|
float l_rate;
|
||||||
|
float ex;
|
||||||
|
|
||||||
|
Layer* input;
|
||||||
|
Layer* hidden;
|
||||||
|
Layer* output;
|
||||||
|
|
||||||
|
void updateWeights();
|
||||||
|
void commitChanges (Layer *l);
|
||||||
|
float error(float);
|
||||||
|
|
||||||
|
float (*actv_f)(float);
|
||||||
|
float (*deriv)(float);
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Enum to choose the eventual training source for our network (XML from a file or from a string)
|
||||||
|
*/
|
||||||
|
typedef enum { file, str } source;
|
||||||
|
|
||||||
|
NeuralNet (size_t, size_t, size_t, float, int);
|
||||||
|
NeuralNet (size_t, size_t, size_t, float(*)(float), float(*)(float), float, int);
|
||||||
|
NeuralNet (const char*) throw();
|
||||||
|
|
||||||
|
float getOutput();
|
||||||
|
float expected();
|
||||||
|
|
||||||
|
vector<float> getVectorOutput();
|
||||||
|
|
||||||
|
void setExpected(float);
|
||||||
|
void update();
|
||||||
|
void propagate();
|
||||||
|
void setInput (vector<float>&);
|
||||||
|
void link();
|
||||||
|
bool save (const char*);
|
||||||
|
void train(string, source) throw();
|
||||||
|
|
||||||
|
static vector<float> split (char, string);
|
||||||
|
static void initXML (string&);
|
||||||
|
static string XMLFromSet (int, string);
|
||||||
|
static void closeXML(string&);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Synapsis
|
||||||
|
* @brief Class for managing synapsis. Don't use this class directly unless you know what
|
||||||
|
* you're doing, use NeuralNet instead
|
||||||
|
*/
|
||||||
|
class Synapsis {
|
||||||
|
float delta;
|
||||||
|
float weight;
|
||||||
|
|
||||||
|
Neuron *in;
|
||||||
|
Neuron *out;
|
||||||
|
|
||||||
|
float (*actv_f)(float);
|
||||||
|
float (*deriv)(float);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Synapsis (Neuron* i, Neuron* o, float(*)(float), float(*)(float));
|
||||||
|
Synapsis (Neuron* i, Neuron* o, float w, float(*)(float), float(*)(float));
|
||||||
|
|
||||||
|
Neuron* getIn();
|
||||||
|
Neuron* getOut();
|
||||||
|
|
||||||
|
void setWeight(float);
|
||||||
|
void setDelta(float);
|
||||||
|
|
||||||
|
float getWeight();
|
||||||
|
float getDelta();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Neuron
|
||||||
|
* @brief Class for managing neurons. Don't use this class directly unless you know what
|
||||||
|
* you're doing, use NeuralNet instead
|
||||||
|
*/
|
||||||
|
class Neuron {
|
||||||
|
float actv_val;
|
||||||
|
float prop_val;
|
||||||
|
|
||||||
|
vector< Synapsis > in;
|
||||||
|
vector< Synapsis > out;
|
||||||
|
|
||||||
|
float (*actv_f)(float);
|
||||||
|
float (*deriv)(float);
|
||||||
|
public:
|
||||||
|
Neuron (float (*)(float), float(*)(float));
|
||||||
|
Neuron (vector< Synapsis >, vector< Synapsis >, float (*)(float), float(*)(float));
|
||||||
|
|
||||||
|
Synapsis& synIn (size_t i);
|
||||||
|
Synapsis& synOut (size_t i);
|
||||||
|
|
||||||
|
void push_in (Synapsis&);
|
||||||
|
void push_out (Synapsis&);
|
||||||
|
|
||||||
|
void setActv (float);
|
||||||
|
void setProp (float);
|
||||||
|
|
||||||
|
float getActv();
|
||||||
|
float getProp();
|
||||||
|
float propagate();
|
||||||
|
|
||||||
|
|
||||||
|
size_t nIn();
|
||||||
|
size_t nOut();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Layer
|
||||||
|
* @brief Class for managing layers of neurons. Don't use this class directly unless you know what
|
||||||
|
* you're doing, use NeuralNet instead
|
||||||
|
*/
|
||||||
|
class Layer {
|
||||||
|
vector< Neuron > elements;
|
||||||
|
void (*update_weights)();
|
||||||
|
|
||||||
|
float (*actv_f)(float);
|
||||||
|
float (*deriv)(float);
|
||||||
|
public:
|
||||||
|
Layer (size_t sz, float (*)(float), float(*)(float));
|
||||||
|
Layer (vector< Neuron >&, float(*)(float), float(*)(float));
|
||||||
|
|
||||||
|
Neuron& operator[] (size_t);
|
||||||
|
|
||||||
|
void link (Layer&);
|
||||||
|
void setProp (vector<float>&);
|
||||||
|
void setActv (vector<float>&);
|
||||||
|
void propagate();
|
||||||
|
|
||||||
|
size_t size();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
578
src/neuralnet.cpp
Normal file
578
src/neuralnet.cpp
Normal file
|
@ -0,0 +1,578 @@
|
||||||
|
/**************************************************************************************************
|
||||||
|
* LibNeural++ v.0.2 - All-purpose library for managing neural networks *
|
||||||
|
* Copyright (C) 2009, BlackLight *
|
||||||
|
* *
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the *
|
||||||
|
* GNU General Public License as published by the Free Software Foundation, either version 3 of *
|
||||||
|
* the License, or (at your option) any later version. This program is distributed in the hope *
|
||||||
|
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
|
||||||
|
* more details. You should have received a copy of the GNU General Public License along with *
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
|
**************************************************************************************************/
|
||||||
|
|
||||||
|
#include "neural++.h"
|
||||||
|
#include "Markup.h"
|
||||||
|
#include <iostream>
|
||||||
|
using namespace neuralpp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Built-in function. The default activation function: f(x)=x
|
||||||
|
*/
|
||||||
|
float __actv(float prop) { return prop; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Default derivate for default activation function: f'(x)=1
|
||||||
|
*/
|
||||||
|
float __deriv(float prop) { return 1; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
* @param in_size Size of the input layer
|
||||||
|
* @param hidden_size Size of the hidden layer
|
||||||
|
* @param out_size Size of the output layer
|
||||||
|
* @param l learn rate (get it after doing some experiments, but generally try to
|
||||||
|
* keep its value quite low to be more accurate)
|
||||||
|
* @param e Epochs (cycles) to execute (the most you execute, the most the network
|
||||||
|
* can be accurate for its purpose)
|
||||||
|
*/
|
||||||
|
NeuralNet::NeuralNet (size_t in_size, size_t hidden_size, size_t out_size, float l, int e) {
|
||||||
|
epochs=e;
|
||||||
|
ref_epochs=epochs;
|
||||||
|
l_rate=l;
|
||||||
|
actv_f=__actv;
|
||||||
|
deriv=__deriv;
|
||||||
|
|
||||||
|
input = new Layer(in_size, __actv, __deriv);
|
||||||
|
hidden = new Layer(hidden_size, __actv, __deriv);
|
||||||
|
output = new Layer(out_size, __actv, __deriv);
|
||||||
|
link();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
* @param in_size Size of the input layer
|
||||||
|
* @param hidden_size Size of the hidden layer
|
||||||
|
* @param out_size Size of the output layer
|
||||||
|
* @param actv Activation function to use (default: f(x)=x)
|
||||||
|
* @param deriv Derivate for the activation function to use (default: f'(x)=1)
|
||||||
|
* @param l learn rate (get it after doing some experiments, but generally try to
|
||||||
|
* keep its value quite low to be more accurate)
|
||||||
|
* @param e Epochs (cycles) to execute (the most you execute, the most the network
|
||||||
|
* can be accurate for its purpose)
|
||||||
|
*/
|
||||||
|
NeuralNet::NeuralNet (size_t in_size, size_t hidden_size, size_t out_size,
|
||||||
|
float(*a)(float), float(*d)(float), float l, int e) {
|
||||||
|
epochs=e;
|
||||||
|
ref_epochs=epochs;
|
||||||
|
l_rate=l;
|
||||||
|
|
||||||
|
actv_f=a;
|
||||||
|
deriv=d;
|
||||||
|
|
||||||
|
input = new Layer(in_size,a,d);
|
||||||
|
hidden = new Layer(hidden_size,a,d);
|
||||||
|
output = new Layer(out_size,a,d);
|
||||||
|
link();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It gets the output of the network (note: the layer output should contain
|
||||||
|
* an only neuron)
|
||||||
|
*/
|
||||||
|
float NeuralNet::getOutput() { return (*output)[0].getActv(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It gets the output of the network in case the output layer contains more neurons
|
||||||
|
*/
|
||||||
|
vector<float> NeuralNet::getVectorOutput() {
|
||||||
|
vector<float> v;
|
||||||
|
|
||||||
|
for (size_t i=0; i<output->size(); i++)
|
||||||
|
v.push_back( (*output)[i].getActv() );
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It get the error made on the expected result as |v-v'|/v
|
||||||
|
* @param Expected value
|
||||||
|
* @return Mean error
|
||||||
|
*/
|
||||||
|
float NeuralNet::error(float expected) {
|
||||||
|
return abs( (getOutput() - expected*
|
||||||
|
deriv(getOutput())) / (abs(expected)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It propagates values through the network. Use this when you want to give
|
||||||
|
* an already trained network some new values the get to the output
|
||||||
|
*/
|
||||||
|
void NeuralNet::propagate() {
|
||||||
|
hidden->propagate();
|
||||||
|
output->propagate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It sets the input for the network
|
||||||
|
* @param v Vector of floats, containing the values to give to your network
|
||||||
|
*/
|
||||||
|
void NeuralNet::setInput(vector<float>& v) {
|
||||||
|
input->setProp(v);
|
||||||
|
input->setActv(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It links the layers of the network (input, hidden, output). Don't use unless
|
||||||
|
* you exactly know what you're doing, it is already called by the constructor
|
||||||
|
*/
|
||||||
|
void NeuralNet::link() {
|
||||||
|
hidden->link(*input);
|
||||||
|
output->link(*hidden);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It sets the value you expect from your network
|
||||||
|
*/
|
||||||
|
void NeuralNet::setExpected(float e) { ex=e; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It gets the value expected. Of course you should specify this when you
|
||||||
|
* build your network by using setExpected.
|
||||||
|
*/
|
||||||
|
float NeuralNet::expected() { return ex; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It updates the weights of the net's synapsis through back-propagation.
|
||||||
|
* In-class use only
|
||||||
|
*/
|
||||||
|
void NeuralNet::updateWeights() {
|
||||||
|
float out_delta;
|
||||||
|
|
||||||
|
for (size_t i=0; i<output->size(); i++) {
|
||||||
|
Neuron *n = &(*output)[i];
|
||||||
|
|
||||||
|
for (size_t j=0; j<n->nIn(); j++) {
|
||||||
|
Synapsis *s = &(n->synIn(j));
|
||||||
|
out_delta = s->getIn()->getActv() * error(ex) * l_rate;
|
||||||
|
s->setDelta(out_delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i=0; i<hidden->size(); i++) {
|
||||||
|
Neuron *n = &(*hidden)[i];
|
||||||
|
float d = deriv(n->getProp()) * n->synOut(0).getWeight() * out_delta;
|
||||||
|
|
||||||
|
for (size_t j=0; j<n->nIn(); j++) {
|
||||||
|
Synapsis *s = &(n->synIn(j));
|
||||||
|
s->setDelta(l_rate * d * s->getIn()->getActv());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It commits the changes made by updateWeights() to the layer l.
|
||||||
|
* In-class use only
|
||||||
|
* @param l Layer to commit the changes
|
||||||
|
*/
|
||||||
|
void NeuralNet::commitChanges (Layer *l) {
|
||||||
|
for (size_t i=0; i<l->size(); i++) {
|
||||||
|
Neuron *n = &(*l)[i];
|
||||||
|
|
||||||
|
for (size_t j=0; j<n->nIn(); j++) {
|
||||||
|
Synapsis *s = &(n->synIn(j));
|
||||||
|
s->setWeight(s->getWeight() + s->getDelta());
|
||||||
|
s->setDelta(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It updates through back-propagation the weights of the synapsis and
|
||||||
|
* computes again the output value for <i>epochs</i> times, calling back
|
||||||
|
* updateWeights and commitChanges functions
|
||||||
|
*/
|
||||||
|
void NeuralNet::update() {
|
||||||
|
while ((epochs--)>0) {
|
||||||
|
updateWeights();
|
||||||
|
commitChanges(output);
|
||||||
|
commitChanges(hidden);
|
||||||
|
propagate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Save an already trained neural network to a binary file
|
||||||
|
* @param fname Name of the file to write
|
||||||
|
* @return true in case of success, false otherwise
|
||||||
|
*/
|
||||||
|
bool NeuralNet::save(const char *fname) {
|
||||||
|
FILE *fp;
|
||||||
|
struct netrecord record;
|
||||||
|
|
||||||
|
if (!(fp=fopen(fname,"wb")))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
record.input_size = input->size();
|
||||||
|
record.hidden_size = hidden->size();
|
||||||
|
record.output_size = output->size();
|
||||||
|
|
||||||
|
record.epochs = ref_epochs;
|
||||||
|
record.l_rate = l_rate;
|
||||||
|
record.ex = ex;
|
||||||
|
|
||||||
|
if (fwrite (&record, sizeof(struct netrecord), 1, fp)<=0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Saving neurons' state
|
||||||
|
for (unsigned int i=0; i < input->size(); i++) {
|
||||||
|
struct neuronrecord r;
|
||||||
|
r.prop = (*input)[i].getProp();
|
||||||
|
r.actv = (*input)[i].getActv();
|
||||||
|
fwrite (&r, sizeof(struct neuronrecord), 1, fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < hidden->size(); i++) {
|
||||||
|
struct neuronrecord r;
|
||||||
|
r.prop = (*hidden)[i].getProp();
|
||||||
|
r.actv = (*hidden)[i].getActv();
|
||||||
|
fwrite (&r, sizeof(struct neuronrecord), 1, fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < output->size(); i++) {
|
||||||
|
struct neuronrecord r;
|
||||||
|
r.prop = (*output)[i].getProp();
|
||||||
|
r.actv = (*output)[i].getActv();
|
||||||
|
fwrite (&r, sizeof(struct neuronrecord), 1, fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Saving synapsis' state
|
||||||
|
for (unsigned int i=0; i < input->size(); i++) {
|
||||||
|
int nout = (*input)[i].nOut();
|
||||||
|
fwrite (&nout, sizeof(int), 1, fp);
|
||||||
|
|
||||||
|
for (int j=0; j < nout; j++) {
|
||||||
|
struct synrecord r;
|
||||||
|
r.w = (*input)[i].synOut(j).getWeight();
|
||||||
|
r.d = (*input)[i].synOut(j).getDelta();
|
||||||
|
fwrite (&r, sizeof(struct synrecord), 1, fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < output->size(); i++) {
|
||||||
|
int nin = (*output)[i].nIn();
|
||||||
|
fwrite (&nin, sizeof(int), 1, fp);
|
||||||
|
|
||||||
|
for (int j=0; j < nin; j++) {
|
||||||
|
struct synrecord r;
|
||||||
|
r.w = (*output)[i].synIn(j).getWeight();
|
||||||
|
r.d = (*output)[i].synIn(j).getDelta();
|
||||||
|
fwrite (&r, sizeof(struct synrecord), 1, fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < hidden->size(); i++) {
|
||||||
|
int nin = (*hidden)[i].nIn();
|
||||||
|
fwrite (&nin, sizeof(int), 1, fp);
|
||||||
|
|
||||||
|
for (int j=0; j < nin; j++) {
|
||||||
|
struct synrecord r;
|
||||||
|
r.w = (*hidden)[i].synIn(j).getWeight();
|
||||||
|
r.d = (*hidden)[i].synIn(j).getDelta();
|
||||||
|
fwrite (&r, sizeof(struct synrecord), 1, fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < hidden->size(); i++) {
|
||||||
|
int nout = (*hidden)[i].nOut();
|
||||||
|
fwrite (&nout, sizeof(int), 1, fp);
|
||||||
|
|
||||||
|
for (int j=0; j < nout; j++) {
|
||||||
|
struct synrecord r;
|
||||||
|
r.w = (*hidden)[i].synOut(j).getWeight();
|
||||||
|
r.d = (*hidden)[i].synOut(j).getDelta();
|
||||||
|
fwrite (&r, sizeof(struct synrecord), 1, fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructs a neural network from a previously saved file
|
||||||
|
* (saved using 'save()' method)
|
||||||
|
* @param fname File name to load the network from
|
||||||
|
* @throw NetworkFileNotFoundException
|
||||||
|
*/
|
||||||
|
NeuralNet::NeuralNet (const char *fname) throw() {
|
||||||
|
struct netrecord record;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
if (!(fp=fopen(fname,"rb")))
|
||||||
|
throw NetworkFileNotFoundException();
|
||||||
|
|
||||||
|
if (fread(&record, sizeof(struct netrecord), 1, fp)<=0)
|
||||||
|
throw NetworkFileNotFoundException();
|
||||||
|
|
||||||
|
*this = NeuralNet(record.input_size, record.hidden_size, record.output_size, record.l_rate, record.epochs);
|
||||||
|
|
||||||
|
// Restore neurons
|
||||||
|
for (unsigned int i=0; i < input->size(); i++) {
|
||||||
|
struct neuronrecord r;
|
||||||
|
fread (&r, sizeof(struct neuronrecord), 1, fp);
|
||||||
|
|
||||||
|
(*input)[i].setProp(r.prop);
|
||||||
|
(*input)[i].setActv(r.actv);
|
||||||
|
(*input)[i].synClear();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < hidden->size(); i++) {
|
||||||
|
struct neuronrecord r;
|
||||||
|
fread (&r, sizeof(struct neuronrecord), 1, fp);
|
||||||
|
|
||||||
|
(*hidden)[i].setProp(r.prop);
|
||||||
|
(*hidden)[i].setActv(r.actv);
|
||||||
|
(*hidden)[i].synClear();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < output->size(); i++) {
|
||||||
|
struct neuronrecord r;
|
||||||
|
fread (&r, sizeof(struct neuronrecord), 1, fp);
|
||||||
|
|
||||||
|
(*output)[i].setProp(r.prop);
|
||||||
|
(*output)[i].setActv(r.actv);
|
||||||
|
(*output)[i].synClear();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < input->size(); i++)
|
||||||
|
(*input)[i].synClear();
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < hidden->size(); i++)
|
||||||
|
(*hidden)[i].synClear();
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < output->size(); i++)
|
||||||
|
(*output)[i].synClear();
|
||||||
|
|
||||||
|
hidden->link(*input);
|
||||||
|
output->link(*hidden);
|
||||||
|
|
||||||
|
// Restore synapsis
|
||||||
|
for (unsigned int i=0; i < input->size(); i++) {
|
||||||
|
int nout;
|
||||||
|
fread (&nout, sizeof(int), 1, fp);
|
||||||
|
|
||||||
|
for (int j=0; j < nout; j++) {
|
||||||
|
struct synrecord r;
|
||||||
|
fread (&r, sizeof(struct synrecord), 1, fp);
|
||||||
|
|
||||||
|
(*input)[i].synOut(j).setWeight(r.w);
|
||||||
|
(*input)[i].synOut(j).setDelta(r.d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < output->size(); i++) {
|
||||||
|
int nin;
|
||||||
|
fread (&nin, sizeof(int), 1, fp);
|
||||||
|
|
||||||
|
for (int j=0; j < nin; j++) {
|
||||||
|
struct synrecord r;
|
||||||
|
fread (&r, sizeof(struct synrecord), 1, fp);
|
||||||
|
|
||||||
|
(*output)[i].synIn(j).setWeight(r.w);
|
||||||
|
(*output)[i].synIn(j).setDelta(r.d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < hidden->size(); i++) {
|
||||||
|
int nin;
|
||||||
|
fread (&nin, sizeof(int), 1, fp);
|
||||||
|
|
||||||
|
for (int j=0; j < nin; j++) {
|
||||||
|
struct synrecord r;
|
||||||
|
fread (&r, sizeof(struct synrecord), 1, fp);
|
||||||
|
|
||||||
|
(*hidden)[i].synIn(j).setWeight(r.w);
|
||||||
|
(*hidden)[i].synIn(j).setDelta(r.d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < hidden->size(); i++) {
|
||||||
|
int nout;
|
||||||
|
fread (&nout, sizeof(int), 1, fp);
|
||||||
|
|
||||||
|
for (int j=0; j < nout; j++) {
|
||||||
|
struct synrecord r;
|
||||||
|
fread (&r, sizeof(struct synrecord), 1, fp);
|
||||||
|
|
||||||
|
(*hidden)[i].synOut(j).setWeight(r.w);
|
||||||
|
(*hidden)[i].synOut(j).setDelta(r.d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Train a network using a training set loaded from an XML file. A sample XML file
|
||||||
|
* is available in examples/adder.xml
|
||||||
|
* @param xml XML file containing our training set
|
||||||
|
* @param src Source type from which the XML will be loaded (from a file [default] or from a string)
|
||||||
|
* @throw InvalidXMLException
|
||||||
|
*/
|
||||||
|
void NeuralNet::train (string xmlsrc, NeuralNet::source src = file) throw() {
|
||||||
|
float out;
|
||||||
|
CMarkup xml;
|
||||||
|
|
||||||
|
if (src == file)
|
||||||
|
xml.Load(xmlsrc.c_str());
|
||||||
|
else
|
||||||
|
xml.SetDoc(xmlsrc.c_str());
|
||||||
|
|
||||||
|
if (!xml.IsWellFormed()) {
|
||||||
|
throw InvalidXMLException();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xml.FindElem("NETWORK")) {
|
||||||
|
while (xml.FindChildElem("TRAINING")) {
|
||||||
|
vector<float> input;
|
||||||
|
float output;
|
||||||
|
bool valid = false;
|
||||||
|
|
||||||
|
xml.IntoElem();
|
||||||
|
|
||||||
|
while (xml.FindChildElem("INPUT")) {
|
||||||
|
xml.IntoElem();
|
||||||
|
input.push_back(atof(xml.GetData().c_str()));
|
||||||
|
xml.OutOfElem();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xml.FindChildElem("OUTPUT")) {
|
||||||
|
xml.IntoElem();
|
||||||
|
output = atof(xml.GetData().c_str());
|
||||||
|
xml.OutOfElem();
|
||||||
|
}
|
||||||
|
|
||||||
|
xml.OutOfElem();
|
||||||
|
|
||||||
|
while (!valid) {
|
||||||
|
char str[BUFSIZ];
|
||||||
|
|
||||||
|
setInput(input);
|
||||||
|
propagate();
|
||||||
|
setExpected(output);
|
||||||
|
update();
|
||||||
|
|
||||||
|
out = getOutput();
|
||||||
|
memset (str, 0x0, sizeof(str));
|
||||||
|
snprintf (str, sizeof(str), "%f", out);
|
||||||
|
|
||||||
|
if (!strstr(str, "inf"))
|
||||||
|
valid=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the training XML for the neural network
|
||||||
|
* @param xml String that will contain the XML
|
||||||
|
*/
|
||||||
|
void NeuralNet::initXML (string& xml) {
|
||||||
|
xml.append("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
|
||||||
|
"<!DOCTYPE NETWORK SYSTEM \"http://blacklight.gotdns.org/prog/neuralpp/trainer.dtd\">\n"
|
||||||
|
"<!-- Automatically generated by Neural++ library - by BlackLight -->\n\n"
|
||||||
|
"<NETWORK>\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Splits a string into a vector of floats, given a delimitator
|
||||||
|
* @param delim Delimitator
|
||||||
|
* @param str String to be splitted
|
||||||
|
* @return Vector of floats containing splitted values
|
||||||
|
*/
|
||||||
|
vector<float> NeuralNet::split (char delim, string str) {
|
||||||
|
char tmp[1024];
|
||||||
|
vector<float> v;
|
||||||
|
memset (tmp, 0x0, sizeof(tmp));
|
||||||
|
|
||||||
|
for (unsigned int i=0, j=0; i <= str.length(); i++) {
|
||||||
|
if (str[i] == delim || i == str.length()) {
|
||||||
|
v.push_back(atof(tmp));
|
||||||
|
memset (tmp, 0x0, sizeof(tmp));
|
||||||
|
j=0;
|
||||||
|
} else
|
||||||
|
tmp[j++] = str[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a training set from a string and copies it to an XML
|
||||||
|
* For example, these strings could be training sets for making sums:
|
||||||
|
* "2,3;5" - "5,6;11" - "2,2;4" - "4,5:9"
|
||||||
|
* This method called on the first string will return an XML such this:
|
||||||
|
* '<training id="0"><input id="0">2</input><input id="1">3</input><output id="0">5</output>
|
||||||
|
* </training>'
|
||||||
|
*
|
||||||
|
* @param id ID for the given training set (0,1,..,n)
|
||||||
|
* @param set String containing input values and expected outputs
|
||||||
|
* @return XML string
|
||||||
|
*/
|
||||||
|
string NeuralNet::XMLFromSet (int id, string set) {
|
||||||
|
string xml;
|
||||||
|
vector<float> in, out;
|
||||||
|
unsigned int delimPos = -1;
|
||||||
|
char delim=';';
|
||||||
|
char tmp[1024];
|
||||||
|
|
||||||
|
for (delimPos=0; delimPos < set.length() && set[delimPos] != delim; delimPos++);
|
||||||
|
|
||||||
|
if (delimPos == set.length())
|
||||||
|
return xml;
|
||||||
|
|
||||||
|
string inStr = set.substr(0,delimPos);
|
||||||
|
string outStr = set.substr(delimPos+1, set.length());
|
||||||
|
|
||||||
|
in = split(',', inStr);
|
||||||
|
out = split(',', outStr);
|
||||||
|
|
||||||
|
snprintf (tmp, sizeof(tmp), "%d", id);
|
||||||
|
xml += "\t<TRAINING ID=\"" + string(tmp) + "\">\n";
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < in.size(); i++) {
|
||||||
|
memset (tmp, 0x0, sizeof(tmp));
|
||||||
|
snprintf (tmp, sizeof(tmp), "%d", i);
|
||||||
|
xml += "\t\t<INPUT ID=\"" + string(tmp) + "\">";
|
||||||
|
|
||||||
|
memset (tmp, 0x0, sizeof(tmp));
|
||||||
|
snprintf (tmp, sizeof(tmp), "%f", in[i]);
|
||||||
|
xml += string(tmp) + "</INPUT>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i=0; i < out.size(); i++) {
|
||||||
|
memset (tmp, 0x0, sizeof(tmp));
|
||||||
|
snprintf (tmp, sizeof(tmp), "%d", i);
|
||||||
|
xml += "\t\t<OUTPUT ID=\"" + string(tmp) + "\">";
|
||||||
|
|
||||||
|
memset (tmp, 0x0, sizeof(tmp));
|
||||||
|
snprintf (tmp, sizeof(tmp), "%f", out[i]);
|
||||||
|
xml += string(tmp) + "</OUTPUT>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
xml += "\t</TRAINING>\n\n";
|
||||||
|
return xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Closes an open XML document generated by "initXML" and "XMLFromSet"
|
||||||
|
* @param XML string to close
|
||||||
|
*/
|
||||||
|
void NeuralNet::closeXML(string &xml) {
|
||||||
|
xml.append("</NETWORK>\n\n");
|
||||||
|
}
|
||||||
|
|
98
src/neuron.cpp
Normal file
98
src/neuron.cpp
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
/**************************************************************************************************
|
||||||
|
* LibNeural++ v.0.2 - All-purpose library for managing neural networks *
|
||||||
|
* Copyright (C) 2009, BlackLight *
|
||||||
|
* *
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the *
|
||||||
|
* GNU General Public License as published by the Free Software Foundation, either version 3 of *
|
||||||
|
* the License, or (at your option) any later version. This program is distributed in the hope *
|
||||||
|
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
|
||||||
|
* more details. You should have received a copy of the GNU General Public License along with *
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
|
**************************************************************************************************/
|
||||||
|
|
||||||
|
#include "neural++.h"
|
||||||
|
using namespace neuralpp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
* @param a Activation function
|
||||||
|
* @param d Its derivate
|
||||||
|
*/
|
||||||
|
Neuron::Neuron (float (*a)(float), float (*d)(float)) {
|
||||||
|
actv_f=a;
|
||||||
|
deriv=d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Alternative constructor, that gets also the synapsis linked to the neuron
|
||||||
|
*/
|
||||||
|
Neuron::Neuron (vector< Synapsis > i, vector< Synapsis > o, float (*a)(float), float(*d)(float)) {
|
||||||
|
in=i;
|
||||||
|
out=o;
|
||||||
|
|
||||||
|
actv_f=a;
|
||||||
|
deriv=d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the i-th synapsis connected on the input of the neuron
|
||||||
|
*/
|
||||||
|
Synapsis& Neuron::synIn (size_t i) { return in[i]; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the i-th synapsis connected on the output of the neuron
|
||||||
|
*/
|
||||||
|
Synapsis& Neuron::synOut (size_t i) { return out[i]; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It pushes a new input synapsis
|
||||||
|
*/
|
||||||
|
void Neuron::push_in (Synapsis& s) { in.push_back(s); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It pushes a new output synapsis
|
||||||
|
*/
|
||||||
|
void Neuron::push_out (Synapsis& s) { out.push_back(s); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Change the propagation value of the neuron
|
||||||
|
*/
|
||||||
|
void Neuron::setProp (float val) { prop_val=val; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Change the activation value of the neuron
|
||||||
|
*/
|
||||||
|
void Neuron::setActv (float val) { actv_val=actv_f(val); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Number of input synapsis
|
||||||
|
*/
|
||||||
|
size_t Neuron::nIn() { return in.size(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Number of output synapsis
|
||||||
|
*/
|
||||||
|
size_t Neuron::nOut() { return out.size(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It gets the propagation value of the neuron
|
||||||
|
*/
|
||||||
|
float Neuron::getProp() { return prop_val; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It gets the activation value of the neuron
|
||||||
|
*/
|
||||||
|
float Neuron::getActv() { return actv_val; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Propagate a neuron's activation value to the connected neurons
|
||||||
|
*/
|
||||||
|
float Neuron::propagate() {
|
||||||
|
float aux=0;
|
||||||
|
|
||||||
|
for (size_t i=0; i<nIn(); i++)
|
||||||
|
aux += (in[i].getWeight() * in[i].getIn()->actv_val);
|
||||||
|
return aux;
|
||||||
|
}
|
||||||
|
|
84
src/synapsis.cpp
Normal file
84
src/synapsis.cpp
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/**************************************************************************************************
|
||||||
|
* LibNeural++ v.0.2 - All-purpose library for managing neural networks *
|
||||||
|
* Copyright (C) 2009, BlackLight *
|
||||||
|
* *
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the *
|
||||||
|
* GNU General Public License as published by the Free Software Foundation, either version 3 of *
|
||||||
|
* the License, or (at your option) any later version. This program is distributed in the hope *
|
||||||
|
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
|
||||||
|
* more details. You should have received a copy of the GNU General Public License along with *
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
|
**************************************************************************************************/
|
||||||
|
|
||||||
|
#include "neural++.h"
|
||||||
|
using namespace neuralpp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
* @param i Input neuron
|
||||||
|
* @param o Output neuron
|
||||||
|
* @param a Activation function
|
||||||
|
* @param d Derivate for activation function
|
||||||
|
*/
|
||||||
|
Synapsis::Synapsis (Neuron* i, Neuron* o, float(*a)(float), float(*d)(float)) {
|
||||||
|
srand((unsigned) time(NULL));
|
||||||
|
|
||||||
|
delta=0;
|
||||||
|
weight=RAND;
|
||||||
|
in=i;
|
||||||
|
out=o;
|
||||||
|
|
||||||
|
actv_f=a;
|
||||||
|
deriv=d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
* @param i Input neuron
|
||||||
|
* @param o Output neuron
|
||||||
|
* @param w Weight for the synapsis (default: random)
|
||||||
|
* @param a Activation function
|
||||||
|
* @param d Derivate for activation function
|
||||||
|
*/
|
||||||
|
Synapsis::Synapsis (Neuron* i, Neuron* o, float w, float(*a)(float), float(*d)(float)) {
|
||||||
|
delta=0;
|
||||||
|
weight=w;
|
||||||
|
in=i;
|
||||||
|
out=o;
|
||||||
|
|
||||||
|
actv_f=a;
|
||||||
|
deriv=d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Reference to input neuron of the synapsis
|
||||||
|
*/
|
||||||
|
Neuron* Synapsis::getIn() { return in; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Reference to output neuron of the synapsis
|
||||||
|
*/
|
||||||
|
Neuron* Synapsis::getOut() { return out; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Weight of the synapsis
|
||||||
|
*/
|
||||||
|
float Synapsis::getWeight() { return weight; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Delta of the synapsis
|
||||||
|
*/
|
||||||
|
float Synapsis::getDelta() { return delta; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It sets the weight of the synapsis
|
||||||
|
*/
|
||||||
|
void Synapsis::setWeight(float w) { weight=w; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief It sets the delta (how much to change the weight after an update)
|
||||||
|
* of the synapsis
|
||||||
|
*/
|
||||||
|
void Synapsis::setDelta(float d) { delta=d; }
|
||||||
|
|
Loading…
Reference in a new issue