Newer
Older
//
// Created by martin on 7/15/18.
//

Michal Kravcenko
committed
size_t ErrorFunction::get_dimension() {
return this->dimension;
}
MSE::MSE(NeuralNetwork *net, DataSet *ds) {
this->net = net;
this->ds = ds;
this->dimension = net->get_n_weights() + net->get_n_biases();

Michal Kravcenko
committed
size_t dim_out = this->ds->get_output_dim();

Michal Kravcenko
committed
// unsigned int dim_in = this->ds->get_input_dim();
size_t n_elements = this->ds->get_n_elements();
double error = 0.0, val;
std::vector<std::pair<std::vector<double>, std::vector<double>>>* data = this->ds->get_data();
// //TODO instead use something smarter
// this->net->copy_weights(weights);
std::vector<double> output( dim_out );

Michal Kravcenko
committed
for( auto el: *data ){ // Iterate through every element in the test set

Michal Kravcenko
committed
this->net->eval_single(el.first, output, weights); // Compute the net output and store it into 'output' variable

Michal Kravcenko
committed
for(size_t j = 0; j < dim_out; ++j) { // Compute difference for every element of the output vector

Michal Kravcenko
committed
val = output[j] - el.second[j];

Michal Kravcenko
committed
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
void MSE::calculate_error_gradient( std::vector<double> ¶ms, std::vector<double> &grad, double alpha ) {
size_t dim_out = this->ds->get_output_dim( );
size_t n_elements = this->ds->get_n_elements();
std::vector<std::pair<std::vector<double>, std::vector<double>>>* data = this->ds->get_data();
std::vector<double> error_derivative( dim_out );
for( auto el: *data ){ // Iterate through every element in the test set
this->net->eval_single(el.first, error_derivative, ¶ms); // Compute the net output and store it into 'output' variable
for( size_t j = 0; j < dim_out; ++j){
error_derivative[ j ] = 2.0 * (error_derivative[ j ] - el.second[ j ]); //real - expected result
}
this->net->add_to_gradient_single( el.first, error_derivative, alpha / n_elements, grad );
}
}
std::vector<double>* MSE::get_parameters() {
std::vector<double> *output = new std::vector<double>( this->net->get_n_weights( ) + this->net->get_n_biases( ) );
size_t i = 0;
for(auto el: *this->net->get_parameter_ptr_weights()){
output->at( i ) = el;
++i;
}
for(auto el: *this->net->get_parameter_ptr_biases()){
output->at( i ) = el;
++i;
}
return output;
}
this->summand = nullptr;
this->summand_coefficient = nullptr;
if( this->summand ){
delete this->summand;
}
if( this->summand_coefficient ){
delete this->summand_coefficient;
}
}
double ErrorSum::eval(std::vector<double> *weights) {
double output = 0.0;
ErrorFunction *ef = nullptr;

Michal Kravcenko
committed
for( unsigned int i = 0; i < this->summand->size(); ++i ){
ef = this->summand->at( i );
if( ef ){
output += ef->eval( weights ) * this->summand_coefficient->at( i );
}
}
return output;
}

Michal Kravcenko
committed
void ErrorSum::calculate_error_gradient( std::vector<double> ¶ms, std::vector<double> &grad, double alpha ) {
ErrorFunction *ef = nullptr;
for( size_t i = 0; i < this->summand->size( ); ++i ){
ef = this->summand->at( i );
if( ef ){
ef->calculate_error_gradient( params, grad, this->summand_coefficient->at( i ) * alpha );
}
}
}

Michal Kravcenko
committed
void ErrorSum::add_error_function( ErrorFunction *F, double alpha ) {
if(!this->summand){
this->summand = new std::vector<ErrorFunction*>(0);
}
this->summand->push_back( F );
if(!this->summand_coefficient){
this->summand_coefficient = new std::vector<double>(0);
}
this->summand_coefficient->push_back( alpha );
if(F){
if(F->get_dimension() > this->dimension){
this->dimension = F->get_dimension();
}
// if(!this->dimension) {
// size_t max = 0;
// for(auto e : *this->summand) {
// if(e->get_dimension() > max) {
// max = e->get_dimension();
// }
// };
//
// this->dimension = max;
// }

Michal Kravcenko
committed
}
std::vector<double>* ErrorSum::get_parameters() {
return this->summand->at( 0 )->get_parameters( );