Skip to content
Snippets Groups Projects
main.cpp 7.29 KiB
Newer Older
  • Learn to ignore specific revisions
  • /**
     * DESCRIPTION OF THE FILE
     *
     * @author Michal Kravčenko
     * @date 14.6.18 -
     */
    
    
    #include <iostream>
    #include <cstdio>
    #include <fstream>
    
    #include <vector>
    #include <utility>
    
    #include <algorithm>
    
    #include <boost/archive/text_oarchive.hpp>
    #include <boost/archive/text_iarchive.hpp>
    
    #include "Network/NeuralNetwork.h"
    #include "Neuron/NeuronLinear.h"
    
    #include "NetConnection/Connection.h"
    #include "NetConnection/ConnectionWeightIdentity.h"
    
    
    #include "Neuron/NeuronBinary.h"
    #include "Neuron/NeuronTanh.h"
    
    #include "DataSet/DataSet.h"
    
    //TODO rewrite "tests" to separate examples
    
    
    //TODO prepsat tak, aby neuronova sit managovala destruktory vsech potrebnych objektu (kvuli serializaci)
    
    /**
     * Test of simple neural network
     * Network should evaluate the function f(x) = x + 1
     */
    
        std::vector<double> in(1);
        std::vector<double> out(1);
    
    
        NeuralNetwork net;
        NeuronLinear* u1 = new NeuronLinear(1.0, 1.0); //f(x) = x + 1.0
        NeuronLinear* u2 = new NeuronLinear(0.0, 1.0); //f(x) = x
        int idx1 = net.add_neuron(u1);
        int idx2 = net.add_neuron(u2);
    ////////////////////// SIMPLE EDGE WEIGHT ////////////////////////////////////////
    //    net.add_connection_simple(idx1, idx2, -1, 1.0);
    ////////////////////// END SIMPLE EDGE WEIGHT ////////////////////////////////////////
    
    /////////////////////////BEGIN OF COMPLEX EDGE WEIGHT//////////////////////////////
    
    Michal Kravcenko's avatar
    Michal Kravcenko committed
       std::function<double(double *, size_t*, size_t)> weight_function = [](double * weight_array, size_t * index_array, size_t n_params){
    
            double a = weight_array[index_array[0]];
            double b = weight_array[index_array[1]];
    //        printf("eval: %f, %f\n",  a, b);
    
    Michal Kravcenko's avatar
    Michal Kravcenko committed
        size_t  weight_indices [2] = {0, 1};
    
        double weight_values [2] = {1.0, 5.0};
        net.add_connection_general(idx1, idx2, &weight_function, weight_indices, weight_values, 2);
    /////////////////////////END OF COMPLEX EDGE WEIGHT//////////////////////////////
    
        for(int i = 0; i < 20; ++i){
            in[0] = 0.05 * i;
            net.eval_single(in, out);
    
            printf("x = %3.2f, f(x) = %3.2f, expected output = %3.2f\n", in[0], out[0], in[0] + 1.0);
        }
    
    
    /**
     * Test of DataSet serialization
     */
    
    std::vector<double> out_f(std::vector<double> v) {
        double sum = 0;
        for(auto& e : v) {
            sum += e;
        }
    
        std::vector<double> out{sum*2, sum*3, sum*4};
        return out;
    }
    
    
    void test3() {
    
    
        /* Manually created data set */
        std::cout << "Manually created data set" << std::endl;
    
        std::vector<std::pair<std::vector<double>, std::vector<double>>> data_vec;
        std::vector<double> inp, out;
    
        for(int i = 0; i < 3; i++) {
            inp.push_back(i);
            out.push_back(i+4);
        }
    
        data_vec.emplace_back(std::make_pair(inp, out));
    
        DataSet ds(&data_vec);
    
        ds.print_data();
    
        ds.store_text("stored_data.4ds");
    
        DataSet ds2("stored_data.4ds");
    
        ds2.print_data();
    
    
        /* Isotropic data set */
        std::cout << "Isotropic data set:" << std::endl;
        std::vector<double> bounds{0,3,0,2};
    
        std::cout << "original one:" << std::endl;
        DataSet ds3(bounds, 5, out_f, 3);
        ds3.print_data();
        ds3.store_text("stored_data2.4ds");
    
        std::cout << "loaded one:" << std::endl;
        DataSet ds4("stored_data2.4ds");
        ds4.print_data();
    
    double particle_swarm_test_function(double *x){
    //    return x[0] * x[1] - x[0] * x[0] + x[1] * x[2];
        return x[0] * x[0];
    }
    
    NeuralNetwork net;
    std::vector<std::vector<double>*> *train_data_input;
    std::vector<std::vector<double>*> *train_data_output;
    
    double test_particle_swarm_neural_net_error_function(double *weights){
    
        net.copy_weights(weights);
    
        unsigned int dim_out = train_data_output->at(0)->size();
    
    //    unsigned int dim_in = train_data_input->at(0)->size();
    
    
        double error = 0.0, val;
    
        std::vector<double> output( dim_out );
        for(unsigned int i = 0; i < train_data_input->size(); ++i){
    
            net.eval_single(*train_data_input->at(i), output);
    
            for(unsigned int j = 0; j < dim_out; ++j){
                val = output[j] - train_data_output->at(i)->at(j);
                error += val * val;
            }
    
        }
    
    
        printf("INPUT: ");
        for(unsigned int i = 0; i < dim_in; ++i){
            printf("%f ", weights[i]);
        }
        printf(", ERROR: %f\n", 0.5 * error);
    
        return 0.5 * error;
    }
    
    //TODO proper memory management
    void test_particle_swarm_neural_net(){
    
    
    //    unsigned int dim_in = 2;
    //    unsigned int dim_out = 1;
    //
    //    /* TRAIN DATA DEFINITION */
    //    train_data_input = new std::vector<std::vector<double>*>();
    //    train_data_output = new std::vector<std::vector<double>*>();
    //
    //    std::vector<double> *input_01 = new std::vector<double>(dim_in);
    //    std::vector<double> *input_02 = new std::vector<double>(dim_in);
    //
    //    std::vector<double> *output_01 = new std::vector<double>(dim_out);
    //    std::vector<double> *output_02 = new std::vector<double>(dim_out);
    //
    //    (*input_01)[0] = 0.0;
    //    (*input_01)[1] = 1.0;
    //    (*output_01)[0] = 0.5;
    //
    //    (*input_02)[0] = 1.0;
    //    (*input_02)[1] = 0.5;
    //    (*output_02)[0] = 0.75;
    //
    //    train_data_input->push_back(input_01);
    //    train_data_output->push_back(output_01);
    //
    //    train_data_input->push_back(input_02);
    //    train_data_output->push_back(output_02);
    //    /* NETWORK DEFINITION */
    //
    //
    //    NeuronLinear* i1 = new NeuronLinear(0.0, 1.0); //f(x) = x
    //    NeuronLinear* i2 = new NeuronLinear(0.0, 1.0); //f(x) = x
    //
    ////    NeuronLogistic* o1 = new NeuronLogistic(1.0, 0.0); //f(x) = (1 + e^(-x + 0.0))^(1.0)
    //    NeuronLinear* o1 = new NeuronLinear(1.0, 2.0); //f(x) = 2x + 1
    //
    //    int idx1 = net.add_neuron(i1);
    //    int idx2 = net.add_neuron(i2);
    //    int idx3 = net.add_neuron(o1);
    //
    //    net.add_connection_simple(idx1, idx3, -1, 1.0);
    //    net.add_connection_simple(idx2, idx3, -1, 1.0);
    //
    //    /* PARTICLE SETUP */
    //    double (*F)(double*) = &test_particle_swarm_neural_net_error_function;
    //
    //    unsigned int n_edges = 2;
    //    unsigned int dim = n_edges, max_iters = 2000;
    //
    //
    //    double domain_bounds [4] = {-800.0, 800.0, -800.0, 800.0};
    //
    //    double c1 = 0.5, c2 = 1.5, w = 0.8;
    //
    //    unsigned int n_particles = 10;
    //
    //    ParticleSwarm swarm_01(F, dim, domain_bounds, c1, c2, w, n_particles, max_iters);
    //
    //    swarm_01.optimize(0.5, 0.02);
    //
    //    /* CLEANUP PHASE */
    //    for( std::vector<double> *input: *train_data_input){
    //        delete input;
    //    }
    //    for( std::vector<double> *output: *train_data_output){
    //        delete output;
    //    }
    //
    //    delete train_data_output;
    //    delete train_data_input;
    
    //
    //void test_particle_swarm(){
    //    double (*F)(double*) = &particle_swarm_test_function;
    //
    //    unsigned int dim = 3, max_iters = 100;
    //
    ////    double domain_bounds [2] = {2.0, 3.0};
    //    double domain_bounds [6] = {-3.0, 3.0, 2.0, 5.0, 1.0, 15.0};
    //
    //    double c1 = 0.5, c2 = 1.5, w = 1.0;
    //
    //    unsigned int n_particles = 1000;
    //
    //    double accuracy = 1e-6;
    //
    //    ParticleSwarm swarm_01(F, dim, domain_bounds, c1, c2, w, n_particles, max_iters);
    //
    //    swarm_01.optimize(0.5, accuracy);
    //}
    
        test_particle_swarm_neural_net();
    
    Martin Beseda's avatar
    Martin Beseda committed
    }