00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "root_mean_squared_error.h"
00019
00020
00021
00022 #include <iostream>
00023 #include <cmath>
00024 #include <fstream>
00025 #include <limits>
00026 #include <sstream>
00027 #include <string>
00028
00029
00030
00031 #include "../../parsers/tinyxml/tinyxml.h"
00032
00033
00034 namespace OpenNN
00035 {
00036
00037
00038
00043
00044 RootMeanSquaredError::RootMeanSquaredError(void) : PerformanceTerm()
00045 {
00046 }
00047
00048
00049
00050
00055
00056 RootMeanSquaredError::RootMeanSquaredError(NeuralNetwork* new_neural_network_pointer)
00057 : PerformanceTerm(new_neural_network_pointer)
00058 {
00059 }
00060
00061
00062
00063
00068
00069 RootMeanSquaredError::RootMeanSquaredError(DataSet* new_data_set_pointer)
00070 : PerformanceTerm(new_data_set_pointer)
00071 {
00072 }
00073
00074
00075
00076
00083
00084 RootMeanSquaredError::RootMeanSquaredError(NeuralNetwork* new_neural_network_pointer, DataSet* new_data_set_pointer)
00085 : PerformanceTerm(new_neural_network_pointer, new_data_set_pointer)
00086 {
00087 }
00088
00089
00090
00091
00096
00097 RootMeanSquaredError::RootMeanSquaredError(TiXmlElement* root_mean_squared_error_element)
00098 : PerformanceTerm(root_mean_squared_error_element)
00099 {
00100 }
00101
00102
00103
00104
00106
00107 RootMeanSquaredError::~RootMeanSquaredError(void)
00108 {
00109 }
00110
00111
00112
00113
00114
00115
00119
00120 void RootMeanSquaredError::check(void) const
00121 {
00122 std::ostringstream buffer;
00123
00124
00125
00126 if(!neural_network_pointer)
00127 {
00128 buffer << "OpenNN Exception: RootMeanSquaredError class.\n"
00129 << "void check(void) const method.\n"
00130 << "Pointer to neural network is NULL.\n";
00131
00132 throw std::logic_error(buffer.str().c_str());
00133 }
00134
00135 const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
00136
00137 if(!multilayer_perceptron_pointer)
00138 {
00139 buffer << "OpenNN Exception: RootMeanSquaredError class.\n"
00140 << "void check(void) const method.\n"
00141 << "Pointer to multilayer perceptron is NULL.\n";
00142
00143 throw std::logic_error(buffer.str().c_str());
00144 }
00145
00146 const unsigned int inputs_number = multilayer_perceptron_pointer->count_inputs_number();
00147 const unsigned int outputs_number = multilayer_perceptron_pointer->count_outputs_number();
00148
00149 if(inputs_number == 0)
00150 {
00151 buffer << "OpenNN Exception: RootMeanSquaredError class.\n"
00152 << "void check(void) const method.\n"
00153 << "Number of inputs in multilayer perceptron object is zero.\n";
00154
00155 throw std::logic_error(buffer.str().c_str());
00156 }
00157
00158 if(outputs_number == 0)
00159 {
00160 buffer << "OpenNN Exception: RootMeanSquaredError class.\n"
00161 << "void check(void) const method.\n"
00162 << "Number of outputs in multilayer perceptron object is zero.\n";
00163
00164 throw std::logic_error(buffer.str().c_str());
00165 }
00166
00167
00168
00169 if(!data_set_pointer)
00170 {
00171 buffer << "OpenNN Exception: RootMeanSquaredError class.\n"
00172 << "void check(void) const method.\n"
00173 << "Pointer to data set is NULL.\n";
00174
00175 throw std::logic_error(buffer.str().c_str());
00176 }
00177
00178
00179
00180 const VariablesInformation& variables_information = data_set_pointer->get_variables_information();
00181
00182 const unsigned int targets_number = variables_information.count_targets_number();
00183
00184 if(inputs_number != inputs_number)
00185 {
00186 buffer << "OpenNN Exception: RootMeanSquaredError class.\n"
00187 << "void check(void) const method.\n"
00188 << "Number of inputs in multilayer perceptron must be equal to number of inputs in data set.\n";
00189
00190 throw std::logic_error(buffer.str().c_str());
00191 }
00192
00193 if(outputs_number != targets_number)
00194 {
00195 buffer << "OpenNN Exception: RootMeanSquaredError class.\n"
00196 << "void check(void) const method.\n"
00197 << "Number of outputs in multilayer perceptron must be equal to number of targets in data set.\n";
00198
00199 throw std::logic_error(buffer.str().c_str());
00200 }
00201 }
00202
00203
00204
00205
00208
00209 double RootMeanSquaredError::calculate_evaluation(void) const
00210 {
00211
00212
00213 #ifdef _DEBUG
00214
00215 check();
00216
00217 #endif
00218
00219
00220
00221 const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
00222
00223 const unsigned int inputs_number = multilayer_perceptron_pointer->count_inputs_number();
00224 const unsigned int outputs_number = multilayer_perceptron_pointer->count_outputs_number();
00225
00226
00227
00228 const InstancesInformation& instances_information = data_set_pointer->get_instances_information();
00229
00230 const unsigned int training_instances_number = instances_information.count_training_instances_number();
00231
00232
00233
00234 Vector<double> inputs(inputs_number);
00235 Vector<double> outputs(outputs_number);
00236 Vector<double> targets(outputs_number);
00237
00238 double sum_squared_error = 0.0;
00239
00240 for(unsigned int i = 0; i < training_instances_number; i++)
00241 {
00242
00243
00244 inputs = data_set_pointer->get_training_input_instance(i);
00245
00246
00247
00248 outputs = multilayer_perceptron_pointer->calculate_outputs(inputs);
00249
00250
00251
00252 targets = data_set_pointer->get_training_target_instance(i);
00253
00254
00255
00256 sum_squared_error += outputs.calculate_sum_squared_error(targets);
00257 }
00258
00259 return(sqrt(sum_squared_error/(double)training_instances_number));
00260 }
00261
00262
00263
00264
00269
00270 double RootMeanSquaredError::calculate_evaluation(const Vector<double>& parameters) const
00271 {
00272
00273
00274 #ifdef _DEBUG
00275
00276 check();
00277
00278 #endif
00279
00280 #ifdef _DEBUG
00281
00282 std::ostringstream buffer;
00283
00284 unsigned int size = parameters.size();
00285
00286 unsigned int parameters_number = neural_network_pointer->count_parameters_number();
00287
00288 if(size != parameters_number)
00289 {
00290 buffer << "OpenNN Exception: RootMeanSquaredError class.\n"
00291 << "double calculate_evaluation(const Vector<double>&) const method.\n"
00292 << "Size (" << size << ") must be equal to number of parameters (" << parameters_number << ").\n";
00293
00294 throw std::logic_error(buffer.str().c_str());
00295 }
00296
00297 #endif
00298
00299 NeuralNetwork neural_network_copy(*neural_network_pointer);
00300
00301 neural_network_copy.set_parameters(parameters);
00302
00303 RootMeanSquaredError root_mean_squared_error_copy(*this);
00304
00305 root_mean_squared_error_copy.set_neural_network_pointer(&neural_network_copy);
00306
00307 return(root_mean_squared_error_copy.calculate_evaluation());
00308 }
00309
00310
00311
00312
00314
00315 Vector<double> RootMeanSquaredError::calculate_gradient(void) const
00316 {
00317
00318
00319 #ifdef _DEBUG
00320
00321 check();
00322
00323 #endif
00324
00325
00326
00327 const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
00328
00329 const unsigned int inputs_number = multilayer_perceptron_pointer->count_inputs_number();
00330 const unsigned int outputs_number = multilayer_perceptron_pointer->count_outputs_number();
00331
00332 const unsigned int layers_number = multilayer_perceptron_pointer->count_layers_number();
00333
00334 const unsigned int parameters_number = multilayer_perceptron_pointer->count_parameters_number();
00335
00336
00337
00338 Vector< Vector< Vector<double> > > first_order_forward_propagation(2);
00339
00340 const bool& conditions_layer_flag = neural_network_pointer->get_conditions_layer_flag();
00341
00342 const ConditionsLayer* conditions_layer_pointer = neural_network_pointer->get_conditions_layer_pointer();
00343
00344 Vector<double> particular_solution;
00345 Vector<double> homogeneous_solution;
00346
00347
00348
00349 const InstancesInformation& instances_information = data_set_pointer->get_instances_information();
00350
00351 const unsigned int training_instances_number = instances_information.count_training_instances_number();
00352
00353 Vector<double> inputs(inputs_number);
00354 Vector<double> targets(outputs_number);
00355
00356
00357
00358 double objective = calculate_evaluation();
00359
00360 Vector< Vector<double> > layers_delta;
00361
00362 Vector<double> output_objective_gradient(outputs_number);
00363
00364 Vector<double> point_gradient(parameters_number, 0.0);
00365
00366 Vector<double> objective_gradient(parameters_number, 0.0);
00367
00368
00369
00370 for(unsigned int i = 0; i < training_instances_number; i++)
00371 {
00372 inputs = data_set_pointer->get_training_input_instance(i);
00373
00374 targets = data_set_pointer->get_training_target_instance(i);
00375
00376 first_order_forward_propagation = multilayer_perceptron_pointer->calculate_first_order_forward_propagation(inputs);
00377
00378 const Vector< Vector<double> >& layers_activation = first_order_forward_propagation[0];
00379 const Vector< Vector<double> >& layers_activation_derivative = first_order_forward_propagation[1];
00380
00381 if(!conditions_layer_flag)
00382 {
00383 output_objective_gradient = (layers_activation[layers_number-1]-targets)/(training_instances_number*objective);
00384
00385 layers_delta = calculate_layers_delta(layers_activation_derivative, output_objective_gradient);
00386 }
00387 else
00388 {
00389 particular_solution = conditions_layer_pointer->calculate_particular_solution(inputs);
00390 homogeneous_solution = conditions_layer_pointer->calculate_homogeneous_solution(inputs);
00391
00392 output_objective_gradient = (particular_solution+homogeneous_solution*layers_activation[layers_number-1] - targets)/(training_instances_number*objective);
00393
00394 layers_delta = calculate_layers_delta(layers_activation_derivative, homogeneous_solution, output_objective_gradient);
00395 }
00396
00397 point_gradient = calculate_point_gradient(inputs, layers_activation, layers_delta);
00398 objective_gradient += point_gradient;
00399 }
00400
00401 return(objective_gradient);
00402 }
00403
00404
00405
00406
00408
00409 double RootMeanSquaredError::calculate_generalization_evaluation(void) const
00410 {
00411
00412
00413 #ifdef _DEBUG
00414
00415 check();
00416
00417 #endif
00418
00419 const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
00420
00421 const unsigned int inputs_number = multilayer_perceptron_pointer->count_inputs_number();
00422 const unsigned int outputs_number = multilayer_perceptron_pointer->count_outputs_number();
00423
00424 const InstancesInformation& instances_information = data_set_pointer->get_instances_information();
00425 const unsigned int generalization_instances_number = instances_information.count_generalization_instances_number();
00426
00427 if(generalization_instances_number == 0)
00428 {
00429 return(0.0);
00430 }
00431
00432 Vector<double> inputs(inputs_number);
00433 Vector<double> outputs(outputs_number);
00434 Vector<double> targets(outputs_number);
00435
00436 double generalization_objective = 0.0;
00437
00438 for(unsigned int i = 0; i < generalization_instances_number; i++)
00439 {
00440
00441
00442 inputs = data_set_pointer->get_generalization_input_instance(i);
00443
00444
00445
00446 outputs = multilayer_perceptron_pointer->calculate_outputs(inputs);
00447
00448
00449
00450 targets = data_set_pointer->get_generalization_target_instance(i);
00451
00452
00453
00454 generalization_objective += outputs.calculate_sum_squared_error(targets);
00455 }
00456
00457 return(sqrt(generalization_objective/(double)generalization_instances_number));
00458 }
00459
00460
00461
00462
00464
00465 Matrix<double> RootMeanSquaredError::calculate_Hessian(void) const
00466 {
00467 Matrix<double> m;
00468
00469 return(m);
00470 }
00471
00472
00473
00474
00476
00477 std::string RootMeanSquaredError::write_performance_term_type(void) const
00478 {
00479 return("ROOT_MEAN_SQUARED_ERROR");
00480 }
00481
00482
00483
00484
00487
00488 TiXmlElement* RootMeanSquaredError::to_XML(void) const
00489 {
00490 std::ostringstream buffer;
00491
00492
00493
00494 TiXmlElement* root_mean_squared_error_element = new TiXmlElement("RootMeanSquaredError");
00495 root_mean_squared_error_element->SetAttribute("Version", 4);
00496
00497
00498 {
00499 TiXmlElement* display_element = new TiXmlElement("Display");
00500 root_mean_squared_error_element->LinkEndChild(display_element);
00501
00502 buffer.str("");
00503 buffer << display;
00504
00505 TiXmlText* display_text = new TiXmlText(buffer.str().c_str());
00506 display_element->LinkEndChild(display_text);
00507 }
00508
00509 return(root_mean_squared_error_element);
00510 }
00511
00512
00513
00514
00516
00517 void RootMeanSquaredError::from_XML(TiXmlElement*)
00518 {
00519 }
00520
00521 }
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538