Newer
Older
/**
* Basic example using particle swarm method to train the network
*/
//
// Created by martin on 7/16/18.
//

Michal Kravcenko
committed
#include <iostream>
#include "4neuro.h"

Michal Kravcenko
committed
void optimize_via_particle_swarm( l4n::NeuralNetwork &net, l4n::ErrorFunction &ef ){

Michal Kravcenko
committed
/* TRAINING METHOD SETUP */
std::vector<double> domain_bounds(2 * (net.get_n_weights() + net.get_n_biases()));
for(size_t i = 0; i < domain_bounds.size() / 2; ++i){
domain_bounds[2 * i] = -10;
domain_bounds[2 * i + 1] = 10;
}
double c1 = 1.7;
double c2 = 1.7;
double w = 0.7;
size_t n_particles = 50;
size_t iter_max = 1000;
/* if the maximal velocity from the previous step is less than 'gamma' times the current maximal velocity, then one
* terminating criterion is met */
double gamma = 0.5;
/* if 'delta' times 'n' particles are in the centroid neighborhood given by the radius 'epsilon', then the second
* terminating criterion is met ('n' is the total number of particles) */
double epsilon = 0.02;
double delta = 0.7;

Michal Kravcenko
committed
&domain_bounds,
c1,
c2,
w,
gamma,
epsilon,
delta,
n_particles,
iter_max
);
swarm_01.optimize( ef );
std::vector<double> *parameters = swarm_01.get_parameters();
net.copy_parameter_space(parameters);
/* ERROR CALCULATION */
std::cout << "Run finished! Error of the network[Particle swarm]: " << ef.eval( nullptr ) << std::endl;
std::cout << "***********************************************************************************************************************" <<std::endl;
}
void optimize_via_gradient_descent( l4n::NeuralNetwork &net, l4n::ErrorFunction &ef ){

Michal Kravcenko
committed
std::cout << "***********************************************************************************************************************" <<std::endl;

Michal Kravcenko
committed
gd.optimize( ef );
std::vector<double> *parameters = gd.get_parameters();
net.copy_parameter_space(parameters);
/* ERROR CALCULATION */
std::cout << "Run finished! Error of the network[Gradient descent]: " << ef.eval( nullptr ) << std::endl;
}

Michal Kravcenko
committed
std::cout << "Running lib4neuro example 1: Basic use of the particle swarm or gradient method to train a simple network with few linear neurons" << std::endl;

Michal Kravcenko
committed
std::cout << "***********************************************************************************************************************" <<std::endl;
std::cout << "The code attempts to find an approximate solution to the system of equations below:" << std::endl;
std::cout << "0 * w1 + 1 * w2 = 0.50" << std::endl;
std::cout << "1 * w1 + 0.5*w2 = 0.75" << std::endl;
std::cout << "***********************************************************************************************************************" <<std::endl;
/* TRAIN DATA DEFINITION */
std::vector<std::pair<std::vector<double>, std::vector<double>>> data_vec;
std::vector<double> inp, out;
inp = {0, 1};
out = {0.5};
data_vec.emplace_back(std::make_pair(inp, out));
inp = {1, 0.5};
out = {0.75};
data_vec.emplace_back(std::make_pair(inp, out));
Martin Beseda
committed
l4n::DataSet ds(&data_vec);
Martin Beseda
committed
l4n::NeuralNetwork net;
Martin Beseda
committed
l4n::NeuronLinear *i1 = new l4n::NeuronLinear( ); //f(x) = x
l4n::NeuronLinear *i2 = new l4n::NeuronLinear( ); //f(x) = x
Martin Beseda
committed
l4n::NeuronLinear *o1 = new l4n::NeuronLinear( ); //f(x) = x
/* Adding neurons to the net */
Martin Beseda
committed
size_t idx1 = net.add_neuron(i1, l4n::BIAS_TYPE::NO_BIAS);
size_t idx2 = net.add_neuron(i2, l4n::BIAS_TYPE::NO_BIAS);
size_t idx3 = net.add_neuron(o1, l4n::BIAS_TYPE::NO_BIAS);

Michal Kravcenko
committed
//
Martin Beseda
committed
net.add_connection_simple(idx1, idx3, l4n::SIMPLE_CONNECTION_TYPE::NEXT_WEIGHT);
net.add_connection_simple(idx2, idx3, l4n::SIMPLE_CONNECTION_TYPE::NEXT_WEIGHT);

Michal Kravcenko
committed
/* specification of the input/output neurons */
std::vector<size_t> net_input_neurons_indices(2);
std::vector<size_t> net_output_neurons_indices(1);
net_input_neurons_indices[0] = idx1;
net_input_neurons_indices[1] = idx2;
net_output_neurons_indices[0] = idx3;
net.specify_input_neurons(net_input_neurons_indices);
net.specify_output_neurons(net_output_neurons_indices);
Martin Beseda
committed
l4n::MSE mse(&net, &ds);

Michal Kravcenko
committed
/* PARTICLE SWARM LEARNING */
net.randomize_parameters();
optimize_via_particle_swarm( net, mse );

Michal Kravcenko
committed
/* GRADIENT DESCENT LEARNING */
net.randomize_parameters();
optimize_via_gradient_descent( net, mse );
Martin Beseda
committed
/* Normalize data to prevent 'nan' results */
ds.normalize();
net.randomize_parameters();
optimize_via_gradient_descent(net, mse);