00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "NormalizedSquaredError.h"
00019
00020
00021
00022 #include <string>
00023 #include <sstream>
00024
00025 #include <iostream>
00026 #include <fstream>
00027 #include <limits>
00028 #include <cmath>
00029
00030 namespace Flood
00031 {
00032
00033
00034
00038
00039 NormalizedSquaredError::NormalizedSquaredError(void) : ObjectiveFunctional()
00040 {
00041 input_target_data_set_pointer = NULL;
00042 }
00043
00044
00045
00046
00051
00052 NormalizedSquaredError::NormalizedSquaredError(MultilayerPerceptron* new_multilayer_perceptron_pointer)
00053 : ObjectiveFunctional(new_multilayer_perceptron_pointer)
00054 {
00055 input_target_data_set_pointer = NULL;
00056 }
00057
00058
00059
00060
00065
00066 NormalizedSquaredError::NormalizedSquaredError(InputTargetDataSet* new_input_target_data_set_pointer)
00067 : ObjectiveFunctional()
00068 {
00069 input_target_data_set_pointer = new_input_target_data_set_pointer;
00070 }
00071
00072
00073
00074
00080
00081 NormalizedSquaredError::NormalizedSquaredError(MultilayerPerceptron* new_multilayer_perceptron_pointer, InputTargetDataSet* new_input_target_data_set_pointer)
00082 : ObjectiveFunctional(new_multilayer_perceptron_pointer)
00083 {
00084 input_target_data_set_pointer = new_input_target_data_set_pointer;
00085 }
00086
00087
00088
00089
00091
00092 NormalizedSquaredError::~NormalizedSquaredError(void)
00093 {
00094 }
00095
00096
00097
00098
00099
00100
00103
00104 void NormalizedSquaredError::set(void)
00105 {
00106 multilayer_perceptron_pointer = NULL;
00107 input_target_data_set_pointer = NULL;
00108 set_default();
00109 }
00110
00111
00112
00113
00117
00118 void NormalizedSquaredError::set(MultilayerPerceptron* new_multilayer_perceptron_pointer)
00119 {
00120 multilayer_perceptron_pointer = new_multilayer_perceptron_pointer;
00121 input_target_data_set_pointer = NULL;
00122 set_default();
00123 }
00124
00125
00126
00127
00131
00132 void NormalizedSquaredError::set(InputTargetDataSet* new_input_target_data_set_pointer)
00133 {
00134 multilayer_perceptron_pointer = NULL;
00135 input_target_data_set_pointer = new_input_target_data_set_pointer;
00136 set_default();
00137 }
00138
00139
00140
00141
00146
00147 void NormalizedSquaredError::set(MultilayerPerceptron* new_multilayer_perceptron_pointer, InputTargetDataSet* new_input_target_data_set_pointer)
00148 {
00149 multilayer_perceptron_pointer = new_multilayer_perceptron_pointer;
00150 input_target_data_set_pointer = new_input_target_data_set_pointer;
00151 set_default();
00152 }
00153
00154
00155
00156
00159
00160 void NormalizedSquaredError::set_input_target_data_set_pointer(InputTargetDataSet* new_input_target_data_set_pointer)
00161 {
00162 input_target_data_set_pointer = new_input_target_data_set_pointer;
00163 }
00164
00165
00166
00167
00170
00171 double NormalizedSquaredError::calculate_training_normalization_coefficient(void)
00172 {
00173 int training_instances_number = input_target_data_set_pointer->get_training_instances_number();
00174
00175
00176
00177 #ifdef _DEBUG
00178
00179 if(training_instances_number == 0)
00180 {
00181 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00182 << "double calculate_training_normalization_coefficient(void) method." << std::endl
00183 << "Number of training instances is zero." << std::endl;
00184
00185 exit(1);
00186 }
00187
00188 #endif
00189
00190 int target_variables_number = input_target_data_set_pointer->get_target_variables_number();
00191
00192 Vector<double> training_target_data_mean = input_target_data_set_pointer->calculate_training_target_data_mean();
00193
00194 Vector<double> training_target_instance(target_variables_number);
00195
00196 double training_normalization_coefficient = 0.0;
00197
00198 for(int i = 0; i < training_instances_number; i++)
00199 {
00200 training_target_instance = input_target_data_set_pointer->get_training_target_instance(i);
00201
00202 training_normalization_coefficient += (training_target_instance-training_target_data_mean).dot(training_target_instance-training_target_data_mean);
00203 }
00204
00205 return(training_normalization_coefficient);
00206 }
00207
00208
00209
00210
00213
00214 double NormalizedSquaredError::calculate_validation_normalization_coefficient(void)
00215 {
00216 int validation_instances_number = input_target_data_set_pointer->get_validation_instances_number();
00217
00218
00219
00220 #ifdef _DEBUG
00221
00222 if(validation_instances_number == 0)
00223 {
00224 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00225 << "double calculate_validation_normalization_coefficient(void) method." << std::endl
00226 << "Number of validation instances is zero." << std::endl;
00227
00228 exit(1);
00229 }
00230
00231 #endif
00232
00233 int target_variables_number = input_target_data_set_pointer->get_target_variables_number();
00234
00235 Vector<double> validation_target_data_mean = input_target_data_set_pointer->calculate_validation_target_data_mean();
00236
00237 Vector<double> validation_target_instance(target_variables_number);
00238
00239 double validation_normalization_coefficient = 0.0;
00240
00241 for(int i = 0; i < validation_instances_number; i++)
00242 {
00243 validation_target_instance = input_target_data_set_pointer->get_validation_target_instance(i);
00244
00245 validation_normalization_coefficient += (validation_target_instance-validation_target_data_mean).dot(validation_target_instance-validation_target_data_mean);
00246 }
00247
00248 return(validation_normalization_coefficient);
00249 }
00250
00251
00252
00253
00256
00257 double NormalizedSquaredError::calculate_objective(void)
00258 {
00259 int inputs_number = multilayer_perceptron_pointer->get_inputs_number();
00260 int outputs_number = multilayer_perceptron_pointer->get_outputs_number();
00261
00262
00263
00264 #ifdef _DEBUG
00265
00266 if(multilayer_perceptron_pointer == NULL)
00267 {
00268 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00269 << "double calculate_objective(void) method." << std::endl
00270 << "Pointer to multilayer perceptron object cannot be NULL." << std::endl;
00271
00272 exit(1);
00273 }
00274 else if(input_target_data_set_pointer == NULL)
00275 {
00276 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00277 << "double calculate_objective(void) method." << std::endl
00278 << "Pointer to input-target data set object cannot be NULL." << std::endl;
00279
00280 exit(1);
00281 }
00282
00283 int input_variables_number = input_target_data_set_pointer->get_input_variables_number();
00284 int target_variables_number = input_target_data_set_pointer->get_target_variables_number();
00285
00286 if(inputs_number != input_variables_number || outputs_number != target_variables_number)
00287 {
00288 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00289 << "double calculate_objective(void) method." << std::endl
00290 << "Number of inputs and outputs in multilayer perceptron must be equal to number of input and output variables in input-target data set." << std::endl;
00291
00292 exit(1);
00293 }
00294
00295 #endif
00296
00297 int training_instances_number = input_target_data_set_pointer->get_training_instances_number();
00298
00299 double training_normalization_coefficient = calculate_training_normalization_coefficient();
00300
00301 #ifdef _DEBUG
00302
00303 if(training_normalization_coefficient < 1.0e-99)
00304 {
00305 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00306 << "double calculate_objective(void) method." << std::endl
00307 << "Training normalization coefficient is zero." << std::endl;
00308
00309 exit(1);
00310 }
00311
00312 #endif
00313
00314 Vector<double> input(inputs_number);
00315 Vector<double> output(outputs_number);
00316 Vector<double> target(outputs_number);
00317 Vector<double> instance_error(outputs_number);
00318
00319 double sum_squared_error = 0.0;
00320
00321 for(int i = 0; i < training_instances_number; i++)
00322 {
00323
00324
00325 input = input_target_data_set_pointer->get_training_input_instance(i);
00326
00327
00328
00329 output = multilayer_perceptron_pointer->calculate_output(input);
00330
00331
00332
00333 target = input_target_data_set_pointer->get_training_target_instance(i);
00334
00335
00336
00337 instance_error = output - target;
00338
00339
00340
00341 sum_squared_error += instance_error.dot(instance_error);
00342 }
00343
00344 return(sum_squared_error/training_normalization_coefficient);
00345 }
00346
00347
00348
00349
00353
00354 Vector<double> NormalizedSquaredError::calculate_output_errors
00355 (const Vector< Vector<double> >& forward_propagation_derivative, const Vector<double>& target)
00356 {
00357 int forward_propagation_derivative_size = forward_propagation_derivative.get_size();
00358 int outputs_number = multilayer_perceptron_pointer->get_outputs_number();
00359
00360
00361
00362 #ifdef _DEBUG
00363
00364 int hidden_layers_number = multilayer_perceptron_pointer->get_hidden_layers_number();
00365
00366 if(forward_propagation_derivative_size != 2*hidden_layers_number+2)
00367 {
00368 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00369 << "Vector<double> calculate_output_errors(const Vector< Vector<double> >&, const Vector<double>&) method." << std::endl
00370 << "Size of forward propagation derivative vector must be equal to 2*hidden_layers_number+2."
00371 << std::endl;
00372
00373 exit(1);
00374 }
00375
00376 int output_layer_output_size = forward_propagation_derivative[forward_propagation_derivative_size-2].get_size();
00377
00378 if(output_layer_output_size != outputs_number)
00379 {
00380 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00381 << "Vector<double> calculate_output_errors(const Vector< Vector<double> >&, const Vector<double>&) method." << std::endl
00382 << "Size of output layer output ("<< output_layer_output_size << ") must be equal to "
00383 << "number of outputs (" << outputs_number << ")." << std::endl;
00384
00385 exit(1);
00386 }
00387
00388 int output_layer_output_derivative_size
00389 = forward_propagation_derivative[forward_propagation_derivative_size-1].get_size();
00390
00391 if(output_layer_output_derivative_size != outputs_number)
00392 {
00393 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00394 << "Vector<double> calculate_output_errors(const Vector< Vector<double> >&, const Vector<double>&) method." << std::endl
00395 << "Size of output layer output derivative (" << output_layer_output_derivative_size << ")must be equal to " << "number of outputs (" << outputs_number << ")." << std::endl;
00396
00397 exit(1);
00398 }
00399
00400 int target_size = target.get_size();
00401
00402 if(target_size != outputs_number)
00403 {
00404 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00405 << "Vector<double> calculate_output_errors(const Vector< Vector<double> >&, const Vector<double>&) method." << std::endl
00406 << "Size of target must be equal to number of outputs." << std::endl;
00407
00408 exit(1);
00409 }
00410
00411 #endif
00412
00413 double training_normalization_coefficient = calculate_training_normalization_coefficient();
00414
00415 #ifdef _DEBUG
00416
00417 if(training_normalization_coefficient < 1.0e-99)
00418 {
00419 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00420 << "Vector<double> calculate_output_errors(const Vector< Vector<double> >&, const Vector<double>&) method." << std::endl
00421 << "Normalization coefficient is zero." << std::endl;
00422
00423 exit(1);
00424 }
00425
00426 #endif
00427
00428 Vector<double> output_layer_output_derivative = forward_propagation_derivative[forward_propagation_derivative_size-1];
00429 Vector<double> output_layer_output = forward_propagation_derivative[forward_propagation_derivative_size-2];
00430
00431 Vector<double> output_errors(outputs_number);
00432
00433 Vector<double> error(outputs_number);
00434
00435 MultilayerPerceptron::ScalingMethod outputs_unscaling_method
00436 = multilayer_perceptron_pointer->get_outputs_unscaling_method();
00437
00438 switch(outputs_unscaling_method)
00439 {
00440 case MultilayerPerceptron::None:
00441 {
00442 error = output_layer_output-target;
00443
00444 output_errors = output_layer_output_derivative*error*2.0/training_normalization_coefficient;
00445 }
00446 break;
00447
00448 case MultilayerPerceptron::MeanStandardDeviation:
00449 {
00450 Vector<double>& output_variables_standard_deviation
00451 = multilayer_perceptron_pointer->get_output_variables_standard_deviation();
00452
00453
00454
00455 #ifdef _DEBUG
00456
00457 int output_variables_standard_deviation_size = output_variables_standard_deviation.get_size();
00458
00459 if(output_variables_standard_deviation_size != outputs_number)
00460 {
00461 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00462 << "Vector<double> calculate_output_errors(const Vector< Vector<double> >&, const Vector<double>&) method." << std::endl
00463 << "Size of output variables standard deviation must be equal to number of outputs." << std::endl;
00464
00465 exit(1);
00466 }
00467
00468 #endif
00469
00470 output_errors = output_layer_output_derivative*error*output_variables_standard_deviation*2.0/training_normalization_coefficient;
00471 }
00472 break;
00473
00474 case MultilayerPerceptron::MinimumMaximum:
00475 {
00476 Vector<double>& output_variables_minimum = multilayer_perceptron_pointer->get_output_variables_minimum();
00477 Vector<double>& output_variables_maximum = multilayer_perceptron_pointer->get_output_variables_maximum();
00478
00479
00480
00481 #ifdef _DEBUG
00482
00483 int output_variables_minimum_size = output_variables_minimum.get_size();
00484 int output_variables_maximum_size = output_variables_maximum.get_size();
00485
00486 if(output_variables_minimum_size != outputs_number)
00487 {
00488 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00489 << "Vector<double> calculate_output_errors(const Vector< Vector<double> >&, const Vector<double>&) method." << std::endl
00490 << "Size of output variables minimum must be equal to number of outputs." << std::endl;
00491
00492 exit(1);
00493 }
00494 else if(output_variables_maximum_size != outputs_number)
00495 {
00496 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00497 << "Vector<double> calculate_output_errors(const Vector< Vector<double> >&, const Vector<double>&) method." << std::endl
00498 << "Size of output variables maximum must be equal to number of outputs." << std::endl;
00499
00500 exit(1);
00501 }
00502
00503 #endif
00504
00505 output_errors = output_layer_output_derivative*error*(output_variables_maximum-output_variables_minimum)/training_normalization_coefficient;
00506 }
00507 break;
00508
00509 default:
00510 {
00511 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00512 << "Vector<double> calculate_output_errors(const Vector< Vector<double> >&, const Vector<double>&) method." << std::endl
00513 << "Unknown outputs unscaling method." << std::endl;
00514
00515 exit(1);
00516 }
00517 break;
00518
00519 }
00520
00521 return(output_errors);
00522 }
00523
00524
00525
00526
00530
00531 Vector< Vector<double> > NormalizedSquaredError::calculate_hidden_errors
00532 (const Vector< Vector<double> >& forward_propagation_derivative, const Vector<double>& output_errors)
00533 {
00534 int outputs_number = multilayer_perceptron_pointer->get_outputs_number();
00535
00536 int hidden_layers_number = multilayer_perceptron_pointer->get_hidden_layers_number();
00537
00538
00539
00540 #ifdef _DEBUG
00541
00542 int forward_propagation_derivative_size = forward_propagation_derivative.get_size();
00543
00544 if(forward_propagation_derivative_size != 2*hidden_layers_number+2)
00545 {
00546 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00547 << "Vector< Vector<double> > calculate_hidden_errors(const Vector< Vector<double> >&, const Vector<double>&) method." << std::endl
00548 << "Size of forward propagation derivative vector must be equal to 2*hidden_layers_number+2."
00549 << std::endl;
00550
00551 exit(1);
00552 }
00553
00554 int output_layer_output_size = forward_propagation_derivative[forward_propagation_derivative_size-2].get_size();
00555
00556 if(output_layer_output_size != outputs_number)
00557 {
00558 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00559 << "Vector< Vector<double> > calculate_hidden_errors(const Vector< Vector<double> >&, const Vector<double>&) method." << std::endl
00560 << "Size of output layer output ("<< output_layer_output_size << ") must be equal to "
00561 << "number of outputs (" << outputs_number << ")." << std::endl;
00562
00563 exit(1);
00564 }
00565
00566 int output_layer_output_derivative_size
00567 = forward_propagation_derivative[forward_propagation_derivative_size-1].get_size();
00568
00569 if(output_layer_output_derivative_size != outputs_number)
00570 {
00571 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00572 << "Vector< Vector<double> > calculate_hidden_errors(const Vector< Vector<double> >&, const Vector<double>&) method." << std::endl
00573 << "Size of output layer output derivative (" << output_layer_output_derivative_size << ")must be equal to "
00574 << "number of outputs (" << outputs_number << ")." << std::endl;
00575
00576 exit(1);
00577 }
00578
00579 int output_errors_size = output_errors.get_size();
00580
00581 if(output_errors_size != outputs_number)
00582 {
00583 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00584 << "Vector< Vector<double> > calculate_hidden_errors(const Vector< Vector<double> >&, const Vector<double>&) method." << std::endl
00585 << "Size of target must be equal to number of outputs." << std::endl;
00586
00587 exit(1);
00588 }
00589
00590 #endif
00591
00592
00593
00594 Vector<int> hidden_layers_size = multilayer_perceptron_pointer->get_hidden_layers_size();
00595
00596 Vector< Vector<double> > hidden_errors(hidden_layers_number);
00597
00598 for(int h = 0; h < hidden_layers_number; h++)
00599 {
00600 hidden_errors[h].set_size(hidden_layers_size[h]);
00601 }
00602
00603
00604
00605 Vector<Perceptron>& output_layer = multilayer_perceptron_pointer->get_output_layer();
00606 Vector< Vector<Perceptron> >& hidden_layers = multilayer_perceptron_pointer->get_hidden_layers();
00607
00608 Vector< Vector<double> > hidden_layers_output_derivative(hidden_layers_number);
00609
00610 for(int i = 0; i < hidden_layers_number; i++)
00611 {
00612 hidden_layers_output_derivative[i] = forward_propagation_derivative[1+2*i];
00613 }
00614
00615 Vector<double> synaptic_weights;
00616
00617 double sum;
00618
00619
00620
00621 for(int j = 0; j < hidden_layers_size[hidden_layers_number-1]; j++)
00622 {
00623 sum = 0.0;
00624
00625 for(int k = 0; k < outputs_number; k++)
00626 {
00627 synaptic_weights = output_layer[k].get_synaptic_weights();
00628
00629 sum += (synaptic_weights[j])*output_errors[k];
00630 }
00631
00632 hidden_errors[hidden_layers_number-1][j] = hidden_layers_output_derivative[hidden_layers_number-1][j]*sum;
00633 }
00634
00635
00636
00637 for(int h = hidden_layers_number-2; h >= 0; h--)
00638 {
00639 for(int j = 0; j < hidden_layers_size[h]; j++)
00640 {
00641 sum = 0.0;
00642
00643 for(int k = 0; k < hidden_layers_size[h+1]; k++)
00644 {
00645 synaptic_weights = hidden_layers[h+1][k].get_synaptic_weights();
00646
00647 sum += (synaptic_weights[j])*hidden_errors[h+1][k];
00648 }
00649
00650 hidden_errors[h][j] = hidden_layers_output_derivative[h][j]*sum;
00651 }
00652 }
00653
00654 return(hidden_errors);
00655 }
00656
00657
00658
00659
00664
00665 Vector<double> NormalizedSquaredError::calculate_hidden_layers_error_gradient
00666 (const Vector<double>& input,
00667 const Vector< Vector<double> >& forward_propagation_derivative,
00668 const Vector< Vector<double> >& hidden_errors)
00669 {
00670 int inputs_number = multilayer_perceptron_pointer->get_inputs_number();
00671 int hidden_layers_number = multilayer_perceptron_pointer->get_hidden_layers_number();
00672
00673
00674
00675 #ifdef _DEBUG
00676
00677 int input_size = input.get_size();
00678
00679 if(input_size != inputs_number)
00680 {
00681 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00682 << "Vector< Vector<double> > calculate_hidden_layers_error_gradient(const Vector< Vector<double> >&, const Vector<double>&, const Vector<double>&) method." << std::endl
00683 << "Size of input (" << input_size << ") must be equal to inputs number (" << inputs_number << ")."
00684 << std::endl;
00685
00686 exit(1);
00687 }
00688
00689
00690 int forward_propagation_derivative_size = forward_propagation_derivative.get_size();
00691
00692 if(forward_propagation_derivative_size != 2*hidden_layers_number+2)
00693 {
00694 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00695 << "Vector< Vector<double> > calculate_hidden_layers_error_gradient(const Vector< Vector<double> >&, const Vector<double>&, const Vector<double>&) method." << std::endl
00696 << "Size of forward propagation derivative (" << forward_propagation_derivative_size << ") must be equal to 2*hidden_layers_number+2 (" << 2*hidden_layers_number+2 << ")."
00697 << std::endl;
00698
00699 exit(1);
00700 }
00701
00702 int hidden_errors_size = hidden_errors.get_size();
00703
00704 if(hidden_errors_size != hidden_layers_number)
00705 {
00706 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00707 << "Vector< Vector<double> > calculate_hidden_layers_error_gradient(const Vector< Vector<double> >&, const Vector<double>&) method." << std::endl
00708 << "Size of output errors ("<< hidden_errors_size << ") must be equal to number of hidden layers (" << hidden_layers_number << ")." << std::endl;
00709
00710 exit(1);
00711 }
00712
00713 #endif
00714
00715
00716
00717 Vector<int> hidden_layers_size = multilayer_perceptron_pointer->get_hidden_layers_size();
00718
00719 int hidden_layers_parameters_number = multilayer_perceptron_pointer->get_hidden_layers_parameters_number();
00720
00721 Vector< Vector<Perceptron> >& hidden_layers = multilayer_perceptron_pointer->get_hidden_layers();
00722
00723 Vector<double> synaptic_weights;
00724
00725 Vector< Vector<double> > hidden_layers_output(hidden_layers_number);
00726
00727 for(int i = 0; i < hidden_layers_number; i++)
00728 {
00729 hidden_layers_output[i] = forward_propagation_derivative[2*i];
00730 }
00731
00732 int index = 0;
00733
00734 Vector<double> hidden_layers_error_gradient(hidden_layers_parameters_number, 0.0);
00735
00736
00737
00738 for(int j = 0; j < hidden_layers_size[0]; j++)
00739 {
00740
00741
00742 hidden_layers_error_gradient[index] += hidden_errors[0][j];
00743 index++;
00744
00745
00746
00747 synaptic_weights = hidden_layers[0][j].get_synaptic_weights();
00748
00749 for(int k = 0; k < inputs_number; k++)
00750 {
00751 hidden_layers_error_gradient[index] += hidden_errors[0][j]*input[k];
00752 index++;
00753 }
00754 }
00755
00756
00757
00758 for(int h = 1; h < hidden_layers_number; h++)
00759 {
00760 for(int j = 0; j < hidden_layers_size[h]; j++)
00761 {
00762
00763
00764 hidden_layers_error_gradient[index] += hidden_errors[h][j];
00765 index++;
00766
00767
00768
00769 synaptic_weights = hidden_layers[h][j].get_synaptic_weights();
00770
00771 for(int k = 0; k < hidden_layers_size[h-1]; k++)
00772 {
00773 hidden_layers_error_gradient[index] += hidden_errors[h][j]*hidden_layers_output[h-1][k];
00774 index++;
00775 }
00776 }
00777 }
00778
00779 return(hidden_layers_error_gradient);
00780 }
00781
00782
00783
00784
00788
00789 Vector<double> NormalizedSquaredError::calculate_output_layer_error_gradient
00790 (const Vector< Vector<double> >& forward_propagation_derivative, const Vector<double>& output_errors)
00791 {
00792 int outputs_number = multilayer_perceptron_pointer->get_outputs_number();
00793 int hidden_layers_number = multilayer_perceptron_pointer->get_hidden_layers_number();
00794
00795
00796
00797 #ifdef _DEBUG
00798
00799 int forward_propagation_derivative_size = forward_propagation_derivative.get_size();
00800
00801 if(forward_propagation_derivative_size != 2*hidden_layers_number+2)
00802 {
00803 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00804 << "Vector< Vector<double> > calculate_output_layer_error_gradient(const Vector< Vector<double> >&, const Vector<double>&) method." << std::endl
00805 << "Size of forward propagation derivative (" << forward_propagation_derivative_size << ") must be equal to 2*hidden_layers_number+2 (" << 2*hidden_layers_number+2 << ")."
00806 << std::endl;
00807
00808 exit(1);
00809 }
00810
00811 int output_errors_size = output_errors.get_size();
00812
00813 if(output_errors_size != outputs_number)
00814 {
00815 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00816 << "Vector< Vector<double> > calculate_output_layer_error_gradient(const Vector< Vector<double> >&, const Vector<double>&) method." << std::endl
00817 << "Size of output errors ("<< output_errors_size << ") must be equal to number of outputs (" << outputs_number << ")." << std::endl;
00818
00819 exit(1);
00820 }
00821
00822 #endif
00823
00824
00825
00826 Vector<int> hidden_layers_size = multilayer_perceptron_pointer->get_hidden_layers_size();
00827
00828 int output_layer_parameters_number = multilayer_perceptron_pointer->get_output_layer_parameters_number();
00829
00830 Vector< Vector<double> > hidden_layers_output(hidden_layers_number);
00831
00832 for(int i = 0; i < hidden_layers_number; i++)
00833 {
00834 hidden_layers_output[i] = forward_propagation_derivative[2*i];
00835 }
00836
00837
00838
00839 Vector<double> output_layer_error_gradient(output_layer_parameters_number, 0.0);
00840
00841 int index = 0;
00842
00843 for(int j = 0; j < outputs_number; j++)
00844 {
00845
00846
00847 output_layer_error_gradient[index] += output_errors[j];
00848 index++;
00849
00850
00851
00852 for(int k = 0; k < hidden_layers_size[hidden_layers_number-1]; k++)
00853 {
00854 output_layer_error_gradient[index] = hidden_layers_output[hidden_layers_number-1][k]*output_errors[j];
00855 index++;
00856 }
00857 }
00858
00859 return(output_layer_error_gradient);
00860 }
00861
00862
00863
00864
00867
00868 Vector<double> NormalizedSquaredError::calculate_objective_gradient(void)
00869 {
00870
00871
00872 #ifdef _DEBUG
00873
00874 if(multilayer_perceptron_pointer == NULL)
00875 {
00876 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00877 << "double calculate_objective_gradient(void) method." << std::endl
00878 << "Pointer to multilayer perceptron object cannot be NULL." << std::endl;
00879
00880 exit(1);
00881 }
00882 else if(input_target_data_set_pointer == NULL)
00883 {
00884 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00885 << "double calculate_objective_gradient(void) method." << std::endl
00886 << "Pointer to input-target data set object cannot be NULL." << std::endl;
00887
00888 exit(1);
00889 }
00890
00891 #endif
00892
00893
00894
00895 int hidden_layers_number = multilayer_perceptron_pointer->get_hidden_layers_number();
00896
00897 Vector<int> hidden_layers_size = multilayer_perceptron_pointer->get_hidden_layers_size();
00898
00899 int outputs_number = multilayer_perceptron_pointer->get_outputs_number();
00900
00901 int forward_propagation_derivative_size = 2*hidden_layers_number + 2;
00902
00903 Vector< Vector<double> > forward_propagation_derivative(forward_propagation_derivative_size);
00904
00905
00906
00907 int training_instances_number = input_target_data_set_pointer->get_training_instances_number();
00908
00909 int input_variables_number = input_target_data_set_pointer->get_input_variables_number();
00910 int target_variables_number = input_target_data_set_pointer->get_target_variables_number(); Vector<double> training_input_instance(input_variables_number);
00911 Vector<double> training_target_instance(target_variables_number);
00912
00913
00914
00915 Vector<double> output_errors(outputs_number);
00916 Vector< Vector<double> > hidden_errors(hidden_layers_number);
00917
00918 for(int h = 0; h < hidden_layers_number; h++)
00919 {
00920 hidden_errors[h].set_size(hidden_layers_size[h]);
00921 }
00922
00923
00924
00925 int hidden_layers_parameters_number = multilayer_perceptron_pointer->get_hidden_layers_parameters_number();
00926 int output_layer_parameters_number = multilayer_perceptron_pointer->get_output_layer_parameters_number();
00927
00928 Vector<double> hidden_layers_error_gradient(hidden_layers_parameters_number, 0.0);
00929 Vector<double> output_layer_error_gradient(output_layer_parameters_number, 0.0);
00930
00931
00932
00933 for(int i = 0; i < training_instances_number; i++)
00934 {
00935 training_input_instance = input_target_data_set_pointer->get_training_input_instance(i);
00936
00937 forward_propagation_derivative = multilayer_perceptron_pointer->calculate_forward_propagation_derivative(training_input_instance);
00938
00939 training_target_instance = input_target_data_set_pointer->get_training_target_instance(i);
00940
00941 output_errors = calculate_output_errors(forward_propagation_derivative, training_target_instance);
00942
00943 hidden_errors = calculate_hidden_errors(forward_propagation_derivative, output_errors);
00944
00945 hidden_layers_error_gradient += calculate_hidden_layers_error_gradient(training_input_instance, forward_propagation_derivative, hidden_errors);
00946
00947 output_layer_error_gradient += calculate_output_layer_error_gradient(forward_propagation_derivative, output_errors);
00948 }
00949
00950 return(hidden_layers_error_gradient.assemble(output_layer_error_gradient));
00951 }
00952
00953
00954
00955
00956
00957 double NormalizedSquaredError::calculate_validation_error(void)
00958 {
00959 int inputs_number = multilayer_perceptron_pointer->get_inputs_number();
00960 int outputs_number = multilayer_perceptron_pointer->get_outputs_number();
00961
00962
00963
00964 #ifdef _DEBUG
00965
00966 if(multilayer_perceptron_pointer == NULL)
00967 {
00968 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00969 << "double calculate_objective(void) method." << std::endl
00970 << "Pointer to multilayer perceptron object cannot be NULL." << std::endl;
00971
00972 exit(1);
00973 }
00974 else if(input_target_data_set_pointer == NULL)
00975 {
00976 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00977 << "double calculate_objective(void) method." << std::endl
00978 << "Pointer to input-target data set object cannot be NULL." << std::endl;
00979
00980 exit(1);
00981 }
00982
00983 int input_variables_number = input_target_data_set_pointer->get_input_variables_number();
00984 int target_variables_number = input_target_data_set_pointer->get_target_variables_number();
00985
00986 if(inputs_number != input_variables_number || outputs_number != target_variables_number)
00987 {
00988 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
00989 << "double calculate_objective(void) method." << std::endl
00990 << "Number of inputs and outputs in multilayer perceptron must be equal to number of input and output variables in input-target data set." << std::endl;
00991
00992 exit(1);
00993 }
00994
00995 #endif
00996
00997 int validation_instances_number = input_target_data_set_pointer->get_validation_instances_number();
00998
00999 if(validation_instances_number == 0)
01000 {
01001 return(0.0);
01002 }
01003
01004 double validation_normalization_coefficient = calculate_validation_normalization_coefficient();
01005
01006 #ifdef _DEBUG
01007
01008 if(validation_normalization_coefficient < 1.0e-99)
01009 {
01010 std::cerr << "Flood Error: NormalizedSquaredError class." << std::endl
01011 << "double calculate_objective(void) method." << std::endl
01012 << "Training normalization coefficient is zero." << std::endl;
01013
01014 exit(1);
01015 }
01016
01017 #endif
01018
01019 Vector<double> input(inputs_number);
01020 Vector<double> output(outputs_number);
01021 Vector<double> target(outputs_number);
01022 Vector<double> instance_error(outputs_number);
01023
01024 double sum_squared_error = 0.0;
01025
01026 for(int i = 0; i < validation_instances_number; i++)
01027 {
01028
01029
01030 input = input_target_data_set_pointer->get_validation_input_instance(i);
01031
01032
01033
01034 output = multilayer_perceptron_pointer->calculate_output(input);
01035
01036
01037
01038 target = input_target_data_set_pointer->get_validation_target_instance(i);
01039
01040
01041
01042 instance_error = output - target;
01043
01044
01045
01046 sum_squared_error += instance_error.dot(instance_error);
01047 }
01048
01049 return(sum_squared_error/validation_normalization_coefficient);
01050 }
01051
01052 }
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069