diff --git a/src/NetConnection/Connection.cpp b/src/NetConnection/Connection.cpp deleted file mode 100644 index 25eb8c90e42d7e32acbb0ac0f7eeaf2c47135ca4..0000000000000000000000000000000000000000 --- a/src/NetConnection/Connection.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/** - * DESCRIPTION OF THE FILE - * - * @author Michal Kravčenko - * @date 13.6.18 - - */ - -#include "Connection.h" - -Connection* Connection::get_copy(Neuron *n_in, Neuron *n_out){ - Connection *output = new Connection(n_in, n_out, this->con, false); - return output; -} - -Connection::Connection(Neuron *n_in, Neuron *n_out, ConnectionWeight* con, bool del_weight) { - this->neuron_in = n_in; - this->neuron_out = n_out; - - this->con = con; - this->delete_connection = del_weight; -} - -Connection::~Connection() { - if(this->con && this->delete_connection ){ - delete this->con; - this->con = nullptr; - } -} - -void Connection::adjust_weights(double* values) { - this->con->adjust_weights(values); -} - - -Neuron* Connection::get_neuron_in() { - return this->neuron_in; -} - -Neuron* Connection::get_neuron_out() { - return this->neuron_out; -} - -//double Connection::get_weight() { -// return this->weight; -//} - -void Connection::pass_signal() { -#ifdef VERBOSE_NN_EVAL - printf(" passing signal between neurons %d -> %d, value: %f * %f\n", this->neuron_in, this->neuron_out, this->neuron_in->get_state(), this->con->eval()); -#endif - this->neuron_out->adjust_potential(this->neuron_in->get_state() * this->con->eval()); -} - -void Connection::set_weights(double *values) { - this->con->set_weights(values); -} diff --git a/src/NetConnection/Connection.h b/src/NetConnection/Connection.h deleted file mode 100644 index b9895f32ff29223c804c07ab886b08d06df7b6f0..0000000000000000000000000000000000000000 --- a/src/NetConnection/Connection.h +++ /dev/null @@ -1,107 +0,0 @@ -/** - * DESCRIPTION OF THE FILE - * - * @author Michal Kravčenko - * @date 13.6.18 - - */ - -#ifndef INC_4NEURO_CONNECTION_H -#define INC_4NEURO_CONNECTION_H - -#include "../Neuron/Neuron.h" -#include "ConnectionWeight.h" -#include "../settings.h" - -class Neuron; -class ConnectionWeight; - -/** - * Class representing directed connection between two neurons - */ -class Connection { -private: - - /** - * Pointer to an object evaluating the weight function - */ - ConnectionWeight *con = nullptr; - /** - * Pointer to the Neuron on the receiving end of this connection - */ - Neuron *neuron_in = nullptr; - - /** - * Pointer to the Neuron on the signaling end of this connection - */ - Neuron *neuron_out = nullptr; - - /** - * - */ - bool delete_connection = true; - - - //TODO pridat gradient pro ucely backpropagation - -public: - - /** - * Returns a new object reprresenting an edge using the same weight function as this one - * @param n_in - * @param n_out - * @return - */ - virtual Connection* get_copy(Neuron *n_in, Neuron *n_out) final; - - /** - * - * @param n_in - * @param n_out - * @param con - * @param delete_weight - */ - Connection(Neuron *n_in, Neuron *n_out, ConnectionWeight* con, bool delete_weight = true); - - /** - * Destructor, deletes the 'con' object - */ - ~Connection(); - - /** - * Takes the array of double values and alters the corresponding weights associated - * with the 'con' object - * @param[in] values Values to be added to the associated weights - */ - void adjust_weights(double *values); - - /** - * Takes the array of double values and sets the corresponding weights associated - * with the 'con' object - * @param[in] values Values to be set to the associated weights - */ - void set_weights(double *values); - - /** - * Takes the output signal of Neuron 'neuron_out', multiplies it by the result of the - * weight function associated with this connection and adds the result to the potential - * of the Neuron 'neuron_in' - */ - void pass_signal(); - - - /** - * Returns the pointer to the Neuron on the receiving end of this connection - * @return - */ - Neuron* get_neuron_in(); - - /** - * Returns the pointer to the Neuron on the signaling end of this connection - * @return - */ - Neuron* get_neuron_out(); - -}; - - -#endif //INC_4NEURO_CONNECTION_H diff --git a/src/NetConnection/ConnectionWeight.cpp b/src/NetConnection/ConnectionFunctionGeneral.cpp similarity index 100% rename from src/NetConnection/ConnectionWeight.cpp rename to src/NetConnection/ConnectionFunctionGeneral.cpp diff --git a/src/NetConnection/ConnectionWeight.h b/src/NetConnection/ConnectionFunctionGeneral.h similarity index 100% rename from src/NetConnection/ConnectionWeight.h rename to src/NetConnection/ConnectionFunctionGeneral.h diff --git a/src/NetConnection/ConnectionFunctionIdentity.cpp b/src/NetConnection/ConnectionFunctionIdentity.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b69160f489296576ca71e5cb99a6ada39c8a7eaf --- /dev/null +++ b/src/NetConnection/ConnectionFunctionIdentity.cpp @@ -0,0 +1,16 @@ +/** + * DESCRIPTION OF THE FILE + * + * @author Michal Kravčenko + * @date 14.6.18 - + */ + +#include "ConnectionWeightIdentity.h" + +ConnectionWeightIdentity::ConnectionWeightIdentity(double * val) { + this->value = val; +} + +double ConnectionWeightIdentity::eval() { + return (*this->value); +} \ No newline at end of file diff --git a/src/NetConnection/ConnectionWeightIdentity.h b/src/NetConnection/ConnectionFunctionIdentity.h similarity index 61% rename from src/NetConnection/ConnectionWeightIdentity.h rename to src/NetConnection/ConnectionFunctionIdentity.h index 2b214abaee05cad7cbe2de3a5210a599962ac3d7..d1d9c8d0f934c08812667f07addb884a1d4fad26 100644 --- a/src/NetConnection/ConnectionWeightIdentity.h +++ b/src/NetConnection/ConnectionFunctionIdentity.h @@ -8,21 +8,22 @@ #ifndef INC_4NEURO_CONNECTIONWEIGHTIDENTITY_H #define INC_4NEURO_CONNECTIONWEIGHTIDENTITY_H -#include "ConnectionWeight.h" +#include "ConnectionFunctionGeneral.h" -class ConnectionWeight; +class ConnectionFunctionGeneral; /** * */ -class ConnectionWeightIdentity:public ConnectionWeight { +class ConnectionWeightIdentity:public ConnectionFunctionGeneral { private: + double * value = nullptr; public: /** * */ - ConnectionWeightIdentity(std::vector<double>* w_array); + ConnectionWeightIdentity(double * value_ptr); /** * diff --git a/src/NetConnection/ConnectionWeightIdentity.cpp b/src/NetConnection/ConnectionWeightIdentity.cpp deleted file mode 100644 index ad3ffc0c8be7b7e06f9a71e9fb4718f7dc9d08dd..0000000000000000000000000000000000000000 --- a/src/NetConnection/ConnectionWeightIdentity.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/** - * DESCRIPTION OF THE FILE - * - * @author Michal Kravčenko - * @date 14.6.18 - - */ - -#include "ConnectionWeightIdentity.h" - -ConnectionWeightIdentity::ConnectionWeightIdentity(std::vector<double>* w_array) { - this->n_params = 1; - this->weight_array = w_array; - - this->param_indices = new int[1]; -} - -double ConnectionWeightIdentity::eval() { - - double a = this->weight_array->at(this->param_indices[0]); - - return a; -} \ No newline at end of file diff --git a/src/Neuron/NeuronNeuralNet.cpp b/src/Neuron/NeuronConstant.cpp similarity index 58% rename from src/Neuron/NeuronNeuralNet.cpp rename to src/Neuron/NeuronConstant.cpp index 70d1307df87a7535ba109c1f4309726c51116aa7..a656c3f628dd7e4d0716435f363f9f6c0688d5b6 100644 --- a/src/Neuron/NeuronNeuralNet.cpp +++ b/src/Neuron/NeuronConstant.cpp @@ -2,7 +2,7 @@ * DESCRIPTION OF THE FILE * * @author Michal Kravčenko - * @date 13.6.18 - + * @date 8.8.18 - */ -#include "NeuronNeuralNet.h" +#include "NeuronConstant.h" diff --git a/src/Neuron/NeuronConstant.h b/src/Neuron/NeuronConstant.h new file mode 100644 index 0000000000000000000000000000000000000000..dff05a073c18122b477e414dd30585b39837c095 --- /dev/null +++ b/src/Neuron/NeuronConstant.h @@ -0,0 +1,17 @@ +/** + * DESCRIPTION OF THE FILE + * + * @author Michal Kravčenko + * @date 8.8.18 - + */ + +#ifndef INC_4NEURO_NEURONCONSTANT_H +#define INC_4NEURO_NEURONCONSTANT_H + + +class NeuronConstant { + +}; + + +#endif //INC_4NEURO_NEURONCONSTANT_H diff --git a/src/Neuron/NeuronNeuralNet.h b/src/Neuron/NeuronNeuralNet.h deleted file mode 100644 index 35cb2a3ac180c2ca8a8201e4dbb66bcccb78568d..0000000000000000000000000000000000000000 --- a/src/Neuron/NeuronNeuralNet.h +++ /dev/null @@ -1,18 +0,0 @@ -/** - * DESCRIPTION OF THE FILE - * - * @author Michal Kravčenko - * @date 13.6.18 - - */ - -#ifndef INC_4NEURO_NEURONNEURALNET_H -#define INC_4NEURO_NEURONNEURALNET_H - -#include "Neuron.h" - -class NeuronNeuralNet:public Neuron { - -}; - - -#endif //INC_4NEURO_NEURONNEURALNET_H diff --git a/src/Neuron/NeuronTanh.cpp b/src/Neuron/NeuronTanh.cpp deleted file mode 100644 index cef2a07faedf044e19f06c368b0729d5c1756bb0..0000000000000000000000000000000000000000 --- a/src/Neuron/NeuronTanh.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// -// Created by fluffymoo on 11.6.18. -// - -#include "NeuronTanh.h" - -Neuron* NeuronTanh::get_copy( ){ - NeuronTanh* output = new NeuronTanh( this->activation_function_parameters[0]); - - return output; -} - -NeuronTanh::NeuronTanh(double a) { - - this->n_activation_function_parameters = 1; - this->activation_function_parameters = new double[1]; - this->activation_function_parameters[0] = a; - - this->edges_in = new std::vector<Connection*>(0); - this->edges_out = new std::vector<Connection*>(0); - -} - -void NeuronTanh::activate( ) { - - double a = this->activation_function_parameters[0]; - double x = this->potential; - double ex = std::pow(E, x - a); - double exi = 1.0 / ex; - - this->state = (ex - exi) / (ex + exi); - -} - -double NeuronTanh::activation_function_eval_partial_derivative(int param_idx) { - - double a = this->activation_function_parameters[0]; - double x = this->potential; - - - if(param_idx == 0){ - /** - * TODO - * Same as activation_function_get_derivative() - */ - double ex = -4.0 * std::pow(E, 2.0 * (x + a)); - double exi = std::pow(E, 2.0 * a) + std::pow(E, 2.0 * x); - - return ex / (exi * exi); - } - - return 0.0; - -} - -double NeuronTanh::activation_function_eval_derivative( ) { - - double a = this->activation_function_parameters[0]; - double x = this->potential; - double ex = -4.0 * std::pow(E, 2.0 * (x + a)); - double exi = std::pow(E, 2.0 * a) + std::pow(E, 2.0 * x); - - return ex / (exi * exi); -} - -Neuron* NeuronTanh::get_derivative() { - return nullptr; -} \ No newline at end of file diff --git a/src/Neuron/NeuronTanh.h b/src/Neuron/NeuronTanh.h deleted file mode 100644 index 3d5ce6d8aabf4ad6bcabb55193612606dde7241d..0000000000000000000000000000000000000000 --- a/src/Neuron/NeuronTanh.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * DESCRIPTION OF THE CLASS - * - * @author Martin Beseda - * @author Martin Mrovec - * @author Michal Kravčenko - * @date 2017 - 2018 - */ - -#ifndef INC_4NEURO_NEURONTANH_H -#define INC_4NEURO_NEURONTANH_H - -#include <cmath> -#include "Neuron.h" -#include "../constants.h" - -class NeuronTanh:public Neuron, public IDifferentiable { - friend class boost::serialization::access; - -protected: - template<class Archive> - void serialize(Archive & ar, const unsigned int version){ - //TODO separate implementation to NeuronLogistic.cpp! - ar & boost::serialization::base_object<Neuron>(*this); - }; - -public: - - Neuron* get_copy( ); - - /** - * Constructs the object of the Hyperbolic Tangent >neuron with activation function - * f(x) = (e^(x-a) - e^(a-x))/(e^(x-a) + e^(a-x)) - * @param[in] a First coefficient, stored in activation_function_parameters[0] - */ - explicit NeuronTanh(double a = 0.0); - - /** - * Evaluates '(e^(x-a) - e^(a-x))/(e^(x-a) + e^(a-x))' and stores the result into the 'state' property - */ - void activate( ) override; - - /** - * Calculates the partial derivative of the activation function - * f(x) = (e^(x-a) - e^(a-x))/(e^(x-a) + e^(a-x)) - * @param[in] param_idx Index of the parameter to calculate derivative of - * @return Partial derivative of the activation function according to the - * 'param_idx'-th parameter. - */ - double activation_function_eval_partial_derivative(int param_idx) override; - - /** - * TODO - * Wrong return statement, there is no b - * Calculates d/dx of (e^(x-a) - e^(a-x))/(e^(x-a) + e^(a-x)) - * @return a * e^(b - x) * [e^(b - x) + 1]^(-a) - */ - double activation_function_eval_derivative( ) override; - - /** - * Returns a pointer to a Neuron with derivative as its activation function - * @return - */ - Neuron* get_derivative() override; -}; - - -#endif //INC_4NEURO_NEURONTANH_H diff --git a/src/examples/net_test_ode_1.cpp b/src/examples/net_test_ode_1.cpp index 525174bdab9d86b9e4e8af2fd094aa63bf0b7838..7cc320be3d373dfde557496406b27ba49e0b8ebf 100644 --- a/src/examples/net_test_ode_1.cpp +++ b/src/examples/net_test_ode_1.cpp @@ -5,18 +5,103 @@ * y(0) = 1 * (d/dt)y(0) = 1 * + * ------------------------------------------- + * Analytical solution: e^(-2x) * (3x + 1) + * * @author Michal Kravčenko * @date 17.7.18 - */ - +#include <random> #include <vector> #include <utility> +#include <iostream> #include "../include/4neuro.h" #include "Solvers/DESolver.h" -int main() { +void test_analytical_gradient_y(unsigned int n_inner_neurons) { + unsigned int n_inputs = 1; +} + +void test_analytical_y(unsigned int n_inner_neurons){ + unsigned int n_inputs = 1; + unsigned int n_outputs = 1; + unsigned int n_equations = 1; + + /* SETUP OF THE TRAINING DATA */ + std::vector<double> inp, out; + + double d1_s = 0.0, d1_e = 1.0, frac, alpha, x; + + /* TRAIN DATA FOR THE GOVERNING DE */ + std::vector<std::pair<std::vector<double>, std::vector<double>>> data_vec_g; + unsigned int train_size = 150; + + /* ISOTROPIC TRAIN SET */ + frac = (d1_e - d1_s) / (train_size - 1); +// for(unsigned int i = 0; i < train_size; ++i){ +// x = frac * i; +// inp = {x}; +// out = {std::pow(E, -2 * x) * (3 * x + 1)}; +// data_vec_g.emplace_back(std::make_pair(inp, out)); +// +// std::cout << i + 1 << " " << x << " " << out[0] << std::endl; +// } + + /* CHEBYSCHEV TRAIN SET */ + alpha = PI / (train_size - 1); + frac = 0.5 * (d1_e - d1_s); + for(unsigned int i = 0; i < train_size; ++i){ + x = (std::cos(PI - alpha * i) + 1.0) * frac + d1_s; + inp = {x}; + out = {std::pow(E, -2 * x) * (3 * x + 1)}; + data_vec_g.emplace_back(std::make_pair(inp, out)); + + std::cout << i + 1 << " " << x << " " << out[0] << std::endl; + } + DataSet ds_00(&data_vec_g); + +// return; + + DESolver solver_01( n_equations, n_inputs, n_inner_neurons, n_outputs ); + + NeuralNetwork * solution = solver_01.get_solution(); + + + /* PARTICLE SWARM TRAINING METHOD SETUP */ + unsigned int max_iters = 150; + + //must encapsulate each of the partial error functions + double *domain_bounds = new double[ 2 * n_inner_neurons * (n_inputs + n_outputs) ]; + for(unsigned int i = 0; i < n_inner_neurons * (n_inputs + n_outputs); ++i){ + domain_bounds[2 * i] = -800.0; + domain_bounds[2 * i + 1] = 800.0; + } + + double c1 = 0.5, c2 = 0.8, w = 0.8; + + unsigned int n_particles = 100; + + double gamma = 0.5, epsilon = 0.001, delta = 0.9; + + MSE mse(solution, &ds_00); + ParticleSwarm swarm_01(&mse, domain_bounds, c1, c2, w, n_particles, max_iters); + swarm_01.optimize( gamma, epsilon, delta ); + + unsigned int n_test_points = 100; + std::vector<double> input(1), output(1); + double error = 0.0; + for(unsigned int i = 0; i < n_test_points; ++i){ + input[0] = i * ((d1_e - d1_s) / (n_test_points - 1)) + d1_s; + solution->eval_single(input, output); + std::cout << i + 1 << " " << std::abs(output[0] - std::pow(E, -2 * input[0]) * (3 * input[0] + 1))<< " " << output[0] << std::endl; + } + + delete [] domain_bounds; +} + +void test_odr(unsigned int n_inner_neurons){ unsigned int n_inputs = 1; unsigned int n_inner_neurons = 5; unsigned int n_outputs = 1; @@ -107,18 +192,41 @@ int main() { domain_bounds[2 * i + 1] = 800.0; } - double c1 = 0.5, c2 = 0.7, w = 0.3; + double c1 = 0.5, c2 = 1.5, w = 0.8; - unsigned int n_particles = 25; + unsigned int n_particles = 100; - double gamma = 0.8, epsilon = 1e-6, delta = 0.9; + double gamma = 0.5, epsilon = 0.02, delta = 0.9; solver_01.solve_via_particle_swarm( domain_bounds, c1, c2, w, n_particles, max_iters, gamma, epsilon, delta ); NeuralNetwork *solution = solver_01.get_solution(); + unsigned int n_test_points = 100; + std::vector<double> input(1), output(1); + for(unsigned int i = 0; i < n_test_points; ++i){ + + input[0] = i * ((d1_e - d1_s) / (n_test_points - 1)) + d1_s; + + solution->eval_single(input, output); + + std::cout << i + 1 << " " << output[0] << std::endl; + } + delete [] domain_bounds; +} + +int main() { + + unsigned int n_inner_neurons = 20; + +// test_odr(n_inner_neurons); + + test_analytical_y(n_inner_neurons); + test_analytical_gradient_y(n_inner_neurons); + + return 0; -} \ No newline at end of file +} diff --git a/src/tests/Connection_test.cpp b/src/tests/Connection_test.cpp deleted file mode 100644 index 027c696c88e37e52175937f74bf15fd80dcc55a3..0000000000000000000000000000000000000000 --- a/src/tests/Connection_test.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/** - * DESCRIPTION OF THE CLASS - * - * @author David Vojtek - * @date 2018 - */ - -#define BOOST_TEST_NO_MAIN - -#include <boost/test/unit_test.hpp> - - -#include "../NetConnection/Connection.h" -#include "../NetConnection/ConnectionWeight.h" -#include "../Neuron/NeuronLinear.h" -#include <iostream> -/** - * Boost testing suite for testing Connection.h - */ - -BOOST_AUTO_TEST_SUITE(Connection_test) - - /** - * Test of constructor of Connection - */ - BOOST_AUTO_TEST_CASE(Connection_construction__test) { - - Neuron *neuron1 = new NeuronLinear(2, 3); - Neuron *neuron2 = new NeuronLinear(4, 5); - std::vector<double> w_array = {2, 3, 4, 5, 6}; - - ConnectionWeight *conn = new ConnectionWeight(2, &w_array); - Connection connection(neuron1, neuron2, conn); - //Test of correct input neuron - BOOST_CHECK_EQUAL(neuron1, connection.get_neuron_in()); - //Test of correct output neuron - BOOST_CHECK_EQUAL(neuron2, connection.get_neuron_out()); - } - - /** - * Test of pass_signal method - */ - BOOST_AUTO_TEST_CASE(Connection_pass_signal_test) { - - Neuron *neuron1 = new NeuronLinear(2, 3); - Neuron *neuron2 = new NeuronLinear(4, 5); - std::vector<double> w_array = {2, 3, 4, 5, 6}; - std::function<double(double *, int *, int)> f = [](double *weight_array, int *index_array, int n_params) { - double a = weight_array[0]; - double b = weight_array[1]; - return (a + 1.5 * b); - }; - - - ConnectionWeight *conn = new ConnectionWeight(2, &w_array); - - Connection connection(neuron1, neuron2, conn); - - neuron1->activate(); - neuron2->activate(); - // test of neuron state before passing signal - BOOST_CHECK_EQUAL(4, neuron2->get_state()); - connection.pass_signal(); - neuron2->activate(); - // test of neuron state after passing signal - BOOST_CHECK_EQUAL(7204, neuron2->get_state()); - - } - - -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/src/tests/NeuronTanh.cpp b/src/tests/NeuronTanh.cpp deleted file mode 100644 index cac6e0982d00011a03c6917ca6f5b439e7527d96..0000000000000000000000000000000000000000 --- a/src/tests/NeuronTanh.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/** - * DESCRIPTION OF THE CLASS - * - * @author David Vojtek - * @date 2018 - */ - -#define BOOST_TEST_NO_MAIN - -#include <boost/test/unit_test.hpp> - -#include "../Neuron/NeuronTanh.h" -/** - * Boost testing suite for testing NeuronTanh.h - * doesn't test inherited methods - */ -BOOST_AUTO_TEST_SUITE(neuronTanh_test) - - /** - * Test of creating new instance of NeuronTanh - */ - BOOST_AUTO_TEST_CASE(neuronTanh_construction__test) { - NeuronTanh neuron(1.745); - //Test of correct value of activation function parameter - BOOST_CHECK_EQUAL(neuron.activation_function_get_parameter(0), 1.745); - } - - /** - * Test of activate method - */ - BOOST_AUTO_TEST_CASE(neuronTanh_activate__test) { - NeuronTanh neuron(2.0); - neuron.activate(); - //Test of correct state after activate neuron - BOOST_CHECK_CLOSE(-0.96402758007581, neuron.get_state(), 0.00001); - } - - /** - * Test of derivative methods - */ - BOOST_AUTO_TEST_CASE(neuronTanh_derivative_test) { - NeuronTanh neuron(2.0); - - //Test of correct output of activation_function_get_derivative method - BOOST_CHECK_CLOSE(-0.0706508248531644, neuron.activation_function_eval_derivative(), 0.00001); - //Tests of correct outputs of activation_function_get_partial_derivative method - BOOST_CHECK_CLOSE(-0.0706508248531644, neuron.activation_function_eval_partial_derivative(0), 0.00001); - BOOST_CHECK_EQUAL(0.0, neuron.activation_function_eval_partial_derivative(10000)); - } - -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file