- 01
 - 02
 - 03
 - 04
 - 05
 - 06
 - 07
 - 08
 - 09
 - 10
 - 11
 - 12
 - 13
 - 14
 - 15
 - 16
 - 17
 - 18
 - 19
 - 20
 - 21
 - 22
 - 23
 - 24
 - 25
 - 26
 - 27
 - 28
 - 29
 - 30
 - 31
 - 32
 - 33
 - 34
 - 35
 - 36
 - 37
 - 38
 - 39
 - 40
 - 41
 - 42
 - 43
 - 44
 - 45
 - 46
 - 47
 - 48
 - 49
 - 50
 - 51
 - 52
 - 53
 - 54
 - 55
 - 56
 - 57
 - 58
 - 59
 - 60
 - 61
 - 62
 - 63
 - 64
 - 65
 - 66
 - 67
 - 68
 
std::tuple<std::vector<long double> , std::vector<std::vector<long double> > , std::vector<long double> >
inline
training(const std::size_t hidden_neurons,
         const long double hlr,
         const std::size_t epochs,
         const std::vector< long double > train_ou,
         const std::vector< std::vector< long double > >& train_in,
         volatile bool * reset)
{
    auto train_inp = train_in;
    auto train_out = train_ou;
//    std::cerr << "hidden_neurons: " << hidden_neurons << std::endl;
//    std::cerr << "hlr: " << hlr << std::endl;
//    std::cerr << "epochs: " << epochs << std::endl;
//    std::cerr << "train_inp: " << train_inp << std::endl;
//    std::cerr << "train_out: " << train_out << std::endl;
    const auto mu_inp = mean( train_inp );
    const auto sigma_inp = stand( train_inp );
    train_inp = ( train_inp - mu_inp[ 0 ] ) / sigma_inp[ 0 ];
    const auto mu_out = mean( train_out );
    const auto sigma_out = stand( train_out );
    train_out = ( train_out - mu_out ) / sigma_out;
    const auto patterns = size( train_inp ).first;
    std::cout << "patterns: " << patterns << std::endl;
    auto bias = ones( patterns );
    train_inp = merge( train_inp, bias );
    const auto inputs = size( train_inp ).second;
    std::vector< long double > err( epochs );
    auto weight_input_hidden = ( randn( inputs, hidden_neurons) - 0.5l ) / 10.0l;
    auto weight_hidden_output = ( randn( hidden_neurons ) - 0.5l ) / 10.0l;
    for( std::size_t i = 0; i < epochs; ++i ) {
        if ( *reset ) {
            break;
        }
        const auto alr = hlr;
        const auto blr = alr / 10.0;
        for( std::size_t j = 0; j < patterns; ++j ){
            const auto patnum = ( static_cast<std::size_t>( round( randd() * patterns + 0.5 ) ) - 1 ) % patterns;
            const auto this_pat = train_inp[ patnum ];
            const auto act = train_out[ patnum ];
            const auto hval = feval( []( const long double & v ){ return std::tanh( v ); }, this_pat * weight_input_hidden );
            const auto pred = hval * weight_hidden_output;
            const auto error = pred - act;
            const auto delta_HO = hval * error * blr;
            weight_hidden_output = weight_hidden_output - delta_HO;
            const auto m1 = weight_hidden_output * alr * error;
            const auto m2 = 1.0l - (hval^2);
            const auto m3 = dot_operator( m1, m2, std::multiplies< long double >());
            const auto m4 = vec_to_vecvec( m3 );
            const auto delta_IH = m4 * this_pat;
            weight_input_hidden = weight_input_hidden - trans( delta_IH );
        }
        const auto p1 = feval( []( const long double& v ){ return std::tanh( v ); }, train_inp * weight_input_hidden );
        const auto pred = weight_hidden_output * trans( p1 );
        const auto error = pred - train_out;
        const auto error_sq = error ^ 2;
        err[ i ] = std::sqrt( std::accumulate( error_sq.cbegin(), error_sq.cend(), 0.0, std::plus<long double> () ) );
        std::cerr << "err[ i ]: " << err[ i ] << ' ' << i <<  std::endl;
    }
    return std::move(std::make_tuple(weight_hidden_output, weight_input_hidden, err));
}
                                    
 Follow us!