00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "ConjugateGradient.h"
00017
00018 #include <string>
00019 #include <sstream>
00020 #include <iostream>
00021 #include <fstream>
00022 #include <algorithm>
00023 #include <functional>
00024 #include <climits>
00025 #include <cmath>
00026 #include <ctime>
00027
00028 namespace Flood
00029 {
00030
00031
00032
00074
00075 ConjugateGradient::ConjugateGradient(ObjectiveFunctional* new_objective_functional_pointer)
00076 : TrainingAlgorithm(new_objective_functional_pointer)
00077 {
00078
00079
00080 training_direction_method = PolakRibiere;
00081 }
00082
00083
00084
00085
00125
00126 ConjugateGradient::ConjugateGradient(void) : TrainingAlgorithm()
00127 {
00128
00129
00130 training_direction_method = PolakRibiere;
00131 }
00132
00133
00134
00135
00137
00138 ConjugateGradient::~ConjugateGradient(void)
00139 {
00140 }
00141
00142
00143
00144
00145
00146
00148
00149 ConjugateGradient::TrainingDirectionMethod ConjugateGradient::get_training_direction_method(void)
00150 {
00151 return(training_direction_method);
00152 }
00153
00154
00155
00156
00158
00159 std::string ConjugateGradient::get_training_direction_method_name(void)
00160 {
00161 switch(training_direction_method)
00162 {
00163 case PolakRibiere:
00164 {
00165 return("PolakRibiere");
00166 }
00167 break;
00168
00169 case FletcherReeves:
00170 {
00171 return("FletcherReeves");
00172 }
00173 break;
00174
00175 default:
00176 {
00177 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
00178 << "std::string get_training_direction_method_name(void) method." << std::endl
00179 << "Unknown training direction method." << std::endl;
00180
00181 exit(1);
00182 }
00183 break;
00184 }
00185 }
00186
00187
00188
00189
00193
00194 void ConjugateGradient::set_training_direction_method
00195 (const ConjugateGradient::TrainingDirectionMethod& new_training_direction_method)
00196 {
00197 training_direction_method = new_training_direction_method;
00198 }
00199
00200
00201
00202
00210
00211 void ConjugateGradient::set_training_direction_method(const std::string& new_training_direction_method_name)
00212 {
00213 if(new_training_direction_method_name == "PolakRibiere")
00214 {
00215 training_direction_method = PolakRibiere;
00216 }
00217 else if(new_training_direction_method_name == "FletcherReeves")
00218 {
00219 training_direction_method = FletcherReeves;
00220 }
00221 else
00222 {
00223 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
00224 << "void set_training_direction_method(const std::string&) method." << std::endl
00225 << "Unknown training direction method: " << new_training_direction_method_name << "." <<std::endl;
00226
00227 exit(1);
00228 }
00229 }
00230
00231
00232
00233
00249
00250 void ConjugateGradient::set_reserve_all_training_history(bool new_reserve_all_training_history)
00251 {
00252
00253
00254 reserve_parameters_history = new_reserve_all_training_history;
00255 reserve_parameters_norm_history = new_reserve_all_training_history;
00256
00257
00258
00259 reserve_evaluation_history = new_reserve_all_training_history;
00260 reserve_gradient_history = new_reserve_all_training_history;
00261 reserve_gradient_norm_history = new_reserve_all_training_history;
00262
00263 reserve_validation_error_history = new_reserve_all_training_history;
00264
00265
00266
00267 reserve_training_direction_history = new_reserve_all_training_history;
00268 reserve_training_rate_history = new_reserve_all_training_history;
00269 reserve_elapsed_time_history = new_reserve_all_training_history;
00270 }
00271
00272
00273
00274
00279
00280 double ConjugateGradient
00281 ::calculate_Fletcher_Reeves_parameter(const Vector<double>& old_gradient, const Vector<double>& gradient)
00282 {
00283 double FletcherReevesParameter = 0.0;
00284
00285 double numerator = gradient.dot(gradient);
00286 double denominator = old_gradient.dot(old_gradient);
00287
00288
00289
00290 if(denominator == 0.0)
00291 {
00292 FletcherReevesParameter = 0.0;
00293 }
00294 else
00295 {
00296 FletcherReevesParameter = numerator/denominator;
00297 }
00298
00299
00300
00301 if(FletcherReevesParameter < 0.0)
00302 FletcherReevesParameter = 0.0;
00303
00304 if(FletcherReevesParameter > 1.0)
00305 FletcherReevesParameter = 1.0;
00306
00307 return(FletcherReevesParameter);
00308 }
00309
00310
00311
00312
00317
00318 double ConjugateGradient
00319 ::calculate_Polak_Ribiere_parameter(const Vector<double>& old_gradient, const Vector<double>& gradient)
00320 {
00321 double Polak_Ribiere_parameter = 0.0;
00322
00323 double numerator = (gradient-old_gradient).dot(gradient);
00324 double denominator = old_gradient.dot(old_gradient);
00325
00326
00327
00328 if(denominator == 0.0)
00329 {
00330 Polak_Ribiere_parameter = 0.0;
00331 }
00332 else
00333 {
00334 Polak_Ribiere_parameter = numerator/denominator;
00335 }
00336
00337
00338
00339 if(Polak_Ribiere_parameter < 0.0)
00340 Polak_Ribiere_parameter = 0.0;
00341
00342 if(Polak_Ribiere_parameter > 1.0)
00343 Polak_Ribiere_parameter = 1.0;
00344
00345 return(Polak_Ribiere_parameter);
00346 }
00347
00348
00349
00350
00356
00357 Vector<double> ConjugateGradient::calculate_Polak_Ribiere_training_direction
00358 (const Vector<double>& old_gradient, const Vector<double>& gradient, const Vector<double>& old_training_direction)
00359 {
00360 double Polak_Ribiere_parameter = calculate_Polak_Ribiere_parameter(old_gradient, gradient);
00361
00362 Vector<double> gradient_descent_term = calculate_gradient_descent_training_direction(gradient);
00363 Vector<double> conjugate_direction_term = old_training_direction*Polak_Ribiere_parameter;
00364
00365 Vector<double> Polak_Ribiere_training_direction = gradient_descent_term + conjugate_direction_term;
00366
00367 double Polak_Ribiere_training_direction_norm = Polak_Ribiere_training_direction.calculate_norm();
00368
00369 return(Polak_Ribiere_training_direction/Polak_Ribiere_training_direction_norm);
00370 }
00371
00372
00373
00374
00380
00381 Vector<double> ConjugateGradient::calculate_Fletcher_Reeves_training_direction
00382 (const Vector<double>& old_gradient, const Vector<double>& gradient, const Vector<double>& old_training_direction)
00383 {
00384 double FletcherReevesParameter = calculate_Fletcher_Reeves_parameter(old_gradient, gradient);
00385
00386 Vector<double> gradient_descent_term = calculate_gradient_descent_training_direction(gradient);
00387 Vector<double> conjugate_direction_term = old_training_direction*FletcherReevesParameter;
00388
00389 Vector<double> Fletcher_Reeves_training_direction = gradient_descent_term + conjugate_direction_term;
00390
00391 double Fletcher_Reeves_training_direction_norm = Fletcher_Reeves_training_direction.calculate_norm();
00392
00393 return(Fletcher_Reeves_training_direction/Fletcher_Reeves_training_direction_norm);
00394 }
00395
00396
00397
00398
00399 Vector<double> ConjugateGradient::calculate_training_direction
00400 (const Vector<double>& old_gradient, const Vector<double>& gradient, const Vector<double>& old_training_direction)
00401 {
00402 switch(training_direction_method)
00403 {
00404 case FletcherReeves:
00405 {
00406 return(calculate_Fletcher_Reeves_training_direction(old_gradient, gradient, old_training_direction));
00407 }
00408 break;
00409
00410 case PolakRibiere:
00411 {
00412 return(calculate_Polak_Ribiere_training_direction(old_gradient, gradient, old_training_direction));
00413 }
00414 break;
00415
00416 default:
00417 {
00418 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
00419 << "Vector<double> calculate_training_direction(const Vector<double>&, const Vector<double>&, const Vector<double>&) method." << std::endl
00420 << "Unknown training direction method: " << training_direction_method << "." <<std::endl;
00421
00422 exit(1);
00423 }
00424 break;
00425 }
00426 }
00427
00428
00429
00430
00431 Vector<double> ConjugateGradient::calculate_gradient_descent_training_direction(const Vector<double>& gradient)
00432 {
00433 double gradient_norm = gradient.calculate_norm();
00434
00435 return(gradient*(-1.0)/gradient_norm);
00436 }
00437
00438
00439
00440
00443
00444 void ConjugateGradient::train(void)
00445 {
00446
00447
00448 #ifdef _DEBUG
00449
00450 if(objective_functional_pointer == NULL)
00451 {
00452 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
00453 << "void train(void) method." << std::endl
00454 << "Pointer to objective functional object cannot be NULL." << std::endl;
00455
00456 exit(1);
00457 }
00458
00459 #endif
00460
00461
00462
00463 if(display)
00464 {
00465 std::cout << "Training with conjugate gradient..." << std::endl;
00466 }
00467
00468
00469
00470 time_t beginning_time, current_time;
00471 time(&beginning_time);
00472 double elapsed_time;
00473
00474
00475
00476 MultilayerPerceptron* multilayer_perceptron_pointer = objective_functional_pointer->get_multilayer_perceptron_pointer();
00477
00478 int parameters_number = multilayer_perceptron_pointer->get_parameters_number();
00479
00480 Vector<double> parameters = multilayer_perceptron_pointer->get_parameters();
00481 double parameters_norm;
00482
00483 Vector<double> parameters_increment(parameters_number);
00484 double parameters_increment_norm;
00485
00486
00487
00488 double validation_error = 0.0;
00489 double old_validation_error = 0.0;
00490 double validation_error_increment = 0.0;
00491
00492 double evaluation = 0.0;
00493 double old_evaluation = 0.0;
00494 double evaluation_improvement = 0.0;
00495
00496 Vector<double> gradient(parameters_number);
00497 double gradient_norm;
00498
00499
00500
00501 Vector<double> old_gradient(parameters_number);
00502 Vector<double> training_direction(parameters_number);
00503 Vector<double> old_training_direction(parameters_number);
00504
00505 double training_slope;
00506
00507 double initial_training_rate = 0.0;
00508 double training_rate = 0.0;
00509 double old_training_rate = 0.0;
00510
00511 Vector<double> training_rate_evaluation(2);
00512
00513 bool stop_training = false;
00514
00515 resize_training_history(maximum_epochs_number+1);
00516
00517
00518
00519 for(int epoch = 0; epoch <= maximum_epochs_number; epoch++)
00520 {
00521
00522
00523 parameters = multilayer_perceptron_pointer->get_parameters();
00524
00525 parameters_norm = parameters.calculate_norm();
00526
00527 if(parameters_norm >= error_parameters_norm)
00528 {
00529 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
00530 << "void train(void) method." << std::endl
00531 << "Parameters norm is greater than error parameters norm." << std::endl;
00532
00533 exit(1);
00534 }
00535 else if(display && parameters_norm >= warning_parameters_norm)
00536 {
00537 std::cout << "Flood Warning: Parameters norm is " << parameters_norm << "." << std::endl;
00538 }
00539
00540
00541
00542 if(epoch == 0)
00543 {
00544 evaluation = objective_functional_pointer->calculate_evaluation();
00545 evaluation_improvement = 0.0;
00546 }
00547 else
00548 {
00549 evaluation = training_rate_evaluation[1];
00550 evaluation_improvement = old_evaluation - evaluation;
00551 }
00552
00553 validation_error = objective_functional_pointer->calculate_validation_error();
00554
00555 if(epoch == 0)
00556 {
00557 validation_error_increment = 0.0;
00558 }
00559 else
00560 {
00561 validation_error_increment = validation_error - old_validation_error;
00562 }
00563
00564 gradient = objective_functional_pointer->calculate_gradient();
00565
00566 gradient_norm = gradient.calculate_norm();
00567
00568 if(display && gradient_norm >= warning_gradient_norm)
00569 {
00570 std::cout << "Flood Warning: Gradient norm is " << gradient_norm << "." << std::endl;
00571 }
00572
00573
00574
00575 if(epoch == 0 || epoch % parameters_number == 0)
00576 {
00577
00578
00579 training_direction = calculate_gradient_descent_training_direction(gradient);
00580 }
00581 else if(fabs(old_gradient.dot(gradient)) >= 0.2*gradient.dot(gradient))
00582 {
00583
00584
00585 training_direction = calculate_gradient_descent_training_direction(gradient);
00586 }
00587 else
00588 {
00589
00590
00591 training_direction = calculate_training_direction(old_gradient, gradient, old_training_direction);
00592 }
00593
00594
00595
00596 training_slope = (gradient/gradient_norm).dot(training_direction);
00597
00598
00599
00600 if(training_slope >= 0.0)
00601 {
00602
00603
00604 training_direction = calculate_gradient_descent_training_direction(gradient);
00605 }
00606
00607
00608
00609 if(epoch == 0)
00610 {
00611 initial_training_rate = first_training_rate;
00612 }
00613 else
00614 {
00615 initial_training_rate = old_training_rate;
00616 }
00617
00618 training_rate_evaluation
00619 = calculate_training_rate_evaluation(evaluation, training_direction, initial_training_rate);
00620
00621 training_rate = training_rate_evaluation[0];
00622
00623 if(epoch != 0 && training_rate < 1.0e-99)
00624 {
00625
00626
00627 training_direction = calculate_gradient_descent_training_direction(gradient);
00628
00629 training_rate_evaluation = calculate_training_rate_evaluation(evaluation, training_direction, first_training_rate);
00630
00631 training_rate = training_rate_evaluation[0];
00632 }
00633
00634 parameters_increment = training_direction*training_rate;
00635 parameters_increment_norm = parameters_increment.calculate_norm();
00636
00637
00638
00639 time(¤t_time);
00640 elapsed_time = difftime(current_time, beginning_time);
00641
00642
00643
00644 if(reserve_parameters_history)
00645 {
00646 parameters_history[epoch] = parameters;
00647 }
00648
00649 if(reserve_parameters_norm_history)
00650 {
00651 parameters_norm_history[epoch] = parameters_norm;
00652 }
00653
00654
00655
00656 if(reserve_evaluation_history)
00657 {
00658 evaluation_history[epoch] = evaluation;
00659 }
00660
00661 if(reserve_validation_error_history)
00662 {
00663 validation_error_history[epoch] = validation_error;
00664 }
00665
00666 if(reserve_gradient_history)
00667 {
00668 gradient_history[epoch] = gradient;
00669 }
00670
00671 if(reserve_gradient_norm_history)
00672 {
00673 gradient_norm_history[epoch] = gradient_norm;
00674 }
00675
00676
00677
00678 if(reserve_training_direction_history)
00679 {
00680 training_direction_history[epoch] = training_direction;
00681 }
00682
00683 if(reserve_training_rate_history)
00684 {
00685 training_rate_history[epoch] = training_rate;
00686 }
00687
00688 if(reserve_elapsed_time_history)
00689 {
00690 elapsed_time_history[epoch] = elapsed_time;
00691 }
00692
00693
00694
00695 if(parameters_increment_norm <= minimum_parameters_increment_norm)
00696 {
00697 if(display)
00698 {
00699 std::cout << "Epoch " << epoch << ": Minimum parameters increment norm reached." << std::endl;
00700 std::cout << "Parameters increment norm: " << parameters_increment_norm << std::endl;
00701 }
00702
00703 stop_training = true;
00704 }
00705
00706 else if(epoch != 0 && evaluation_improvement <= minimum_evaluation_improvement)
00707 {
00708 if(display)
00709 {
00710 std::cout << "Epoch " << epoch << ": Minimum evaluation improvement reached." << std::endl;
00711 std::cout << "Evaluation improvement: " << evaluation_improvement << std::endl;
00712 }
00713
00714 stop_training = true;
00715 }
00716
00717 else if(evaluation <= evaluation_goal)
00718 {
00719 if(display)
00720 {
00721 std::cout << "Epoch " << epoch << ": Evaluation goal reached." << std::endl;
00722 }
00723
00724 stop_training = true;
00725 }
00726
00727 else if(early_stopping && epoch != 0 && validation_error_increment > 0.0)
00728 {
00729 if(display)
00730 {
00731 std::cout << "Epoch " << epoch << ": Validation error stopped improving." << std::endl;
00732 std::cout << "Validation error increment: " << validation_error_increment << std::endl;
00733 }
00734
00735 stop_training = true;
00736 }
00737
00738 else if(gradient_norm <= gradient_norm_goal)
00739 {
00740 if(display)
00741 {
00742 std::cout << "Epoch " << epoch << ": Gradient norm goal reached." << std::endl;
00743 }
00744
00745 stop_training = true;
00746 }
00747
00748 else if(epoch == maximum_epochs_number)
00749 {
00750 if(display)
00751 {
00752 std::cout << "Epoch " << epoch << ": Maximum number of epochs reached." << std::endl;
00753 }
00754
00755 stop_training = true;
00756 }
00757
00758 else if(elapsed_time >= maximum_time)
00759 {
00760 if(display)
00761 {
00762 std::cout << "Epoch " << epoch << ": Maximum training time reached." << std::endl;
00763 }
00764
00765 stop_training = true;
00766 }
00767
00768 if(stop_training)
00769 {
00770 if(display)
00771 {
00772 std::cout << "Parameters norm: " << parameters_norm << std::endl;
00773
00774 std::cout << "Evaluation: " << evaluation << std::endl;
00775
00776 if(validation_error != 0)
00777 {
00778 std::cout << "Validation error: " << validation_error << std::endl;
00779 }
00780
00781 std::cout << "Gradient norm: " << gradient_norm << std::endl;
00782
00783 objective_functional_pointer->print_information();
00784
00785 std::cout << "Training rate: " << training_rate << std::endl
00786 << "Elapsed time: " << elapsed_time << std::endl;
00787 }
00788
00789 resize_training_history(1+epoch);
00790
00791 break;
00792 }
00793
00794 else if(display && epoch % display_period == 0)
00795 {
00796 std::cout << "Epoch " << epoch << ";" << std::endl;
00797
00798 std::cout << "Parameters norm: " << parameters_norm << std::endl;
00799
00800 std::cout << "Evaluation: " << evaluation << std::endl;
00801
00802 if(validation_error != 0)
00803 {
00804 std::cout << "Validation error: " << validation_error << std::endl;
00805 }
00806
00807 std::cout << "Gradient norm: " << gradient_norm << std::endl;
00808
00809 objective_functional_pointer->print_information();
00810
00811 std::cout << "Training rate: " << training_rate << std::endl
00812 << "Elapsed time: " << elapsed_time << std::endl;
00813 }
00814
00815
00816
00817 parameters += parameters_increment;
00818
00819 multilayer_perceptron_pointer->set_parameters(parameters);
00820
00821
00822
00823 old_evaluation = evaluation;
00824 old_validation_error = validation_error;
00825 old_gradient = gradient;
00826
00827 old_training_direction = training_direction;
00828 old_training_rate = training_rate;
00829 }
00830 }
00831
00832
00833
00834
00839
00840 std::string ConjugateGradient::to_XML(bool show_declaration)
00841 {
00842 std::stringstream buffer;
00843
00844 if(show_declaration)
00845 {
00846 buffer << "<Flood version='3.0' class='ConjugateGradient'>" << std::endl;
00847 }
00848
00849
00850
00851 buffer << "<TrainingDirectionMethod>" << std::endl
00852 << get_training_direction_method_name() << std::endl
00853 << "</TrainingDirectionMethod>" << std::endl;
00854
00855 buffer << "<TrainingRateMethod>" << std::endl
00856 << get_training_rate_method_name() << std::endl
00857 << "</TrainingRateMethod>" << std::endl;
00858
00859
00860
00861 buffer << "<BracketingFactor> " << std::endl
00862 << bracketing_factor << std::endl
00863 << "</BracketingFactor> " << std::endl;
00864
00865 buffer << "<FirstTrainingRate> " << std::endl
00866 << first_training_rate << std::endl
00867 << "</FirstTrainingRate> " << std::endl;
00868
00869 buffer << "<TrainingRateTolerance>" << std::endl
00870 << training_rate_tolerance << std::endl
00871 << "</TrainingRateTolerance>" << std::endl;
00872
00873 buffer << "<WarningTrainingRate>" << std::endl
00874 << warning_training_rate << std::endl
00875 << "</WarningTrainingRate>" << std::endl;
00876
00877 buffer << "<ErrorTrainingRate>" << std::endl
00878 << error_training_rate << std::endl
00879 << "</ErrorTrainingRate>" << std::endl;
00880
00881
00882
00883 buffer << "<MinimumParametersIncrementNorm>" << std::endl
00884 << minimum_parameters_increment_norm << std::endl
00885 << "</MinimumParametersIncrementNorm>" << std::endl;
00886
00887 buffer << "<MinimumEvaluationImprovement>" << std::endl
00888 << minimum_evaluation_improvement << std::endl
00889 << "</MinimumEvaluationImprovement>" << std::endl;
00890
00891 buffer << "<EvaluationGoal>" << std::endl
00892 << evaluation_goal << std::endl
00893 << "</EvaluationGoal>" << std::endl;
00894
00895 buffer << "<GradientNormGoal>" << std::endl
00896 << gradient_norm_goal << std::endl
00897 << "</GradientNormGoal>" << std::endl;
00898
00899 buffer << "<MaximumEpochsNumber>" << std::endl
00900 << maximum_epochs_number << std::endl
00901 << "</MaximumEpochsNumber>" << std::endl;
00902
00903 buffer << "<MaximumTime>" << std::endl
00904 << maximum_time << std::endl
00905 << "</MaximumTime>" << std::endl;
00906
00907
00908
00909 buffer << "<ReserveParametersHistory>" << std::endl
00910 << reserve_parameters_history << std::endl
00911 << "</ReserveParametersHistory>" << std::endl;
00912
00913 buffer << "<ReserveParametersNormHistory>" << std::endl
00914 << reserve_parameters_norm_history << std::endl
00915 << "</ReserveParametersNormHistory>" << std::endl;
00916
00917 buffer << "<ReserveEvaluationHistory>" << std::endl
00918 << reserve_evaluation_history << std::endl
00919 << "</ReserveEvaluationHistory>" << std::endl;
00920
00921 buffer << "<ReserveGradientHistory>" << std::endl
00922 << reserve_gradient_history << std::endl
00923 << "</ReserveGradientHistory>" << std::endl;
00924
00925 buffer << "<ReserveGradientNormHistory>" << std::endl
00926 << reserve_gradient_norm_history << std::endl
00927 << "</ReserveGradientNormHistory>" << std::endl;
00928
00929 buffer << "<ReserveValidationErrorHistory>" << std::endl
00930 << reserve_validation_error_history << std::endl
00931 << "</ReserveValidationErrorHistory>" << std::endl;
00932
00933 buffer << "<ReserveTrainingDirectionHistory>" << std::endl
00934 << reserve_training_direction_history << std::endl
00935 << "</ReserveTrainingDirectionHistory>" << std::endl;
00936
00937 buffer << "<ReserveTrainingRateHistory>" << std::endl
00938 << reserve_training_rate_history << std::endl
00939 << "</ReserveTrainingRateHistory>" << std::endl;
00940
00941 buffer << "<ReserveElapsedTimeHistory>" << std::endl
00942 << reserve_elapsed_time_history << std::endl
00943 << "</ReserveElapsedTimeHistory>" << std::endl;
00944
00945
00946
00947 buffer << "<Display>" << std::endl
00948 << display << std::endl
00949 << "</Display>" << std::endl;
00950
00951 buffer << "<DisplayPeriod>" << std::endl
00952 << display_period << std::endl
00953 << "</DisplayPeriod>" << std::endl;
00954
00955 return(buffer.str());
00956 }
00957
00958
00959
00960
00965
00966 void ConjugateGradient::load(const char* filename)
00967 {
00968
00969
00970 std::fstream file;
00971
00972 file.open(filename, std::ios::in);
00973
00974 if(!file.is_open())
00975 {
00976 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
00977 << "void load(const char*) method." << std::endl
00978 << "Cannot open conjugate gradient XML-type file." << std::endl;
00979
00980 exit(1);
00981 }
00982
00983 std::string word;
00984 std::string line;
00985
00986
00987
00988 getline(file, line);
00989
00990 if(line != "<Flood version='3.0' class='ConjugateGradient'>")
00991 {
00992
00993
00994
00995
00996
00997 }
00998
00999 while(!file.eof())
01000 {
01001 file >> word;
01002
01003
01004
01005 if(word == "<TrainingDirectionMethod>")
01006 {
01007 std::string new_training_direction_method_name;
01008
01009 file >> new_training_direction_method_name;
01010
01011 set_training_direction_method(new_training_direction_method_name);
01012
01013 file >> word;
01014
01015 if(word != "</TrainingDirectionMethod>")
01016 {
01017 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01018 << "void load(const char*) method." << std::endl
01019 << "Unknown training direction method end tag: " << word << std::endl;
01020
01021 exit(1);
01022 }
01023 }
01024 else if(word == "<TrainingRateMethod>")
01025 {
01026 std::string new_training_rate_method;
01027
01028 file >> new_training_rate_method;
01029
01030 set_training_rate_method(new_training_rate_method);
01031
01032 file >> word;
01033
01034 if(word != "</TrainingRateMethod>")
01035 {
01036 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01037 << "void load(const char*) method." << std::endl
01038 << "Unknown training rate method end tag: " << word << std::endl;
01039
01040 exit(1);
01041 }
01042 }
01043
01044
01045
01046 else if(word == "<BracketingFactor>")
01047 {
01048 double new_backeting_factor;
01049
01050 file >> new_backeting_factor;
01051
01052 set_bracketing_factor(new_backeting_factor);
01053
01054 file >> word;
01055
01056 if(word != "</BracketingFactor>")
01057 {
01058 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01059 << "void load(const char*) method." << std::endl
01060 << "Unknown bracketing factor end tag: " << word << std::endl;
01061
01062 exit(1);
01063 }
01064 }
01065 else if(word == "<FirstTrainingRate>")
01066 {
01067 double new_first_training_rate;
01068
01069 file >> new_first_training_rate;
01070
01071 set_first_training_rate(new_first_training_rate);
01072
01073 file >> word;
01074
01075 if(word != "</FirstTrainingRate>")
01076 {
01077 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01078 << "void load(const char*) method." << std::endl
01079 << "Unknown first training rate end tag: " << word << std::endl;
01080
01081 exit(1);
01082 }
01083 }
01084 else if(word == "<TrainingRateTolerance>")
01085 {
01086 double new_training_rate_tolerance;
01087
01088 file >> new_training_rate_tolerance;
01089
01090 set_training_rate_tolerance(new_training_rate_tolerance);
01091
01092 file >> word;
01093
01094 if(word != "</TrainingRateTolerance>")
01095 {
01096 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01097 << "void load(const char*) method." << std::endl
01098 << "Unknown training rate tolerance end tag: " << word << std::endl;
01099
01100 exit(1);
01101 }
01102 }
01103 else if(word == "<WarningTrainingRate>")
01104 {
01105 double new_warning_training_rate;
01106
01107 file >> new_warning_training_rate;
01108
01109 set_warning_training_rate(new_warning_training_rate);
01110
01111 file >> word;
01112
01113 if(word != "</WarningTrainingRate>")
01114 {
01115 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01116 << "void load(const char*) method." << std::endl
01117 << "Unknown warning training rate end tag: " << word << std::endl;
01118
01119 exit(1);
01120 }
01121 }
01122 else if(word == "<ErrorTrainingRate>")
01123 {
01124 double new_error_training_rate;
01125
01126 file >> new_error_training_rate;
01127
01128 set_error_training_rate(new_error_training_rate);
01129
01130 file >> word;
01131
01132 if(word != "</ErrorTrainingRate>")
01133 {
01134 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01135 << "void load(const char*) method." << std::endl
01136 << "Unknown error training rate end tag: " << word << std::endl;
01137
01138 exit(1);
01139 }
01140 }
01141
01142
01143
01144 else if(word == "<MinimumParametersIncrementNorm>")
01145 {
01146 double new_minimum_parameters_increment_norm;
01147
01148 file >> new_minimum_parameters_increment_norm;
01149
01150 set_minimum_parameters_increment_norm(new_minimum_parameters_increment_norm);
01151
01152 file >> word;
01153
01154 if(word != "</MinimumParametersIncrementNorm>")
01155 {
01156 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01157 << "void load(const char*) method." << std::endl
01158 << "Unknown minimum parameters increment norm end tag: " << word << std::endl;
01159
01160 exit(1);
01161 }
01162 }
01163 else if(word == "<MinimumEvaluationImprovement>")
01164 {
01165 double new_minimum_evaluation_improvement;
01166
01167 file >> new_minimum_evaluation_improvement;
01168
01169 set_minimum_evaluation_improvement(new_minimum_evaluation_improvement);
01170
01171 file >> word;
01172
01173 if(word != "</MinimumEvaluationImprovement>")
01174 {
01175 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01176 << "void load(const char*) method." << std::endl
01177 << "Unknown minimum evaluation improvement end tag: " << word << std::endl;
01178
01179 exit(1);
01180 }
01181 }
01182 else if(word == "<EvaluationGoal>")
01183 {
01184 double new_evaluation_goal;
01185
01186 file >> new_evaluation_goal;
01187
01188 set_evaluation_goal(new_evaluation_goal);
01189
01190 file >> word;
01191
01192 if(word != "</EvaluationGoal>")
01193 {
01194 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01195 << "void load(const char*) method." << std::endl
01196 << "Unknown evaluation goal end tag: " << word << std::endl;
01197
01198 exit(1);
01199 }
01200 }
01201 else if(word == "<GradientNormGoal>")
01202 {
01203 double new_gradient_norm_goal;
01204
01205 file >> new_gradient_norm_goal;
01206
01207 set_gradient_norm_goal(new_gradient_norm_goal);
01208
01209 file >> word;
01210
01211 if(word != "</GradientNormGoal>")
01212 {
01213 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01214 << "void load(const char*) method." << std::endl
01215 << "Unknown gradient norm goal end tag: " << word << std::endl;
01216
01217 exit(1);
01218 }
01219 }
01220 else if(word == "<MaximumEpochsNumber>")
01221 {
01222 int new_maximum_epochs_number;
01223
01224 file >> new_maximum_epochs_number;
01225
01226 set_maximum_epochs_number(new_maximum_epochs_number);
01227
01228 file >> word;
01229
01230 if(word != "</MaximumEpochsNumber>")
01231 {
01232 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01233 << "void load(const char*) method." << std::endl
01234 << "Unknown maximum epochs number end tag: " << word << std::endl;
01235
01236 exit(1);
01237 }
01238 }
01239 else if(word == "<MaximumTime>")
01240 {
01241 double new_maximum_time;
01242
01243 file >> new_maximum_time;
01244
01245 set_maximum_time(new_maximum_time);
01246
01247 file >> word;
01248
01249 if(word != "</MaximumTime>")
01250 {
01251 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01252 << "void load(const char*) method." << std::endl
01253 << "Unknown maximum time end tag: " << word << std::endl;
01254
01255 exit(1);
01256 }
01257 }
01258 else if(word == "<EarlyStopping>")
01259 {
01260 bool new_early_stopping;
01261
01262 file >> new_early_stopping;
01263
01264 set_early_stopping(new_early_stopping);
01265
01266 file >> word;
01267
01268 if(word != "</EarlyStopping>")
01269 {
01270 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01271 << "void load(const char*) method." << std::endl
01272 << "Unknown early stopping end tag: " << word << std::endl;
01273
01274 exit(1);
01275 }
01276 }
01277
01278
01279
01280 else if(word == "<ReserveParametersHistory>")
01281 {
01282 bool new_reserve_parameters_history;
01283
01284 file >> new_reserve_parameters_history;
01285
01286 set_reserve_parameters_history(new_reserve_parameters_history);
01287
01288 file >> word;
01289
01290 if(word != "</ReserveParametersHistory>")
01291 {
01292 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01293 << "void load(const char*) method." << std::endl
01294 << "Unknown reserve parameters history end tag: " << word << std::endl;
01295
01296 exit(1);
01297 }
01298 }
01299 else if(word == "<ReserveParametersNormHistory>")
01300 {
01301 bool new_reserve_parameters_norm_history;
01302
01303 file >> new_reserve_parameters_norm_history;
01304
01305 set_reserve_parameters_norm_history(new_reserve_parameters_norm_history);
01306
01307 file >> word;
01308
01309 if(word != "</ReserveParametersNormHistory>")
01310 {
01311 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01312 << "void load(const char*) method." << std::endl
01313 << "Unknown reserve parameters norm history end tag: " << word << std::endl;
01314
01315 exit(1);
01316 }
01317 }
01318 else if(word == "<ReserveEvaluationHistory>")
01319 {
01320 bool new_reserve_evaluation_history;
01321
01322 file >> new_reserve_evaluation_history;
01323
01324 set_reserve_evaluation_history(new_reserve_evaluation_history);
01325
01326 file >> word;
01327
01328 if(word != "</ReserveEvaluationHistory>")
01329 {
01330 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01331 << "void load(const char*) method." << std::endl
01332 << "Unknown reserve evaluation history end tag: " << word << std::endl;
01333
01334 exit(1);
01335 }
01336 }
01337 else if(word == "<ReserveGradientHistory>")
01338 {
01339 bool new_reserve_gradient_history;
01340
01341 file >> new_reserve_gradient_history;
01342
01343 set_reserve_gradient_history(new_reserve_gradient_history);
01344
01345 file >> word;
01346
01347 if(word != "</ReserveGradientHistory>")
01348 {
01349 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01350 << "void load(const char*) method." << std::endl
01351 << "Unknown reserve gradient history end tag: " << word << std::endl;
01352
01353 exit(1);
01354 }
01355 }
01356 else if(word == "<ReserveGradientNormHistory>")
01357 {
01358 bool new_reserve_gradient_norm_history;
01359
01360 file >> new_reserve_gradient_norm_history;
01361
01362 set_reserve_gradient_norm_history(new_reserve_gradient_norm_history);
01363
01364 file >> word;
01365
01366 if(word != "</ReserveGradientNormHistory>")
01367 {
01368 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01369 << "void load(const char*) method." << std::endl
01370 << "Unknown reserve gradient norm history end tag: " << word << std::endl;
01371
01372 exit(1);
01373 }
01374 }
01375 else if(word == "<ReserveTrainingDirectionHistory>")
01376 {
01377 bool new_reserve_training_direction_history;
01378
01379 file >> new_reserve_training_direction_history;
01380
01381 set_reserve_training_direction_history(new_reserve_training_direction_history);
01382
01383 file >> word;
01384
01385 if(word != "</ReserveTrainingDirectionHistory>")
01386 {
01387 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01388 << "void load(const char*) method." << std::endl
01389 << "Unknown reserve training direction history end tag: " << word << std::endl;
01390
01391 exit(1);
01392 }
01393 }
01394
01395 else if(word == "<ReserveTrainingRateHistory>")
01396 {
01397 bool new_reserve_training_rate_history;
01398
01399 file >> new_reserve_training_rate_history;
01400
01401 set_reserve_training_rate_history(new_reserve_training_rate_history);
01402
01403 file >> word;
01404
01405 if(word != "</ReserveTrainingRateHistory>")
01406 {
01407 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01408 << "void load(const char*) method." << std::endl
01409 << "Unknown reserve training rate history end tag: " << word << std::endl;
01410
01411 exit(1);
01412 }
01413 }
01414 else if(word == "<ReserveElapsedTimeHistory>")
01415 {
01416 bool new_reserve_elapsed_time_history;
01417
01418 file >> new_reserve_elapsed_time_history;
01419
01420 set_reserve_elapsed_time_history(new_reserve_elapsed_time_history);
01421
01422 file >> word;
01423
01424 if(word != "</ReserveElapsedTimeHistory>")
01425 {
01426 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01427 << "void load(const char*) method." << std::endl
01428 << "Unknown reserve elapsed time history end tag: " << word << std::endl;
01429
01430 exit(1);
01431 }
01432 }
01433 else if(word == "<ReserveValidationErrorHistory>")
01434 {
01435 bool new_reserve_validation_error_history;
01436
01437 file >> new_reserve_validation_error_history;
01438
01439 set_reserve_validation_error_history(new_reserve_validation_error_history);
01440
01441 file >> word;
01442
01443 if(word != "</ReserveValidationErrorHistory>")
01444 {
01445 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01446 << "void load(const char*) method." << std::endl
01447 << "Unknown reserve validation error history end tag: " << word << std::endl;
01448
01449 exit(1);
01450 }
01451 }
01452
01453
01454
01455 else if(word == "<Display>")
01456 {
01457 bool new_display;
01458
01459 file >> new_display;
01460
01461 set_display(new_display);
01462
01463 file >> word;
01464
01465 if(word != "</Display>")
01466 {
01467 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01468 << "void load(const char*) method." << std::endl
01469 << "Unknown display end tag: " << word << std::endl;
01470
01471 exit(1);
01472 }
01473 }
01474 else if(word == "<DisplayPeriod>")
01475 {
01476 int new_display_period;
01477
01478 file >> new_display_period;
01479
01480 set_display_period(new_display_period);
01481
01482 file >> word;
01483
01484 if(word != "</DisplayPeriod>")
01485 {
01486 std::cerr << "Flood Error: ConjugateGradient class." << std::endl
01487 << "void load(const char*) method." << std::endl
01488 << "Unknown display period end tag: " << word << std::endl;
01489
01490 exit(1);
01491 }
01492 }
01493 else
01494 {
01495
01496 }
01497 }
01498
01499
01500
01501 file.close();
01502 }
01503
01504
01505
01506
01511
01512 void ConjugateGradient::resize_training_history(int new_size)
01513 {
01514
01515
01516 if(reserve_parameters_history)
01517 {
01518 parameters_history.resize(new_size);
01519 }
01520
01521 if(reserve_parameters_norm_history)
01522 {
01523 parameters_norm_history.resize(new_size);
01524 }
01525
01526
01527
01528 if(reserve_evaluation_history)
01529 {
01530 evaluation_history.resize(new_size);
01531 }
01532
01533 if(reserve_gradient_history)
01534 {
01535 gradient_history.resize(new_size);
01536 }
01537
01538 if(reserve_gradient_norm_history)
01539 {
01540 gradient_norm_history.resize(new_size);
01541 }
01542
01543 if(reserve_validation_error_history)
01544 {
01545 validation_error_history.resize(new_size);
01546 }
01547
01548
01549
01550 if(reserve_training_direction_history)
01551 {
01552 training_direction_history.resize(new_size);
01553 }
01554
01555 if(reserve_training_rate_history)
01556 {
01557 training_rate_history.resize(new_size);
01558 }
01559
01560 if(reserve_elapsed_time_history)
01561 {
01562 elapsed_time_history.resize(new_size);
01563 }
01564
01565 }
01566
01567
01568
01569
01573
01574 std::string ConjugateGradient::get_training_history_XML(bool show_declaration)
01575 {
01576 std::stringstream buffer;
01577
01578 if(show_declaration)
01579 {
01580 buffer << "<Flood version='3.0' class='ConjugateGradient' content='TrainingHistory'>" << std::endl;
01581 }
01582
01583
01584
01585 if(reserve_parameters_history)
01586 {
01587 buffer << "<ParametersHistory>" << std::endl;
01588
01589 for(int i = 0; i < parameters_history.get_size(); i++)
01590 {
01591 buffer << parameters_history[i] << std::endl;
01592 }
01593
01594 buffer << "</ParametersHistory>" << std::endl;
01595 }
01596
01597 if(reserve_parameters_norm_history)
01598 {
01599 buffer << "<ParametersNormHistory>" << std::endl
01600 << parameters_norm_history << std::endl
01601 << "</ParametersNormHistory>" << std::endl;
01602 }
01603
01604
01605
01606 if(reserve_evaluation_history)
01607 {
01608 buffer << "<EvaluationHistory>" << std::endl
01609 << evaluation_history << std::endl
01610 << "</EvaluationHistory>" << std::endl;
01611 }
01612
01613 if(reserve_gradient_history)
01614 {
01615 buffer << "<GradientHistory>" << std::endl;
01616 for(int i = 0; i < gradient_history.get_size(); i++)
01617 {
01618 buffer << gradient_history[i] << std::endl;
01619 }
01620
01621 buffer << "</GradientHistory>" << std::endl;
01622 }
01623
01624 if(reserve_gradient_norm_history)
01625 {
01626 buffer << "<GradientNormHistory>" << std::endl
01627 << gradient_norm_history << std::endl
01628 << "</GradientNormHistory>" << std::endl;
01629 }
01630
01631 if(reserve_validation_error_history)
01632 {
01633 buffer << "<ValidationErrorHistory>" << std::endl
01634 << validation_error_history << std::endl
01635 << "</ValidationErrorHistory>" << std::endl;
01636 }
01637
01638
01639
01640 if(reserve_training_direction_history)
01641 {
01642 buffer << "<TrainingDirectionHistory>" << std::endl;
01643 for(int i = 0; i < training_direction_history.get_size(); i++)
01644 {
01645 buffer << training_direction_history[i] << std::endl;
01646 }
01647
01648 buffer << "</TrainingDirectionHistory>" << std::endl;
01649 }
01650
01651 if(reserve_training_rate_history)
01652 {
01653 buffer << "<TrainingRateHistory>" << std::endl
01654 << training_rate_history << std::endl
01655 << "</TrainingRateHistory>" << std::endl;
01656 }
01657
01658 if(reserve_elapsed_time_history)
01659 {
01660 buffer << "<ElapsedTimeHistory>" << std::endl
01661 << elapsed_time_history << std::endl
01662 << "</ElapsedTimeHistory>" << std::endl;
01663 }
01664
01665 return(buffer.str());
01666 }
01667
01668 }
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685