- 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));
}