From 25996a5e705cdc2d70dac6c65f3869da76157e8d Mon Sep 17 00:00:00 2001 From: blacklight Date: Sun, 16 Aug 2009 11:09:42 +0200 Subject: [PATCH] Growing up... --- ChangeLog | 4 ++ doc/html/namespacemembers.html | 42 ++++++++++++++++ doc/html/namespacemembers_func.html | 42 ++++++++++++++++ examples/adderFromScratch.cpp | 2 + examples/doAdd.cpp | 2 + examples/learnAdd.cpp | 4 +- include/neural++.hpp | 75 ++++++++++++++++------------- src/layer.cpp | 23 ++++----- src/neuralnet.cpp | 33 ++++++------- src/neuron.cpp | 14 ++++-- 10 files changed, 169 insertions(+), 72 deletions(-) create mode 100644 doc/html/namespacemembers.html create mode 100644 doc/html/namespacemembers_func.html diff --git a/ChangeLog b/ChangeLog index 760ad27..3d3dd38 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ --- Release 0.4 --- +2009-08-16 BlackLight + + * neuron.cpp: Fixing propagate() function + 2009-08-15 BlackLight * Makefile: Now you compile Neural++ with -Wall -pedantic diff --git a/doc/html/namespacemembers.html b/doc/html/namespacemembers.html new file mode 100644 index 0000000..6b935e3 --- /dev/null +++ b/doc/html/namespacemembers.html @@ -0,0 +1,42 @@ + + +Neural++: Class Members + + + + + +
+Here is a list of all namespace members with links to the namespace documentation for each member: +

+

+
+
Generated on Sat Aug 15 02:56:02 2009 for Neural++ by  + +doxygen 1.5.6
+ + diff --git a/doc/html/namespacemembers_func.html b/doc/html/namespacemembers_func.html new file mode 100644 index 0000000..1d5ce33 --- /dev/null +++ b/doc/html/namespacemembers_func.html @@ -0,0 +1,42 @@ + + +Neural++: Class Members + + + + + +
+  +

+

