* New tree configuration of the project:
.../
... + -- EO
| |
| |
+-- src ----- + -- EDO
| |
| |
+-- test + -- MO
| |
| |
+-- tutorial + -- MOEO
| |
| |
+-- doc + -- SMP
| |
| |
... + -- EOMPI
|
|
+ -- EOSERIAL
Question for current maintainers: ./README: new release?
Also:
* Moving out eompi & eoserial modules (issue #2).
* Correction of the errors when executing "make doc" command.
* Adding a solution for the conflicting headers problem (see the two CMake Cache
Values: PROJECT_TAG & PROJECT_HRS_INSTALL_SUBPATH) (issue #1)
* Header inclusions:
** src: changing absolute paths into relative paths ('#include <...>' -> '#include "..."')
** test, tutorial: changing relative paths into absolute paths ('#include "..."' -> '#include <...>')
* Moving out some scripts from EDO -> to the root
* Add a new script for compilation and installation (see build_gcc_linux_install)
* Compilation with uBLAS library or EDO module: now ok
* Minor modifications on README & INSTALL files
* Comment eompi failed tests with no end
*** TODO: CPack (debian (DEB) & RedHat (RPM) packages) (issues #6 & #7) ***
This commit is contained in:
parent
515bd5943d
commit
490e837f7a
2359 changed files with 7688 additions and 16329 deletions
|
|
@ -1,513 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// mlp.h
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef mlp_h
|
||||
#define mlp_h
|
||||
|
||||
#include <algorithm> // generate
|
||||
#include <cmath> // exp
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <numeric>
|
||||
#include <stdexcept> // invalid_argument
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <utils/eoRNG.h> // eoRng
|
||||
#include <utils/rnd_generators.h> // normal_generator
|
||||
#include <vecop.h> // *
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits>
|
||||
|
||||
#ifdef HAVE_LIBYAML_CPP
|
||||
#include <yaml-cpp/serializable.h>
|
||||
#endif // HAVE_LIBYAML_CPP
|
||||
|
||||
|
||||
namespace mlp
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
typedef double real;
|
||||
typedef std::vector<real> vector;
|
||||
}
|
||||
|
||||
|
||||
namespace std {
|
||||
ostream& operator<<(ostream& os, const mlp::vector& v)
|
||||
{
|
||||
ostream_iterator<mlp::real> oi(os, " ");
|
||||
copy(v.begin(), v.end(), oi);
|
||||
return os;
|
||||
}
|
||||
|
||||
istream& operator>>(istream& is, mlp::vector& v)
|
||||
{
|
||||
for (mlp::vector::iterator vi = v.begin() ; vi != v.end() ; vi++) {
|
||||
is >> *vi;
|
||||
}
|
||||
return is;
|
||||
}
|
||||
}
|
||||
|
||||
namespace mlp
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// useful typedefs
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
const real max_real = std::numeric_limits<real>::max();
|
||||
const real min_real = std::numeric_limits<real>::min();
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// sigmoid
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
real sigmoid(const real& x)
|
||||
{
|
||||
return 1.0 / (1.0 + exp(-x));
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// neuron
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
struct neuron
|
||||
{
|
||||
real bias;
|
||||
vector weight;
|
||||
|
||||
neuron(const unsigned& num_inputs = 0): weight(num_inputs) {}
|
||||
|
||||
void reset()
|
||||
{
|
||||
normal_generator<real> rnd(1.0);
|
||||
bias = rnd();
|
||||
generate(weight.begin(), weight.end(), rnd);
|
||||
}
|
||||
|
||||
real operator()(const vector& input) const
|
||||
{
|
||||
return sigmoid(bias + weight * input);
|
||||
}
|
||||
|
||||
unsigned length() const { return weight.size() + 1; }
|
||||
|
||||
void normalize()
|
||||
{
|
||||
real n = sqrt(bias * bias + weight * weight);
|
||||
bias /= n;
|
||||
weight /= n;
|
||||
}
|
||||
|
||||
void desaturate()
|
||||
{
|
||||
bias = -5.0 + 10.0 / (1.0 + exp(bias / -5.0));
|
||||
|
||||
for (vector::iterator w = weight.begin(); w != weight.end(); ++w)
|
||||
*w = -5.0 + 10.0 / (1.0 + exp(*w / -5.0));
|
||||
}
|
||||
|
||||
void perturb_num(double &num, double magnitude) {
|
||||
double scale = max(num, 0.05) * magnitude;
|
||||
double perturbation = scale * (rng.uniform() - 0.5);
|
||||
num += perturbation;
|
||||
}
|
||||
|
||||
void perturb(double magnitude = 0.3, double probability = 1.0)
|
||||
{
|
||||
|
||||
for (vector::iterator w = weight.begin(); w != weight.end(); ++w)
|
||||
if ( probability >= 1.0 || rng.uniform() < probability)
|
||||
perturb_num(*w, magnitude);
|
||||
if ( probability >= 1.0 || rng.uniform() < probability)
|
||||
perturb_num(bias, magnitude);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBYAML_CPP
|
||||
YAML_SERIALIZABLE_AUTO(neuron)
|
||||
void emit_yaml(YAML::Emitter&out) const {
|
||||
out << YAML::BeginMap;
|
||||
out << YAML::Key << "Class" << YAML::Value << "mlp::neuron";
|
||||
YAML_EMIT_MEMBER(out,bias);
|
||||
YAML_EMIT_MEMBER(out,weight);
|
||||
out << YAML::EndMap;
|
||||
}
|
||||
void load_yaml(const YAML::Node& node) {
|
||||
YAML_LOAD_MEMBER(node, bias);
|
||||
YAML_LOAD_MEMBER(node, weight);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
namespace std {
|
||||
|
||||
ostream& operator<<(ostream& os, const mlp::neuron& n)
|
||||
{
|
||||
return os << n.bias << " " << n.weight;
|
||||
}
|
||||
|
||||
istream& operator>>(istream& is, mlp::neuron& n)
|
||||
{
|
||||
return is >> n.bias >> n.weight;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace mlp {
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// layer
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class layer: public std::vector<neuron>
|
||||
{
|
||||
public:
|
||||
layer(const unsigned& num_inputs = 0, const unsigned& num_neurons = 0):
|
||||
std::vector<neuron>(num_neurons, neuron(num_inputs)) {}
|
||||
|
||||
void reset()
|
||||
{
|
||||
normal_generator<real> rnd(1.0);
|
||||
for(iterator n = begin(); n != end(); ++n)
|
||||
n->reset();
|
||||
}
|
||||
|
||||
vector operator()(const vector& input) const
|
||||
{
|
||||
vector output(size());
|
||||
|
||||
for(unsigned i = 0; i < output.size(); ++i)
|
||||
output[i] = (*this)[i](input);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
unsigned length() const { return front().length() * size(); }
|
||||
|
||||
void normalize()
|
||||
{
|
||||
for(iterator n = begin(); n != end(); ++n)
|
||||
n->normalize();
|
||||
}
|
||||
|
||||
void desaturate()
|
||||
{
|
||||
for(iterator n = begin(); n != end(); ++n)
|
||||
n->desaturate();
|
||||
}
|
||||
|
||||
void perturb(double magnitude = 0.3, double probability = 1.0)
|
||||
{
|
||||
for(iterator n = begin(); n != end(); ++n)
|
||||
n->perturb();
|
||||
}
|
||||
#ifdef HAVE_LIBYAML_CPP
|
||||
friend ostream& operator<<(YAML::Emitter& e, const layer &l) {
|
||||
e << ((std::vector<neuron>)l);
|
||||
}
|
||||
|
||||
friend void operator>>(const YAML::Node& n, layer &l) {
|
||||
// These temporary variable shenanegins are necessary because
|
||||
// the compiler gets very confused about which template operator>>
|
||||
// function to use.
|
||||
// The following does not work: n >> l;
|
||||
// So we use a temporary variable thusly:
|
||||
std::vector<mlp::neuron> *obviously_a_vector = &l;
|
||||
n >> *obviously_a_vector;
|
||||
}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace std {
|
||||
|
||||
ostream& operator<<(ostream& os, const mlp::layer& l)
|
||||
{
|
||||
ostream_iterator<mlp::neuron> oi(os, " ");
|
||||
copy(l.begin(), l.end(), oi);
|
||||
return os;
|
||||
}
|
||||
|
||||
istream& operator>>(istream& is, mlp::layer& l)
|
||||
{
|
||||
for (mlp::layer::iterator li = l.begin() ; li != l.end() ; li++) {
|
||||
is >> *li;
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace mlp {
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// net
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class net: public std::vector<layer>
|
||||
#ifdef HAVE_LIBYAML_CPP
|
||||
, public YAML::Serializable
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
net(const unsigned& num_inputs = 0,
|
||||
const unsigned& num_outputs = 0,
|
||||
const std::vector<unsigned>& hidden = std::vector<unsigned>())
|
||||
{
|
||||
init(num_inputs,num_outputs,hidden);
|
||||
}
|
||||
|
||||
|
||||
net(istream &is) {
|
||||
load(is);
|
||||
}
|
||||
#ifdef HAVE_LIBYAML_CPP
|
||||
YAML_SERIALIZABLE_AUTO(net)
|
||||
void emit_members(YAML::Emitter&out) const {
|
||||
const std::vector<layer>* me_as_layer_vector = this;
|
||||
out << YAML::Key << "layers" << YAML::Value << *me_as_layer_vector;
|
||||
}
|
||||
|
||||
void load_members(const YAML::Node& node) {
|
||||
std::vector<layer>* me_as_layer_vector = this;
|
||||
node["layers"] >> *me_as_layer_vector;
|
||||
}
|
||||
#endif // HAVE_LIBYAML_CPP
|
||||
|
||||
/** Virtual destructor */
|
||||
virtual ~net() {};
|
||||
|
||||
void load(istream &is) {
|
||||
unsigned num_inputs;
|
||||
unsigned num_outputs;
|
||||
unsigned num_hidden_layers;
|
||||
|
||||
is >> num_inputs >> num_outputs >> num_hidden_layers;
|
||||
|
||||
std::vector<unsigned> layer_sizes;
|
||||
for (unsigned i=0; i<num_hidden_layers;i++) {
|
||||
unsigned layer_size;
|
||||
is >> layer_size;
|
||||
layer_sizes.push_back(layer_size);
|
||||
}
|
||||
unsigned check_outputs;
|
||||
is >> check_outputs;
|
||||
assert (check_outputs == num_outputs);
|
||||
init (num_inputs,num_outputs,layer_sizes);
|
||||
// skip forward to pass up opening '<' char
|
||||
char c=' ';
|
||||
while (c!='<' && !is.eof()) { is >> c;}
|
||||
for (iterator l =begin() ; l != end(); l++) {
|
||||
is >> *l;
|
||||
}
|
||||
do { is >> c; } while (c == ' ' && !is.eof());
|
||||
assert(c == '>');
|
||||
}
|
||||
|
||||
void init( unsigned num_inputs,
|
||||
unsigned num_outputs,
|
||||
const std::vector<unsigned>& hidden ) {
|
||||
clear();
|
||||
switch(hidden.size())
|
||||
{
|
||||
case 0:
|
||||
push_back(layer(num_inputs, num_outputs));
|
||||
break;
|
||||
default:
|
||||
push_back(layer(num_inputs, hidden.front()));
|
||||
for (unsigned i = 0; i < hidden.size() - 1; ++i)
|
||||
push_back(layer(hidden[i], hidden[i + 1]));
|
||||
push_back(layer(hidden.back(), num_outputs));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
normal_generator<real> rnd(1.0);
|
||||
for(iterator l = begin(); l != end(); ++l)
|
||||
l->reset();
|
||||
}
|
||||
|
||||
virtual vector operator()(const vector& input) const ;
|
||||
|
||||
unsigned winner(const vector& input) const
|
||||
{
|
||||
vector tmp = (*this)(input);
|
||||
return (max_element(tmp.begin(), tmp.end()) - tmp.begin());
|
||||
}
|
||||
|
||||
void save(ostream &os) const {
|
||||
// Save the number of inputs, number of outputs, and number of hidden layers
|
||||
os << num_inputs() << "\n" << num_outputs() << "\n" << num_hidden_layers() << "\n";
|
||||
for(const_iterator l = begin(); l != end(); ++l)
|
||||
os << l->size() << " ";
|
||||
os << "\n";
|
||||
os << "< ";
|
||||
for(const_iterator l = begin(); l != end(); ++l)
|
||||
os << *l << " ";
|
||||
os << ">\n";
|
||||
}
|
||||
|
||||
|
||||
unsigned num_inputs() const { return front().front().length() - 1; }
|
||||
unsigned num_outputs() const { return back().size(); }
|
||||
unsigned num_hidden_layers() const {
|
||||
signed s = (signed) size() -1;
|
||||
return (s<0) ? 0 : s ;
|
||||
}
|
||||
|
||||
|
||||
unsigned length()
|
||||
{
|
||||
unsigned sum = 0;
|
||||
|
||||
for(iterator l = begin(); l != end(); ++l)
|
||||
sum += l->length();
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
void normalize()
|
||||
{
|
||||
for(iterator l = begin(); l != end(); ++l)
|
||||
l->normalize();
|
||||
}
|
||||
|
||||
void desaturate()
|
||||
{
|
||||
for(iterator l = begin(); l != end(); ++l)
|
||||
l->desaturate();
|
||||
}
|
||||
|
||||
void perturb(double magnitude = 0.3, double probability = 1.0)
|
||||
{
|
||||
for(iterator l = begin(); l != end(); ++l)
|
||||
l->perturb();
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef NO_MLP_VIRTUALS
|
||||
vector net::operator()(const vector& input) const
|
||||
{
|
||||
vector tmp = input;
|
||||
|
||||
for(const_iterator l = begin(); l != end(); ++l)
|
||||
tmp = (*l)(tmp);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// sample
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
struct sample
|
||||
{
|
||||
vector input, output;
|
||||
|
||||
sample(unsigned input_size = 0, unsigned output_size = 0):
|
||||
input(input_size), output(output_size) {}
|
||||
};
|
||||
|
||||
istream& operator>>(istream& is, sample& s)
|
||||
{
|
||||
return is >> s.input >> s.output;
|
||||
}
|
||||
|
||||
ostream& operator<<(ostream& os, const sample& s)
|
||||
{
|
||||
return os << s.input << " " << s.output;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// set
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class set: public std::vector<sample>
|
||||
{
|
||||
public:
|
||||
set(unsigned input_size = 0, unsigned output_size = 0,
|
||||
unsigned num_samples = 0):
|
||||
std::vector<sample>(num_samples, sample(input_size, output_size)) {}
|
||||
|
||||
set(istream& is) : std::vector<sample>(0, sample(0, 0)) {
|
||||
clear();
|
||||
load(is);
|
||||
}
|
||||
|
||||
void load(istream &is) {
|
||||
unsigned input_size, output_size;
|
||||
is >> input_size >> output_size;
|
||||
sample samp(input_size, output_size);;
|
||||
while (is >> samp) { push_back(samp); }
|
||||
}
|
||||
|
||||
void save(ostream &os) const {
|
||||
os << front().input.size() << " " << front().output.size() << endl;
|
||||
copy(begin(), end(), ostream_iterator<sample>(os,"\n"));
|
||||
}
|
||||
};
|
||||
|
||||
ostream& operator<<(ostream& os, const set& s)
|
||||
{
|
||||
os << "<" << endl;
|
||||
for (unsigned i = 0; i < s.size(); ++i)
|
||||
os << s[i] << endl;
|
||||
return os << ">";
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// euclidean_distance
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
real euclidean_distance(const net& n1, const net& n2)
|
||||
{
|
||||
real sum = 0;
|
||||
|
||||
for(net::const_reverse_iterator l1 = n1.rbegin(), l2 = n2.rbegin();
|
||||
l1 != n1.rend() && l2 != n2.rend(); ++l1, ++l2)
|
||||
for(layer::const_iterator n1 = l1->begin(), n2 = l2->begin();
|
||||
n1 != l1->end() && n2 != l2->end(); ++n1, ++n2)
|
||||
{
|
||||
real b = n1->bias - n2->bias;
|
||||
vector w = n1->weight - n2->weight;
|
||||
sum += b * b + w * w;
|
||||
}
|
||||
/*
|
||||
#include <fstream>
|
||||
std::ofstream file("dist.stat", ios::app);
|
||||
file << sqrt(sum) << endl;
|
||||
*/
|
||||
return sqrt(sum);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
} // namespace mlp
|
||||
|
||||
|
||||
|
||||
#endif // mlp_h
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// mode:C++
|
||||
// c-file-style: "Stroustrup"
|
||||
// End:
|
||||
Loading…
Add table
Add a link
Reference in a new issue