Skip to content
Snippets Groups Projects
net_test_1.cpp 4.25 KiB
Newer Older
  • Learn to ignore specific revisions
  • /**
     * Basic example using particle swarm method to train the network
     */
    
    
    //
    // Created by martin on 7/16/18.
    //
    
    
    #include <vector>
    
    
        std::cout << "Running lib4neuro example   1: Basic use of the particle swarm method to train a simple network with few linear neurons" << std::endl;
        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));
    
        DataSet ds(&data_vec);
    
        /* NETWORK DEFINITION */
    
    
        /* Input neurons */
    
    Michal Kravcenko's avatar
    Michal Kravcenko committed
        NeuronLinear *i1 = new NeuronLinear( );  //f(x) = x
        NeuronLinear *i2 = new NeuronLinear( );  //f(x) = x
    
    
        /* Output neuron */
    
        NeuronLinear *o1 = new NeuronLinear( );  //f(x) = x
    
    
    
    
        /* Adding neurons to the net */
    
        size_t idx1 = net.add_neuron(i1, BIAS_TYPE::NO_BIAS);
        size_t idx2 = net.add_neuron(i2, BIAS_TYPE::NO_BIAS);
    
        size_t idx3 = net.add_neuron(o1, BIAS_TYPE::NO_BIAS);
    //
    
    
        /* Adding connections */
    
        net.add_connection_simple(idx1, idx3, SIMPLE_CONNECTION_TYPE::NEXT_WEIGHT);
        net.add_connection_simple(idx2, idx3, SIMPLE_CONNECTION_TYPE::NEXT_WEIGHT);
    
    
        //net.randomize_weights();
    
    
    Michal Kravcenko's avatar
    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);
    
        /* ERROR FUNCTION SPECIFICATION */
        MSE mse(&net, &ds);
    
        /* 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;
    
    
        ParticleSwarm swarm_01(
                &domain_bounds,
                c1,
                c2,
                w,
                gamma,
                epsilon,
                delta,
                n_particles,
                iter_max
        );
        swarm_01.optimize( mse );
    
        std::vector<double> *parameters = swarm_01.get_parameters();
    
        net.copy_parameter_space(parameters);
    
        printf("w1 = %10.7f\n", parameters->at( 0 ));
        printf("w2 = %10.7f\n", parameters->at( 1 ));
        std::cout << "***********************************************************************************************************************" <<std::endl;
        /* ERROR CALCULATION */
        double error = 0.0;
        inp = {0, 1};
        net.eval_single( inp, out );
        error += (0.5 - out[0]) * (0.5 - out[0]);
        std::cout << "x = (0,   1), expected output: 0.50, real output: " << out[0] << std::endl;
    
        inp = {1, 0.5};
        net.eval_single( inp, out );
        error += (0.75 - out[0]) * (0.75 - out[0]);
        std::cout << "x = (1, 0.5), expected output: 0.75, real output: " << out[0] << std::endl;
        std::cout << "Run finished! Error of the network: " << 0.5 * error << std::endl;