+
+
Generated on Sat Aug 15 02:56:02 2009 for Neural++ by  + +doxygen 1.5.6
+ + diff --git a/examples/adderFromScratch.cpp b/examples/adderFromScratch.cpp index c49e9b6..9be0ef5 100644 --- a/examples/adderFromScratch.cpp +++ b/examples/adderFromScratch.cpp @@ -7,6 +7,8 @@ #include #include + +using namespace std; using namespace neuralpp; int main() { diff --git a/examples/doAdd.cpp b/examples/doAdd.cpp index 9b6d3ee..f94bdf2 100644 --- a/examples/doAdd.cpp +++ b/examples/doAdd.cpp @@ -7,6 +7,8 @@ #include #include + +using namespace std; using namespace neuralpp; #define NETFILE "adder.net" diff --git a/examples/learnAdd.cpp b/examples/learnAdd.cpp index 0b9ad78..1583dc5 100644 --- a/examples/learnAdd.cpp +++ b/examples/learnAdd.cpp @@ -8,10 +8,12 @@ #include #include + +using namespace std; using namespace neuralpp; int main() { - NeuralNet net(2, 2, 1, 0.0005, 10000); + NeuralNet net(2, 2, 1, 0.005, 1000); cout << "Training in progress - This may take a while...\n"; net.train("adder.xml", NeuralNet::file); diff --git a/include/neural++.hpp b/include/neural++.hpp index f1e0079..dc3d9fc 100644 --- a/include/neural++.hpp +++ b/include/neural++.hpp @@ -1,5 +1,5 @@ /************************************************************************************************** - * LibNeural++ v.0.2 - All-purpose library for managing neural networks * + * LibNeural++ v.0.4 - 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 * @@ -23,7 +23,6 @@ #include #include "neural++_exception.hpp" -using namespace std; //! Default rand value: |sin(rand)|, always >= 0 and <= 1 #define RAND (double) ( (rand() / (RAND_MAX/2)) - 1) @@ -51,7 +50,8 @@ namespace neuralpp { int epochs; int ref_epochs; double l_rate; - double ex; + //double ex; + std::vector ex; /** * @brief It updates the weights of the net's synapsis through back-propagation. @@ -64,10 +64,10 @@ namespace neuralpp { * In-class use only * @param l Layer to commit the changes */ - void commitChanges (Layer *l); + void commitChanges (Layer& l); /** - * @brief Get the error made on the expected result as |v-v'|/v + * @brief Get the error made on the expected result as squared deviance * @param ex Expected value * @return Mean error */ @@ -111,7 +111,7 @@ namespace neuralpp { * @param file Binary file containing a neural network previously saved by save() method * @throw NetworkFileNotFoundException */ - NeuralNet (const string file) throw(NetworkFileNotFoundException); + NeuralNet (const std::string file) throw(NetworkFileNotFoundException); /** @@ -139,21 +139,34 @@ namespace neuralpp { * @brief It gets the output of the network in case the output layer contains more neurons * @return A vector containing the output values of the network */ - vector getOutputs(); + std::vector getOutputs(); /** - * @brief It gets the value expected. Of course you should specify this when you + * @brief Get the expected value (in case you have an only neuron in output layer). Of course you should specify this when you * build your network by using setExpected. * @return The expected output value for a certain training phase */ double expected() const; /** - * @brief It sets the value you expect from your network + * @brief Get the expected value (in case you have an only neuron in output layer). Of course you should specify this when you + * build your network by using setExpected. + * @return The expected output value for a certain training phase + */ + std::vector getExpected() const; + + /** + * @brief It sets the value you expect from your network (in case the network has an only neuron in its output layer) * @param ex Expected output value */ void setExpected(double ex); + /** + * @brief Set the values you expect from your network + * @param ex Expected output values + */ + void setExpected(std::vector ex); + /** * @brief It updates through back-propagation the weights of the synapsis and * computes again the output value for epochs times, calling back @@ -171,7 +184,7 @@ namespace neuralpp { * @brief It sets the input for the network * @param v Vector of doubles, containing the values to give to your network */ - void setInput (vector& v); + void setInput (std::vector v); /** * @brief It links the layers of the network (input, hidden, output). Don't use unless @@ -185,7 +198,7 @@ namespace neuralpp { * @throws NetworkFileWriteException When you get an error writing the network's information to * a file */ - void save(const char* fname) throw(NetworkFileWriteException); + void save (const char* fname) throw(NetworkFileWriteException); /** * @brief Train a network using a training set loaded from an XML file. A sample XML file @@ -194,13 +207,13 @@ namespace neuralpp { * @param src Source type from which the XML will be loaded (from a file [default] or from a string) * @throw InvalidXMLException */ - void train (string xml, source src) throw(InvalidXMLException); + void train (std::string xml, source src) throw(InvalidXMLException); /** * @brief Initialize the training XML for the neural network * @param xml String that will contain the XML */ - static void initXML (string& xml); + static void initXML (std::string& xml); /** * @brief Splits a string into a vector of doubles, given a delimitator @@ -208,7 +221,7 @@ namespace neuralpp { * @param str String to be splitted * @return Vector of doubles containing splitted values */ - static vector split (char delim, string str); + static std::vector split (char delim, std::string str); /** * @brief Get a training set from a string and copies it to an XML @@ -222,13 +235,13 @@ namespace neuralpp { * @param set String containing input values and expected outputs * @return XML string */ - static string XMLFromSet (int id, string set); + static std::string XMLFromSet (int id, std::string set); /** * @brief Closes an open XML document generated by "initXML" and "XMLFromSet" * @param xml XML string to be closed */ - static void closeXML(string& xml); + static void closeXML(std::string& xml); }; /** @@ -337,8 +350,8 @@ namespace neuralpp { double actv_val; double prop_val; - vector< Synapsis > in; - vector< Synapsis > out; + std::vector< Synapsis > in; + std::vector< Synapsis > out; double (*actv_f)(double); @@ -355,7 +368,7 @@ namespace neuralpp { * @param out Output synapses * @param a Activation function */ - Neuron (vector in, vector out, + Neuron (std::vector in, std::vector out, double (*a)(double)); /** @@ -376,13 +389,13 @@ namespace neuralpp { * @brief It pushes a new input synapsis * @param s Synapsis to be pushed */ - void push_in (Synapsis& s); + void push_in (Synapsis s); /** * @brief It pushes a new output synapsis * @param s Synapsis to be pushed */ - void push_out (Synapsis& s); + void push_out (Synapsis s); /** * @brief Change the activation value of the neuron @@ -409,9 +422,9 @@ namespace neuralpp { double getProp(); /** - * @brief It propagates its activation value to the connected neurons + * @brief Compute the propagation value of the neuron and set it */ - double propagate(); + void propagate(); /** * @brief Get the number of input synapsis for the neuron @@ -437,7 +450,7 @@ namespace neuralpp { * you're doing, use NeuralNet instead */ class Layer { - vector elements; + std::vector elements; void (*update_weights)(); double (*actv_f)(double); @@ -456,7 +469,7 @@ namespace neuralpp { * @param neurons Vector of neurons to be included in the layer * @param a Activation function */ - Layer (vector& neurons, double(*a)(double)); + Layer (std::vector& neurons, double(*a)(double)); /** * @brief Redefinition for operator []. It gets the neuron at i @@ -471,17 +484,11 @@ namespace neuralpp { */ void link (Layer& l); - /** - * @brief It sets a vector of propagation values to all its neurons - * @param v Vector of values to write as propagation values - */ - void setProp (vector& v); - /** - * @brief It sets a vector of activation values to all its neurons - * @param v Vector of values to write as activation values + * @brief Set the input values for the neurons of the layer (just use it for the input layer) + * @param v Vector containing the input values */ - void setActv (vector& v); + void setInput (std::vector v); /** * @brief It propagates its activation values to the output layers diff --git a/src/layer.cpp b/src/layer.cpp index 8498185..e74fe76 100644 --- a/src/layer.cpp +++ b/src/layer.cpp @@ -14,6 +14,8 @@ #include #include "neural++.hpp" +using std::vector; + namespace neuralpp { Layer::Layer(size_t sz, double (*a) (double)) { for (size_t i = 0; i < sz; i++) { @@ -24,7 +26,7 @@ namespace neuralpp { actv_f = a; } - Layer::Layer(vector < Neuron > &el, double (*a) (double)) { + Layer::Layer(vector &el, double (*a) (double)) { elements = el; actv_f = a; } @@ -40,7 +42,7 @@ namespace neuralpp { return elements[i]; } - void Layer::link(Layer & l) { + void Layer::link(Layer& l) { srand((unsigned) time(NULL)); for (size_t i = 0; i < l.size(); i++) { @@ -56,23 +58,16 @@ namespace neuralpp { } } - void Layer::setProp(vector < double >&v) { - for (size_t i = 0; i < size(); i++) + void Layer::setInput (vector v) { + for (size_t i = 0; i < size(); i++) { elements[i].setProp(v[i]); - } - - void Layer::setActv(vector < double >&v) { - for (size_t i = 0; i < size(); i++) elements[i].setActv(v[i]); + } } 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())); - } + for (size_t i = 0; i < size(); i++) + elements[i].propagate(); } } diff --git a/src/neuralnet.cpp b/src/neuralnet.cpp index fcef047..d2de71e 100644 --- a/src/neuralnet.cpp +++ b/src/neuralnet.cpp @@ -13,6 +13,7 @@ #include #include +using namespace std; #include "neural++.hpp" #include "Markup.h" @@ -78,9 +79,8 @@ namespace neuralpp { output->propagate(); } - void NeuralNet::setInput(vector & v) { - input->setProp(v); - input->setActv(v); + void NeuralNet::setInput(vector v) { + input->setInput(v); } void NeuralNet::link() { @@ -89,11 +89,12 @@ namespace neuralpp { } void NeuralNet::setExpected(double e) { - ex = e; + ex.clear(); + ex.push_back(e); } double NeuralNet::expected() const { - return ex; + return ex[0]; } void NeuralNet::updateWeights() { @@ -101,24 +102,20 @@ namespace neuralpp { for (size_t i = 0; i < output->size(); i++) { Neuron *n = &(*output)[i]; - double prop = 0.0; - - for (size_t j = 0; j < n->nIn(); j++) - prop += (n->synIn(j).getWeight() * n->synIn(j).getIn()->getActv()); - + for (size_t j = 0; j < n->nIn(); j++) { Synapsis *s = &(n->synIn(j)); if (ref_epochs - epochs > 0) out_delta = (-l_rate) * (getOutput() - expected()) * - df(actv_f, prop) * s->getIn()->getActv() + + df(actv_f, n->getProp()) * s->getIn()->getActv() + s->momentum(ref_epochs, ref_epochs - epochs) * s->getPrevDelta(); else out_delta = (-l_rate) * (getOutput() - expected()) * - df(actv_f, prop) * s->getIn()->getActv(); + df(actv_f, n->getProp()) * s->getIn()->getActv(); s->setDelta(out_delta); } @@ -148,9 +145,9 @@ namespace neuralpp { } } - void NeuralNet::commitChanges(Layer * l) { - for (size_t i = 0; i < l->size(); i++) { - Neuron *n = &(*l)[i]; + 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)); @@ -164,8 +161,8 @@ namespace neuralpp { void NeuralNet::update() { while ((epochs--) > 0) { updateWeights(); - commitChanges(output); - commitChanges(hidden); + commitChanges(*output); + commitChanges(*hidden); propagate(); } } @@ -183,7 +180,7 @@ namespace neuralpp { record.epochs = ref_epochs; record.l_rate = l_rate; - record.ex = ex; + record.ex = ex[0]; if (out.write((char*) &record, sizeof(struct netrecord)) <= 0) throw NetworkFileWriteException(); diff --git a/src/neuron.cpp b/src/neuron.cpp index fa90085..fd648fe 100644 --- a/src/neuron.cpp +++ b/src/neuron.cpp @@ -13,6 +13,8 @@ #include "neural++.hpp" +using std::vector; + namespace neuralpp { Neuron::Neuron(double (*a) (double)) { actv_f = a; @@ -35,11 +37,11 @@ namespace neuralpp { return out[i]; } - void Neuron::push_in(Synapsis & s) { + void Neuron::push_in(Synapsis s) { in.push_back(s); } - void Neuron::push_out(Synapsis & s) { + void Neuron::push_out(Synapsis s) { out.push_back(s); } @@ -67,13 +69,15 @@ namespace neuralpp { return actv_val; } - double Neuron::propagate() { - double aux = 0; + void Neuron::propagate() { + double aux = 0.0; for (size_t i = 0; i < nIn(); i++) aux += (in[i].getWeight() * in[i].getIn()->actv_val); - return aux; + + setProp(aux); + setActv( actv_f(getProp()) ); } void Neuron::synClear() {