OpenNN  2.2
Open Neural Networks Library
gradient_descent.cpp
1 /****************************************************************************************************************/
2 /* */
3 /* OpenNN: Open Neural Networks Library */
4 /* www.artelnics.com/opennn */
5 /* */
6 /* G R A D I E N T D E S C E N T C L A S S */
7 /* */
8 /* Roberto Lopez */
9 /* Artelnics - Making intelligent use of data */
11 /* */
12 /****************************************************************************************************************/
13 
14 // Open NN includes
15 
16 #include "gradient_descent.h"
17 
18 namespace OpenNN
19 {
20 
21 // DEFAULT CONSTRUCTOR
22 
26 
29 {
30  set_default();
31 }
32 
33 
34 // PERFORMANCE FUNCTIONAL CONSTRUCTOR
35 
40 
41 GradientDescent::GradientDescent(PerformanceFunctional* new_performance_functional_pointer)
42 : TrainingAlgorithm(new_performance_functional_pointer)
43 {
44  training_rate_algorithm.set_performance_functional_pointer(new_performance_functional_pointer);
45 
46  set_default();
47 }
48 
49 
50 // XML CONSTRUCTOR
51 
56 
57 GradientDescent::GradientDescent(const tinyxml2::XMLDocument& document) : TrainingAlgorithm(document)
58 {
59  set_default();
60 
61  from_XML(document);
62 }
63 
64 
65 // DESTRUCTOR
66 
68 
70 {
71 }
72 
73 
74 // METHODS
75 
76 // const TrainingRateAlgorithm& get_training_rate_algorithm(void) const method
77 
79 
81 {
83 }
84 
85 
86 // TrainingRateAlgorithm* get_training_rate_algorithm_pointer(void) method
87 
89 
91 {
92  return(&training_rate_algorithm);
93 }
94 
95 
96 // const double& get_warning_parameters_norm(void) const method
97 
100 
102 {
103  return(warning_parameters_norm);
104 }
105 
106 
107 // const double& get_warning_gradient_norm(void) const method
108 
111 
113 {
114  return(warning_gradient_norm);
115 }
116 
117 
118 // const double& get_warning_training_rate(void) const method
119 
122 
124 {
125  return(warning_training_rate);
126 }
127 
128 
129 // const double& get_error_parameters_norm(void) const method
130 
133 
135 {
136  return(error_parameters_norm);
137 }
138 
139 
140 // const double& get_error_gradient_norm(void) const method
141 
144 
146 {
147  return(error_gradient_norm);
148 }
149 
150 
151 // const double& get_error_training_rate(void) const method
152 
155 
157 {
158  return(error_training_rate);
159 }
160 
161 
162 // const double& get_minimum_parameters_increment_norm(void) const method
163 
165 
167 {
169 }
170 
171 
172 // const double& get_minimum_performance_increase(void) const method
173 
175 
177 {
179 }
180 
181 
182 // const double& get_performance_goal(void) const method
183 
186 
187 const double& GradientDescent::get_performance_goal(void) const
188 {
189  return(performance_goal);
190 }
191 
192 
193 // const double& get_gradient_norm_goal(void) const method
194 
197 
199 {
200  return(gradient_norm_goal);
201 }
202 
203 
204 // const size_t& get_maximum_generalization_performance_decreases(void) const method
205 
207 
209 {
211 }
212 
213 
214 // const size_t& get_maximum_iterations_number(void) const method
215 
217 
219 {
221 }
222 
223 
224 // const double& get_maximum_time(void) const method
225 
227 
228 const double& GradientDescent::get_maximum_time(void) const
229 {
230  return(maximum_time);
231 }
232 
233 
234 // const bool& get_reserve_parameters_history(void) const method
235 
237 
239 {
241 }
242 
243 
244 // const bool& get_reserve_parameters_norm_history(void) const method
245 
247 
249 {
251 }
252 
253 
254 // const bool& get_reserve_performance_history(void) const method
255 
257 
259 {
261 }
262 
263 
264 // const bool& get_reserve_gradient_history(void) const method
265 
267 
269 {
270  return(reserve_gradient_history);
271 }
272 
273 
274 // const bool& get_reserve_gradient_norm_history(void) const method
275 
277 
279 {
281 }
282 
283 
284 // const bool& get_reserve_training_direction_history(void) const method
285 
287 
289 {
291 }
292 
293 
294 // const bool& get_reserve_training_rate_history(void) const method
295 
297 
299 {
301 }
302 
303 
304 // const bool& get_reserve_elapsed_time_history(void) const method
305 
307 
309 {
311 }
312 
313 
314 // const bool& get_reserve_generalization_performance_history(void) const method
315 
317 
319 {
321 }
322 
323 
324 // void set_training_rate_algorithm(const TrainingRateAlgorithm&) method
325 
328 
330 {
331  training_rate_algorithm = new_training_rate_algorithm;
332 }
333 
334 
335 // void set_performance_functional_pointer(PerformanceFunctional*) method
336 
340 
342 {
343  performance_functional_pointer = new_performance_functional_pointer;
344 
345  training_rate_algorithm.set_performance_functional_pointer(new_performance_functional_pointer);
346 }
347 
348 
349 // void set_default(void) method
350 
352 {
353  // TRAINING PARAMETERS
354 
355  warning_parameters_norm = 1.0e6;
356  warning_gradient_norm = 1.0e6;
357  warning_training_rate = 1.0e6;
358 
359  error_parameters_norm = 1.0e9;
360  error_gradient_norm = 1.0e9;
361  error_training_rate = 1.0e9;
362 
363  // STOPPING CRITERIA
364 
366 
368  performance_goal = -1.0e99;
369  gradient_norm_goal = 0.0;
371 
373  maximum_time = 1000.0;
374 
375  // TRAINING HISTORY
376 
379 
381  reserve_gradient_history = false;
384 
388 
389  // UTILITIES
390 
391  display = true;
392  display_period = 10;
393 }
394 
395 
396 // void set_reserve_all_training_history(bool) method
397 
411 
412 void GradientDescent::set_reserve_all_training_history(const bool& new_reserve_all_training_history)
413 {
414  // Multilayer perceptron
415 
416  reserve_parameters_history = new_reserve_all_training_history;
417  reserve_parameters_norm_history = new_reserve_all_training_history;
418 
419  // Performance functional
420 
421  reserve_performance_history = new_reserve_all_training_history;
422  reserve_gradient_history = new_reserve_all_training_history;
423  reserve_gradient_norm_history = new_reserve_all_training_history;
424 
425  reserve_generalization_performance_history = new_reserve_all_training_history;
426 
427  // Training algorithm
428 
429  reserve_training_direction_history = new_reserve_all_training_history;
430  reserve_training_rate_history = new_reserve_all_training_history;
431 
432  reserve_elapsed_time_history = new_reserve_all_training_history;
433 }
434 
435 
436 // void set_warning_parameters_norm(const double&) method
437 
441 
442 void GradientDescent::set_warning_parameters_norm(const double& new_warning_parameters_norm)
443 {
444  // Control sentence (if debug)
445 
446  #ifndef NDEBUG
447 
448  if(new_warning_parameters_norm < 0.0)
449  {
450  std::ostringstream buffer;
451 
452  buffer << "OpenNN Exception: GradientDescent class.\n"
453  << "void set_warning_parameters_norm(const double&) method.\n"
454  << "Warning parameters norm must be equal or greater than 0.\n";
455 
456  throw std::logic_error(buffer.str());
457  }
458 
459  #endif
460 
461  // Set warning parameters norm
462 
463  warning_parameters_norm = new_warning_parameters_norm;
464 }
465 
466 
467 // void set_warning_gradient_norm(const double&) method
468 
472 
473 void GradientDescent::set_warning_gradient_norm(const double& new_warning_gradient_norm)
474 {
475  // Control sentence (if debug)
476 
477  #ifndef NDEBUG
478 
479  if(new_warning_gradient_norm < 0.0)
480  {
481  std::ostringstream buffer;
482 
483  buffer << "OpenNN Exception: GradientDescent class.\n"
484  << "void set_warning_gradient_norm(const double&) method.\n"
485  << "Warning gradient norm must be equal or greater than 0.\n";
486 
487  throw std::logic_error(buffer.str());
488  }
489 
490  #endif
491 
492  // Set warning gradient norm
493 
494  warning_gradient_norm = new_warning_gradient_norm;
495 }
496 
497 
498 // void set_warning_training_rate(const double&) method
499 
503 
504 void GradientDescent::set_warning_training_rate(const double& new_warning_training_rate)
505 {
506  // Control sentence (if debug)
507 
508  #ifndef NDEBUG
509 
510  if(new_warning_training_rate < 0.0)
511  {
512  std::ostringstream buffer;
513 
514  buffer << "OpenNN Exception: GradientDescent class.\n"
515  << "void set_warning_training_rate(const double&) method.\n"
516  << "Warning training rate must be equal or greater than 0.\n";
517 
518  throw std::logic_error(buffer.str());
519  }
520 
521  #endif
522 
523  warning_training_rate = new_warning_training_rate;
524 }
525 
526 
527 // void set_error_parameters_norm(const double&) method
528 
532 
533 void GradientDescent::set_error_parameters_norm(const double& new_error_parameters_norm)
534 {
535  // Control sentence (if debug)
536 
537  #ifndef NDEBUG
538 
539  if(new_error_parameters_norm < 0.0)
540  {
541  std::ostringstream buffer;
542 
543  buffer << "OpenNN Exception: GradientDescent class.\n"
544  << "void set_error_parameters_norm(const double&) method.\n"
545  << "Error parameters norm must be equal or greater than 0.\n";
546 
547  throw std::logic_error(buffer.str());
548  }
549 
550  #endif
551 
552  // Set error parameters norm
553 
554  error_parameters_norm = new_error_parameters_norm;
555 }
556 
557 
558 // void set_error_gradient_norm(const double&) method
559 
563 
564 void GradientDescent::set_error_gradient_norm(const double& new_error_gradient_norm)
565 {
566  // Control sentence (if debug)
567 
568  #ifndef NDEBUG
569 
570  if(new_error_gradient_norm < 0.0)
571  {
572  std::ostringstream buffer;
573 
574  buffer << "OpenNN Exception: GradientDescent class.\n"
575  << "void set_error_gradient_norm(const double&) method.\n"
576  << "Error gradient norm must be equal or greater than 0.\n";
577 
578  throw std::logic_error(buffer.str());
579  }
580 
581  #endif
582 
583  // Set error gradient norm
584 
585  error_gradient_norm = new_error_gradient_norm;
586 }
587 
588 
589 // void set_error_training_rate(const double&) method
590 
594 
595 void GradientDescent::set_error_training_rate(const double& new_error_training_rate)
596 {
597  // Control sentence (if debug)
598 
599  #ifndef NDEBUG
600 
601  if(new_error_training_rate < 0.0)
602  {
603  std::ostringstream buffer;
604 
605  buffer << "OpenNN Exception: GradientDescent class.\n"
606  << "void set_error_training_rate(const double&) method.\n"
607  << "Error training rate must be equal or greater than 0.\n";
608 
609  throw std::logic_error(buffer.str());
610  }
611 
612  #endif
613 
614  // Set error training rate
615 
616  error_training_rate = new_error_training_rate;
617 }
618 
619 
620 // void set_minimum_parameters_increment_norm(const double&) method
621 
624 
625 void GradientDescent::set_minimum_parameters_increment_norm(const double& new_minimum_parameters_increment_norm)
626 {
627  // Control sentence (if debug)
628 
629  #ifndef NDEBUG
630 
631  if(new_minimum_parameters_increment_norm < 0.0)
632  {
633  std::ostringstream buffer;
634 
635  buffer << "OpenNN Exception: GradientDescent class.\n"
636  << "void new_minimum_parameters_increment_norm(const double&) method.\n"
637  << "Minimum parameters increment norm must be equal or greater than 0.\n";
638 
639  throw std::logic_error(buffer.str());
640  }
641 
642  #endif
643 
644  // Set error training rate
645 
646  minimum_parameters_increment_norm = new_minimum_parameters_increment_norm;
647 }
648 
649 
650 // void set_minimum_performance_increase(const double&) method
651 
654 
655 void GradientDescent::set_minimum_performance_increase(const double& new_minimum_performance_increase)
656 {
657  // Control sentence (if debug)
658 
659  #ifndef NDEBUG
660 
661  if(new_minimum_performance_increase < 0.0)
662  {
663  std::ostringstream buffer;
664 
665  buffer << "OpenNN Exception: GradientDescent class.\n"
666  << "void set_minimum_performance_increase(const double&) method.\n"
667  << "Minimum performance improvement must be equal or greater than 0.\n";
668 
669  throw std::logic_error(buffer.str());
670  }
671 
672  #endif
673 
674  // Set minimum performance improvement
675 
676  minimum_performance_increase = new_minimum_performance_increase;
677 }
678 
679 
680 // void set_performance_goal(const double&) method
681 
685 
686 void GradientDescent::set_performance_goal(const double& new_performance_goal)
687 {
688  performance_goal = new_performance_goal;
689 }
690 
691 
692 // void set_gradient_norm_goal(const double&) method
693 
697 
698 void GradientDescent::set_gradient_norm_goal(const double& new_gradient_norm_goal)
699 {
700  // Control sentence (if debug)
701 
702  #ifndef NDEBUG
703 
704  if(new_gradient_norm_goal < 0.0)
705  {
706  std::ostringstream buffer;
707 
708  buffer << "OpenNN Exception: GradientDescent class.\n"
709  << "void set_gradient_norm_goal(const double&) method.\n"
710  << "Gradient norm goal must be equal or greater than 0.\n";
711 
712  throw std::logic_error(buffer.str());
713  }
714 
715  #endif
716 
717  // Set gradient norm goal
718 
719  gradient_norm_goal = new_gradient_norm_goal;
720 }
721 
722 
723 // void set_maximum_generalization_performance_decreases(const size_t&) method
724 
727 
728 void GradientDescent::set_maximum_generalization_performance_decreases(const size_t& new_maximum_generalization_performance_decreases)
729 {
730  maximum_generalization_performance_decreases = new_maximum_generalization_performance_decreases;
731 }
732 
733 
734 // void set_maximum_iterations_number(size_t) method
735 
738 
739 void GradientDescent::set_maximum_iterations_number(const size_t& new_maximum_iterations_number)
740 {
741  maximum_iterations_number = new_maximum_iterations_number;
742 }
743 
744 
745 // void set_maximum_time(const double&) method
746 
749 
750 void GradientDescent::set_maximum_time(const double& new_maximum_time)
751 {
752  // Control sentence (if debug)
753 
754  #ifndef NDEBUG
755 
756  if(new_maximum_time < 0.0)
757  {
758  std::ostringstream buffer;
759 
760  buffer << "OpenNN Exception: GradientDescent class.\n"
761  << "void set_maximum_time(const double&) method.\n"
762  << "Maximum time must be equal or greater than 0.\n";
763 
764  throw std::logic_error(buffer.str());
765  }
766 
767  #endif
768 
769  // Set maximum time
770 
771  maximum_time = new_maximum_time;
772 }
773 
774 
775 // void set_reserve_parameters_history(bool) method
776 
779 
780 void GradientDescent::set_reserve_parameters_history(const bool& new_reserve_parameters_history)
781 {
782  reserve_parameters_history = new_reserve_parameters_history;
783 }
784 
785 
786 // void set_reserve_parameters_norm_history(bool) method
787 
790 
791 void GradientDescent::set_reserve_parameters_norm_history(const bool& new_reserve_parameters_norm_history)
792 {
793  reserve_parameters_norm_history = new_reserve_parameters_norm_history;
794 }
795 
796 
797 // void set_reserve_performance_history(bool) method
798 
801 
802 void GradientDescent::set_reserve_performance_history(const bool& new_reserve_performance_history)
803 {
804  reserve_performance_history = new_reserve_performance_history;
805 }
806 
807 
808 // void set_reserve_gradient_history(bool) method
809 
812 
813 void GradientDescent::set_reserve_gradient_history(const bool& new_reserve_gradient_history)
814 {
815  reserve_gradient_history = new_reserve_gradient_history;
816 }
817 
818 
819 // void set_reserve_gradient_norm_history(bool) method
820 
824 
825 void GradientDescent::set_reserve_gradient_norm_history(const bool& new_reserve_gradient_norm_history)
826 {
827  reserve_gradient_norm_history = new_reserve_gradient_norm_history;
828 }
829 
830 
831 // void set_reserve_training_direction_history(bool) method
832 
836 
837 void GradientDescent::set_reserve_training_direction_history(const bool& new_reserve_training_direction_history)
838 {
839  reserve_training_direction_history = new_reserve_training_direction_history;
840 }
841 
842 
843 // void set_reserve_training_rate_history(bool) method
844 
848 
849 void GradientDescent::set_reserve_training_rate_history(const bool& new_reserve_training_rate_history)
850 {
851  reserve_training_rate_history = new_reserve_training_rate_history;
852 }
853 
854 
855 // void set_reserve_elapsed_time_history(bool) method
856 
860 
861 void GradientDescent::set_reserve_elapsed_time_history(const bool& new_reserve_elapsed_time_history)
862 {
863  reserve_elapsed_time_history = new_reserve_elapsed_time_history;
864 }
865 
866 
867 // void set_reserve_generalization_performance_history(bool) method
868 
872 
873 void GradientDescent::set_reserve_generalization_performance_history(const bool& new_reserve_generalization_performance_history)
874 {
875  reserve_generalization_performance_history = new_reserve_generalization_performance_history;
876 }
877 
878 
879 // void set_display_period(size_t) method
880 
884 
885 void GradientDescent::set_display_period(const size_t& new_display_period)
886 {
887  // Control sentence (if debug)
888 
889  #ifndef NDEBUG
890 
891  if(new_display_period <= 0)
892  {
893  std::ostringstream buffer;
894 
895  buffer << "OpenNN Exception: GradientDescent class.\n"
896  << "void set_display_period(const double&) method.\n"
897  << "First training rate must be greater than 0.\n";
898 
899  throw std::logic_error(buffer.str());
900  }
901 
902  #endif
903 
904  display_period = new_display_period;
905 }
906 
907 
908 
909 // Vector<double> calculate_training_direction(const Vector<double>&) const method
910 
914 
916 {
917  // Control sentence (if debug)
918 
919  #ifndef NDEBUG
920 
921  std::ostringstream buffer;
922 
924  {
925  buffer << "OpenNN Exception: GradientDescent class.\n"
926  << "Vector<double> calculate_training_direction(const Vector<double>&) const method.\n"
927  << "Performance functional pointer is NULL.\n";
928 
929  throw std::logic_error(buffer.str());
930  }
931 
933 
934  const size_t parameters_number = neural_network_pointer->count_parameters_number();
935 
936  const size_t gradient_size = gradient.size();
937 
938  if(gradient_size != parameters_number)
939  {
940  buffer << "OpenNN Exception: GradientDescent class.\n"
941  << "Vector<double> calculate_training_direction(const Vector<double>&) const method.\n"
942  << "Size of gradient (" << gradient_size << ") is not equal to number of parameters (" << parameters_number << ").\n";
943 
944  throw std::logic_error(buffer.str());
945  }
946 
947  #endif
948 
949  return(gradient.calculate_normalized()*(-1.0));
950 }
951 
952 
953 // std::string GradientDescentResults::to_string(void) const method
954 
956 {
957  std::ostringstream buffer;
958 
959  // Parameters history
960 
961  if(!parameters_history.empty())
962  {
963  if(!parameters_history[0].empty())
964  {
965  buffer << "% Parameters history:\n"
966  << parameters_history << "\n";
967  }
968  }
969 
970  // Parameters norm history
971 
972  if(!parameters_norm_history.empty())
973  {
974  buffer << "% Parameters norm history:\n"
975  << parameters_norm_history << "\n";
976  }
977 
978  // Performance history
979 
980  if(!performance_history.empty())
981  {
982  buffer << "% Performance history:\n"
983  << performance_history << "\n";
984  }
985 
986  // Generalization performance history
987 
989  {
990  buffer << "% Generalization performance history:\n"
992  }
993 
994  // Gradient history
995 
996  if(!gradient_history.empty())
997  {
998  if(!gradient_history[0].empty())
999  {
1000  buffer << "% Gradient history:\n"
1001  << gradient_history << "\n";
1002  }
1003  }
1004 
1005  // Gradient norm history
1006 
1007  if(!gradient_norm_history.empty())
1008  {
1009  buffer << "% Gradient norm history:\n"
1010  << gradient_norm_history << "\n";
1011  }
1012 
1013  // Training direction history
1014 
1015  if(!training_direction_history.empty())
1016  {
1017  if(!training_direction_history[0].empty())
1018  {
1019  buffer << "% Training direction history:\n"
1020  << training_direction_history << "\n";
1021  }
1022  }
1023 
1024  // Training rate history
1025 
1026  if(!training_rate_history.empty())
1027  {
1028  buffer << "% Training rate history:\n"
1029  << training_rate_history << "\n";
1030  }
1031 
1032  // Elapsed time history
1033 
1034  if(!elapsed_time_history.empty())
1035  {
1036  buffer << "% Elapsed time history:\n"
1037  << elapsed_time_history << "\n";
1038  }
1039 
1040  // Stopping criterion
1041 
1042  if(!stopping_criterion.empty())
1043  {
1044  buffer << "% Stopping criterion:\n"
1045  << stopping_criterion << "\n";
1046  }
1047 
1048  return(buffer.str());
1049 }
1050 
1051 
1052 // Matrix<std::string> write_final_results(const size_t& precision) const method
1053 
1055 {
1056  std::ostringstream buffer;
1057 
1058  Vector<std::string> names;
1059  Vector<std::string> values;
1060 
1061  // Final parameters norm
1062 
1063  names.push_back("Final parameters norm");
1064 
1065  buffer.str("");
1066  buffer << std::setprecision(precision) << final_parameters_norm;
1067 
1068  values.push_back(buffer.str());
1069 
1070  // Final performance
1071 
1072  names.push_back("Final performance");
1073 
1074  buffer.str("");
1075  buffer << std::setprecision(precision) << final_performance;
1076 
1077  values.push_back(buffer.str());
1078 
1079  // Final generalization performance
1080 
1081  const PerformanceFunctional* performance_functional_pointer = gradient_descent_pointer->get_performance_functional_pointer();
1082 
1083  if(performance_functional_pointer->has_generalization())
1084  {
1085  names.push_back("Final generalization performance");
1086 
1087  buffer.str("");
1088  buffer << std::setprecision(precision) << final_generalization_performance;
1089 
1090  values.push_back(buffer.str());
1091  }
1092 
1093  // Final gradient norm
1094 
1095  names.push_back("Final gradient norm");
1096 
1097  buffer.str("");
1098  buffer << std::setprecision(precision) << final_gradient_norm;
1099 
1100  values.push_back(buffer.str());
1101 
1102  // Final training rate
1103 
1104 // names.push_back("Final training rate");
1105 
1106 // buffer.str("");
1107 // buffer << std::setprecision(precision) << final_training_rate;
1108 
1109 // values.push_back(buffer.str());
1110 
1111  // Iterations number
1112 
1113  names.push_back("Iterations number");
1114 
1115  buffer.str("");
1116  buffer << iterations_number;
1117 
1118  values.push_back(buffer.str());
1119 
1120  // Elapsed time
1121 
1122  names.push_back("Elapsed time");
1123 
1124  buffer.str("");
1125  buffer << elapsed_time;
1126 
1127  values.push_back(buffer.str());
1128 
1129  const size_t rows_number = names.size();
1130  const size_t columns_number = 2;
1131 
1132  Matrix<std::string> final_results(rows_number, columns_number);
1133 
1134  final_results.set_column(0, names);
1135  final_results.set_column(1, values);
1136 
1137  return(final_results);
1138 }
1139 
1140 
1141 // void GradientDescentResults::resize_training_history(const size_t&) method
1142 
1145 
1147 {
1148  // Control sentence (if debug)
1149 
1150  #ifndef NDEBUG
1151 
1152  if(gradient_descent_pointer == NULL)
1153  {
1154  std::ostringstream buffer;
1155 
1156  buffer << "OpenNN Exception: GradientDescentResults structure.\n"
1157  << "void resize_training_history(const size_t&) method.\n"
1158  << "Gradient descent pointer is NULL.\n";
1159 
1160  throw std::logic_error(buffer.str());
1161  }
1162 
1163  #endif
1164 
1165  if(gradient_descent_pointer->get_reserve_parameters_history())
1166  {
1167  parameters_history.resize(new_size);
1168  }
1169 
1170  if(gradient_descent_pointer->get_reserve_parameters_norm_history())
1171  {
1172  parameters_norm_history.resize(new_size);
1173  }
1174 
1175  if(gradient_descent_pointer->get_reserve_performance_history())
1176  {
1177  performance_history.resize(new_size);
1178  }
1179 
1180  if(gradient_descent_pointer->get_reserve_generalization_performance_history())
1181  {
1182  generalization_performance_history.resize(new_size);
1183  }
1184 
1185  if(gradient_descent_pointer->get_reserve_gradient_history())
1186  {
1187  gradient_history.resize(new_size);
1188  }
1189 
1190  if(gradient_descent_pointer->get_reserve_gradient_norm_history())
1191  {
1192  gradient_norm_history.resize(new_size);
1193  }
1194 
1195  if(gradient_descent_pointer->get_reserve_training_direction_history())
1196  {
1197  training_direction_history.resize(new_size);
1198  }
1199 
1200  if(gradient_descent_pointer->get_reserve_training_rate_history())
1201  {
1202  training_rate_history.resize(new_size);
1203  }
1204 
1205  if(gradient_descent_pointer->get_reserve_elapsed_time_history())
1206  {
1207  elapsed_time_history.resize(new_size);
1208  }
1209 }
1210 
1211 
1212 // GradientDescentResults* perform_training(void) method
1213 
1218 
1220 {
1221  GradientDescentResults* results_pointer = new GradientDescentResults(this);
1222 
1223  // Control sentence (if debug)
1224 
1225  #ifndef NDEBUG
1226 
1227  check();
1228 
1229  #endif
1230 
1231  // Start training
1232 
1233  if(display)
1234  {
1235  std::cout << "Training with gradient descent...\n";
1236  }
1237 
1238  // Neural network stuff
1239 
1241 
1242  const size_t parameters_number = neural_network_pointer->count_parameters_number();
1243 
1244  Vector<double> parameters(parameters_number);
1245  double parameters_norm;
1246 
1247  Vector<double> parameters_increment(parameters_number);
1248  double parameters_increment_norm;
1249 
1250  // Performance functional stuff
1251 
1252  double generalization_performance = 0.0;
1253  double old_generalization_performance = 0.0;
1254 
1255  double performance = 0.0;
1256  double old_performance = 0.0;
1257  double performance_increase = 0.0;
1258 
1259  Vector<double> gradient(parameters_number);
1260  double gradient_norm;
1261 
1262  PerformanceFunctional::FirstOrderperformance first_order_performance;
1263 
1264  // Training algorithm stuff
1265 
1266  size_t generalization_failures = 0;
1267 
1268  Vector<double> training_direction(parameters_number);
1269 
1270  const double first_training_rate = 0.01;
1271 
1272  double initial_training_rate = 0.0;
1273  double training_rate = 0.0;
1274  double old_training_rate = 0.0;
1275 
1276  Vector<double> directional_point(2, 0.0);
1277 
1278  bool stop_training = false;
1279 
1280  time_t beginning_time, current_time;
1281  time(&beginning_time);
1282  double elapsed_time;
1283 
1285 
1286  // Main loop
1287 
1288  for(size_t iteration = 0; iteration <= maximum_iterations_number; iteration++)
1289  {
1290  // Neural network stuff
1291 
1292  parameters = neural_network_pointer->arrange_parameters();
1293 
1294  parameters_norm = parameters.calculate_norm();
1295 
1296  if(display && parameters_norm >= warning_parameters_norm)
1297  {
1298  std::cout << "OpenNN Warning: Parameters norm is " << parameters_norm << ".\n";
1299  }
1300 
1301  // Performance functional stuff
1302 
1303  if(iteration == 0)
1304  {
1306  performance_increase = 1.0e99;
1307  }
1308  else
1309  {
1310  performance = directional_point[1];
1311  performance_increase = old_performance - performance;
1312  }
1313 
1315 
1316  gradient_norm = gradient.calculate_norm();
1317 
1318  if(display && gradient_norm >= warning_gradient_norm)
1319  {
1320  std::cout << "OpenNN Warning: Gradient norm is " << gradient_norm << ".\n";
1321  }
1322 
1324 
1325  if(iteration != 0 && generalization_performance > old_generalization_performance)
1326  {
1327  generalization_failures++;
1328  }
1329 
1330  // Training algorithm
1331 
1332  training_direction = calculate_training_direction(gradient);
1333 
1334  if(iteration == 0)
1335  {
1336  initial_training_rate = first_training_rate;//training_rate_algorithm.get_first_training_rate();
1337  }
1338  else
1339  {
1340  initial_training_rate = old_training_rate;
1341  }
1342 
1343  directional_point = training_rate_algorithm.calculate_directional_point(performance, training_direction, initial_training_rate);
1344 
1345  training_rate = directional_point[0];
1346 
1347  parameters_increment = training_direction*training_rate;
1348  parameters_increment_norm = parameters_increment.calculate_norm();
1349 
1350  // Elapsed time
1351 
1352  time(&current_time);
1353  elapsed_time = difftime(current_time, beginning_time);
1354 
1355  // Training history neural network
1356 
1358  {
1359  results_pointer->parameters_history[iteration] = parameters;
1360  }
1361 
1363  {
1364  results_pointer->parameters_norm_history[iteration] = parameters_norm;
1365  }
1366 
1367  // Training history performance functional
1368 
1370  {
1371  results_pointer->performance_history[iteration] = performance;
1372  }
1373 
1375  {
1376  results_pointer->gradient_history[iteration] = gradient;
1377  }
1378 
1380  {
1381  results_pointer->gradient_norm_history[iteration] = gradient_norm;
1382  }
1383 
1385  {
1386  results_pointer->generalization_performance_history[iteration] = generalization_performance;
1387  }
1388 
1389  // Training history training algorithm
1390 
1392  {
1393  results_pointer->training_direction_history[iteration] = training_direction;
1394  }
1395 
1397  {
1398  results_pointer->training_rate_history[iteration] = training_rate;
1399  }
1400 
1402  {
1403  results_pointer->elapsed_time_history[iteration] = elapsed_time;
1404  }
1405 
1406  // Stopping Criteria
1407 
1408  if(parameters_increment_norm <= minimum_parameters_increment_norm)
1409  {
1410  if(display)
1411  {
1412  std::cout << "Iteration " << iteration << ": Minimum parameters increment norm reached.\n";
1413  std::cout << "Parameters increment norm: " << parameters_increment_norm << std::endl;
1414  }
1415 
1416  stop_training = true;
1417  }
1418 
1419  else if(iteration != 0 && performance_increase <= minimum_performance_increase)
1420  {
1421  if(display)
1422  {
1423  std::cout << "Iteration " << iteration << ": Minimum performance increase reached.\n"
1424  << "Performance increase: " << performance_increase << std::endl;
1425  }
1426 
1427  stop_training = true;
1428  }
1429 
1430  else if(performance <= performance_goal)
1431  {
1432  if(display)
1433  {
1434  std::cout << "Iteration " << iteration << ": Performance goal reached.\n";
1435  }
1436 
1437  stop_training = true;
1438  }
1439 
1440  else if(generalization_failures >= maximum_generalization_performance_decreases)
1441  {
1442  if(display)
1443  {
1444  std::cout << "Iteration " << iteration << ": Maximum generalization failures reached.\n"
1445  << "Generalization failures: " << generalization_failures << std::endl;
1446  }
1447 
1448  stop_training = true;
1449  }
1450 
1451  else if(gradient_norm <= gradient_norm_goal)
1452  {
1453  if(display)
1454  {
1455  std::cout << "Iteration " << iteration << ": Gradient norm goal reached.\n";
1456  }
1457 
1458  stop_training = true;
1459  }
1460 
1461  else if(iteration == maximum_iterations_number)
1462  {
1463  if(display)
1464  {
1465  std::cout << "Iteration " << iteration << ": Maximum number of iterations reached.\n";
1466  }
1467 
1468  stop_training = true;
1469  }
1470 
1471  else if(elapsed_time >= maximum_time)
1472  {
1473  if(display)
1474  {
1475  std::cout << "Iteration " << iteration << ": Maximum training time reached.\n";
1476  }
1477 
1478  stop_training = true;
1479  }
1480 
1481  if(iteration != 0 && iteration % save_period == 0)
1482  {
1483  neural_network_pointer->save(neural_network_file_name);
1484  }
1485 
1486  if(stop_training)
1487  {
1488  if(display)
1489  {
1490  std::cout << "Parameters norm: " << parameters_norm << "\n"
1491  << "Performance: " << performance << "\n"
1492  << "Gradient norm: " << gradient_norm << "\n"
1494  << "Training rate: " << training_rate << "\n"
1495  << "Elapsed time: " << elapsed_time << std::endl;
1496 
1497  if(generalization_performance != 0)
1498  {
1499  std::cout << "Generalization performance: " << generalization_performance << std::endl;
1500  }
1501  }
1502 
1503  results_pointer->resize_training_history(1+iteration);
1504 
1505  results_pointer->final_parameters = parameters;
1506 
1507  results_pointer->final_parameters_norm = parameters_norm;
1508 
1509  results_pointer->final_performance = performance;
1510 
1511  results_pointer->final_generalization_performance = generalization_performance;
1512 
1513  results_pointer->final_gradient = gradient;
1514 
1515  results_pointer->final_gradient_norm = gradient_norm;
1516 
1517  results_pointer->final_training_direction = training_direction;
1518 
1519  results_pointer->final_training_rate = training_rate;
1520 
1521  results_pointer->elapsed_time = elapsed_time;
1522 
1523  results_pointer->iterations_number = iteration;
1524 
1525  break;
1526  }
1527  else if(display && iteration % display_period == 0)
1528  {
1529  std::cout << "Iteration " << iteration << ";\n"
1530  << "Parameters norm: " << parameters_norm << "\n"
1531  << "Performance: " << performance << "\n"
1532  << "Gradient norm: " << gradient_norm << "\n"
1534  << "Training rate: " << training_rate << "\n"
1535  << "Elapsed time: " << elapsed_time << std::endl;
1536 
1537  if(generalization_performance != 0)
1538  {
1539  std::cout << "Generalization performance: " << generalization_performance << std::endl;
1540  }
1541  }
1542 
1543  // Set new parameters
1544 
1545  parameters += parameters_increment;
1546 
1547  neural_network_pointer->set_parameters(parameters);
1548 
1549  // Update stuff
1550 
1551  old_performance = performance;
1552  old_generalization_performance = generalization_performance;
1553 
1554  old_training_rate = training_rate;
1555  }
1556 
1557  return(results_pointer);
1558 }
1559 
1560 
1561 // std::string write_training_algorithm_type(void) const method
1562 
1564 {
1565  return("GRADIENT_DESCENT");
1566 }
1567 
1568 
1569 // Matrix<std::string> to_string_matrix(void) const method
1570 
1571 // the most representative
1572 
1574 {
1575  std::ostringstream buffer;
1576 
1577  Vector<std::string> labels;
1578  Vector<std::string> values;
1579 
1580  // Training rate method
1581 
1582  labels.push_back("Training rate method");
1583 
1584  const std::string training_rate_method = training_rate_algorithm.write_training_rate_method();
1585 
1586  values.push_back(training_rate_method);
1587 
1588  // Training rate tolerance
1589 
1590  labels.push_back("Training rate tolerance");
1591 
1592  buffer.str("");
1594 
1595  values.push_back(buffer.str());
1596 
1597  // Minimum parameters increment norm
1598 
1599  labels.push_back("Minimum parameters increment norm");
1600 
1601  buffer.str("");
1603 
1604  values.push_back(buffer.str());
1605 
1606  // Minimum performance increase
1607 
1608  labels.push_back("Minimum performance increase");
1609 
1610  buffer.str("");
1611  buffer << minimum_performance_increase;
1612 
1613  values.push_back(buffer.str());
1614 
1615  // Performance goal
1616 
1617  labels.push_back("Performance goal");
1618 
1619  buffer.str("");
1620  buffer << performance_goal;
1621 
1622  values.push_back(buffer.str());
1623 
1624  // Gradient norm goal
1625 
1626  labels.push_back("Gradient norm goal");
1627 
1628  buffer.str("");
1629  buffer << gradient_norm_goal;
1630 
1631  values.push_back(buffer.str());
1632 
1633  // Maximum generalization failures
1634 
1635  labels.push_back("Maximum generalization failures");
1636 
1637  buffer.str("");
1639 
1640  values.push_back(buffer.str());
1641 
1642  // Maximum iterations number
1643 
1644  labels.push_back("Maximum iterations number");
1645 
1646  buffer.str("");
1647  buffer << maximum_iterations_number;
1648 
1649  values.push_back(buffer.str());
1650 
1651  // Maximum time
1652 
1653  labels.push_back("Maximum time");
1654 
1655  buffer.str("");
1656  buffer << maximum_time;
1657 
1658  values.push_back(buffer.str());
1659 
1660  // Reserve parameters norm history
1661 
1662  labels.push_back("Reserve parameters norm history");
1663 
1664  buffer.str("");
1666 
1667  values.push_back(buffer.str());
1668 
1669  // Reserve performance history
1670 
1671  labels.push_back("Reserve performance history");
1672 
1673  buffer.str("");
1674  buffer << reserve_performance_history;
1675 
1676  values.push_back(buffer.str());
1677 
1678  // Reserve gradient norm history
1679 
1680  labels.push_back("Reserve gradient norm history");
1681 
1682  buffer.str("");
1684 
1685  values.push_back(buffer.str());
1686 
1687  // Reserve generalization performance history
1688 
1689  labels.push_back("Reserve generalization performance history");
1690 
1691  buffer.str("");
1693 
1694  values.push_back(buffer.str());
1695 
1696  // Reserve training direction norm history
1697 
1698 // labels.push_back("");
1699 
1700 // buffer.str("");
1701 // buffer << reserve_training_direction_norm_history;
1702 
1703  // Reserve training rate history
1704 
1705 // labels.push_back("");
1706 
1707 // buffer.str("");
1708 // buffer << reserve_training_rate_history;
1709 
1710 // values.push_back(buffer.str());
1711 
1712  // Reserve elapsed time history
1713 
1714  labels.push_back("Reserve elapsed time history");
1715 
1716  buffer.str("");
1717  buffer << reserve_elapsed_time_history;
1718 
1719  values.push_back(buffer.str());
1720 
1721  const size_t rows_number = labels.size();
1722  const size_t columns_number = 2;
1723 
1724  Matrix<std::string> string_matrix(rows_number, columns_number);
1725 
1726  string_matrix.set_column(0, labels);
1727  string_matrix.set_column(1, values);
1728 
1729  return(string_matrix);
1730 }
1731 
1732 
1733 // tinyxml2::XMLDocument* to_XML(void) const method
1734 
1737 
1738 tinyxml2::XMLDocument* GradientDescent::to_XML(void) const
1739 {
1740  std::ostringstream buffer;
1741 
1742  tinyxml2::XMLDocument* document = new tinyxml2::XMLDocument;
1743 
1744  // Training algorithm
1745 
1746  tinyxml2::XMLElement* root_element = document->NewElement("GradientDescent");
1747 
1748  document->InsertFirstChild(root_element);
1749 
1750  tinyxml2::XMLElement* element = NULL;
1751  tinyxml2::XMLText* text = NULL;
1752 
1753  // Training rate algorithm
1754  {
1755  tinyxml2::XMLElement* element = document->NewElement("TrainingRateAlgorithm");
1756  root_element->LinkEndChild(element);
1757 
1758  const tinyxml2::XMLDocument* training_rate_algorithm_document = training_rate_algorithm.to_XML();
1759 
1760  const tinyxml2::XMLElement* training_rate_algorithm_element = training_rate_algorithm_document->FirstChildElement("TrainingRateAlgorithm");
1761 
1762  DeepClone(element, training_rate_algorithm_element, document, NULL);
1763 
1764  delete training_rate_algorithm_document;
1765  }
1766 
1767 
1768  // Warning parameters norm
1769 
1770  element = document->NewElement("WarningParametersNorm");
1771  root_element->LinkEndChild(element);
1772 
1773  buffer.str("");
1774  buffer << warning_parameters_norm;
1775 
1776  text = document->NewText(buffer.str().c_str());
1777  element->LinkEndChild(text);
1778 
1779  // Warning gradient norm
1780 
1781  element = document->NewElement("WarningGradientNorm");
1782  root_element->LinkEndChild(element);
1783 
1784  buffer.str("");
1785  buffer << warning_gradient_norm;
1786 
1787  text = document->NewText(buffer.str().c_str());
1788  element->LinkEndChild(text);
1789 
1790  // Warning training rate
1791 
1792  element = document->NewElement("WarningTrainingRate");
1793  root_element->LinkEndChild(element);
1794 
1795  buffer.str("");
1796  buffer << warning_training_rate;
1797 
1798  text = document->NewText(buffer.str().c_str());
1799  element->LinkEndChild(text);
1800 
1801  // Error parameters norm
1802 
1803  element = document->NewElement("ErrorParametersNorm");
1804  root_element->LinkEndChild(element);
1805 
1806  buffer.str("");
1807  buffer << error_parameters_norm;
1808 
1809  text = document->NewText(buffer.str().c_str());
1810  element->LinkEndChild(text);
1811 
1812  // Error gradient norm
1813 
1814  element = document->NewElement("ErrorGradientNorm");
1815  root_element->LinkEndChild(element);
1816 
1817  buffer.str("");
1818  buffer << error_gradient_norm;
1819 
1820  text = document->NewText(buffer.str().c_str());
1821  element->LinkEndChild(text);
1822 
1823  // Error training rate
1824 
1825  element = document->NewElement("ErrorTrainingRate");
1826  root_element->LinkEndChild(element);
1827 
1828  buffer.str("");
1829  buffer << error_training_rate;
1830 
1831  text = document->NewText(buffer.str().c_str());
1832  element->LinkEndChild(text);
1833 
1834  // Minimum parameters increment norm
1835 
1836  element = document->NewElement("MinimumParametersIncrementNorm");
1837  root_element->LinkEndChild(element);
1838 
1839  buffer.str("");
1841 
1842  text = document->NewText(buffer.str().c_str());
1843  element->LinkEndChild(text);
1844 
1845  // Minimum performance increase
1846 
1847  element = document->NewElement("MinimumPerformanceIncrease");
1848  root_element->LinkEndChild(element);
1849 
1850  buffer.str("");
1851  buffer << minimum_performance_increase;
1852 
1853  text = document->NewText(buffer.str().c_str());
1854  element->LinkEndChild(text);
1855 
1856  // Performance goal
1857 
1858  element = document->NewElement("PerformanceGoal");
1859  root_element->LinkEndChild(element);
1860 
1861  buffer.str("");
1862  buffer << performance_goal;
1863 
1864  text = document->NewText(buffer.str().c_str());
1865  element->LinkEndChild(text);
1866 
1867  // Gradient norm goal
1868 
1869  element = document->NewElement("GradientNormGoal");
1870  root_element->LinkEndChild(element);
1871 
1872  buffer.str("");
1873  buffer << gradient_norm_goal;
1874 
1875  text = document->NewText(buffer.str().c_str());
1876  element->LinkEndChild(text);
1877 
1878  // Maximum generalization performance decreases
1879 
1880  element = document->NewElement("MaximumGeneralizationPerformanceDecreases");
1881  root_element->LinkEndChild(element);
1882 
1883  buffer.str("");
1885 
1886  text = document->NewText(buffer.str().c_str());
1887  element->LinkEndChild(text);
1888 
1889  // Maximum iterations number
1890 
1891  element = document->NewElement("MaximumIterationsNumber");
1892  root_element->LinkEndChild(element);
1893 
1894  buffer.str("");
1895  buffer << maximum_iterations_number;
1896 
1897  text = document->NewText(buffer.str().c_str());
1898  element->LinkEndChild(text);
1899 
1900  // Maximum time
1901 
1902  element = document->NewElement("MaximumTime");
1903  root_element->LinkEndChild(element);
1904 
1905  buffer.str("");
1906  buffer << maximum_time;
1907 
1908  text = document->NewText(buffer.str().c_str());
1909  element->LinkEndChild(text);
1910 
1911  // Reserve parameters history
1912 
1913  element = document->NewElement("ReserveParametersHistory");
1914  root_element->LinkEndChild(element);
1915 
1916  buffer.str("");
1917  buffer << reserve_parameters_history;
1918 
1919  text = document->NewText(buffer.str().c_str());
1920  element->LinkEndChild(text);
1921 
1922  // Reserve parameters norm history
1923 
1924  element = document->NewElement("ReserveParametersNormHistory");
1925  root_element->LinkEndChild(element);
1926 
1927  buffer.str("");
1929 
1930  text = document->NewText(buffer.str().c_str());
1931  element->LinkEndChild(text);
1932 
1933  // Reserve performance history
1934 
1935  element = document->NewElement("ReservePerformanceHistory");
1936  root_element->LinkEndChild(element);
1937 
1938  buffer.str("");
1939  buffer << reserve_performance_history;
1940 
1941  text = document->NewText(buffer.str().c_str());
1942  element->LinkEndChild(text);
1943 
1944  // Reserve generalization performance history
1945 
1946  element = document->NewElement("ReserveGeneralizationPerformanceHistory");
1947  root_element->LinkEndChild(element);
1948 
1949  buffer.str("");
1951 
1952  text = document->NewText(buffer.str().c_str());
1953  element->LinkEndChild(text);
1954 
1955  // Reserve gradient history
1956 
1957  element = document->NewElement("ReserveGradientHistory");
1958  root_element->LinkEndChild(element);
1959 
1960  buffer.str("");
1961  buffer << reserve_gradient_history;
1962 
1963  text = document->NewText(buffer.str().c_str());
1964  element->LinkEndChild(text);
1965 
1966  // Reserve gradient norm history
1967 
1968  element = document->NewElement("ReserveGradientNormHistory");
1969  root_element->LinkEndChild(element);
1970 
1971  buffer.str("");
1973 
1974  text = document->NewText(buffer.str().c_str());
1975  element->LinkEndChild(text);
1976 
1977  // Reserve training direction history
1978 
1979  element = document->NewElement("ReserveTrainingDirectionHistory");
1980  root_element->LinkEndChild(element);
1981 
1982  buffer.str("");
1984 
1985  text = document->NewText(buffer.str().c_str());
1986  element->LinkEndChild(text);
1987 
1988  // Reserve training rate history
1989 
1990  element = document->NewElement("ReserveTrainingRateHistory");
1991  root_element->LinkEndChild(element);
1992 
1993  buffer.str("");
1995 
1996  text = document->NewText(buffer.str().c_str());
1997  element->LinkEndChild(text);
1998 
1999  // Reserve elapsed time history
2000 
2001  element = document->NewElement("ReserveElapsedTimeHistory");
2002  root_element->LinkEndChild(element);
2003 
2004  buffer.str("");
2005  buffer << reserve_elapsed_time_history;
2006 
2007  text = document->NewText(buffer.str().c_str());
2008  element->LinkEndChild(text);
2009 
2010  // Reserve generalization performance history
2011 
2012  element = document->NewElement("ReserveGeneralizationPerformanceHistory");
2013  root_element->LinkEndChild(element);
2014 
2015  buffer.str("");
2017 
2018  text = document->NewText(buffer.str().c_str());
2019  element->LinkEndChild(text);
2020 
2021  // Display period
2022 
2023  element = document->NewElement("DisplayPeriod");
2024  root_element->LinkEndChild(element);
2025 
2026  buffer.str("");
2027  buffer << display_period;
2028 
2029  text = document->NewText(buffer.str().c_str());
2030  element->LinkEndChild(text);
2031 
2032  // Save period
2033 
2034  element = document->NewElement("SavePeriod");
2035  root_element->LinkEndChild(element);
2036 
2037  buffer.str("");
2038  buffer << save_period;
2039 
2040  text = document->NewText(buffer.str().c_str());
2041  element->LinkEndChild(text);
2042 
2043  // Neural network file name
2044 
2045  element = document->NewElement("NeuralNetworkFileName");
2046  root_element->LinkEndChild(element);
2047 
2048  text = document->NewText(neural_network_file_name.c_str());
2049  element->LinkEndChild(text);
2050 
2051  // Display warnings
2052 
2053  element = document->NewElement("Display");
2054  root_element->LinkEndChild(element);
2055 
2056  buffer.str("");
2057  buffer << display;
2058 
2059  text = document->NewText(buffer.str().c_str());
2060  element->LinkEndChild(text);
2061 
2062  return(document);
2063 }
2064 
2065 
2066 // void from_XML(const tinyxml2::XMLDocument&) method
2067 
2068 void GradientDescent::from_XML(const tinyxml2::XMLDocument& document)
2069 {
2070  const tinyxml2::XMLElement* root_element = document.FirstChildElement("GradientDescent");
2071 
2072  if(!root_element)
2073  {
2074  std::ostringstream buffer;
2075 
2076  buffer << "OpenNN Exception: GradientDescent class.\n"
2077  << "void from_XML(const tinyxml2::XMLDocument&) method.\n"
2078  << "Gradient descent element is NULL.\n";
2079 
2080  throw std::logic_error(buffer.str());
2081  }
2082 
2083  // Training rate algorithm
2084  {
2085  const tinyxml2::XMLElement* training_rate_algorithm_element = root_element->FirstChildElement("TrainingRateAlgorithm");
2086 
2087  if(training_rate_algorithm_element)
2088  {
2089  tinyxml2::XMLDocument training_rate_algorithm_document;
2090 
2091  tinyxml2::XMLElement* element_clone = training_rate_algorithm_document.NewElement("TrainingRateAlgorithm");
2092  training_rate_algorithm_document.InsertFirstChild(element_clone);
2093 
2094  DeepClone(element_clone, training_rate_algorithm_element, &training_rate_algorithm_document, NULL);
2095 
2096  training_rate_algorithm.from_XML(training_rate_algorithm_document);
2097  }
2098  }
2099 
2100  // Warning parameters norm
2101  {
2102  const tinyxml2::XMLElement* element = root_element->FirstChildElement("WarningParametersNorm");
2103 
2104  if(element)
2105  {
2106  const double new_warning_parameters_norm = atof(element->GetText());
2107 
2108  try
2109  {
2110  set_warning_parameters_norm(new_warning_parameters_norm);
2111  }
2112  catch(const std::logic_error& e)
2113  {
2114  std::cout << e.what() << std::endl;
2115  }
2116  }
2117  }
2118 
2119  // Warning gradient norm
2120  {
2121  const tinyxml2::XMLElement* element = root_element->FirstChildElement("WarningGradientNorm");
2122 
2123  if(element)
2124  {
2125  const double new_warning_gradient_norm = atof(element->GetText());
2126 
2127  try
2128  {
2129  set_warning_gradient_norm(new_warning_gradient_norm);
2130  }
2131  catch(const std::logic_error& e)
2132  {
2133  std::cout << e.what() << std::endl;
2134  }
2135  }
2136  }
2137 
2138  // Warning training rate
2139  {
2140  const tinyxml2::XMLElement* element = root_element->FirstChildElement("WarningTrainingRate");
2141 
2142  if(element)
2143  {
2144  const double new_warning_training_rate = atof(element->GetText());
2145 
2146  try
2147  {
2148  set_warning_training_rate(new_warning_training_rate);
2149  }
2150  catch(const std::logic_error& e)
2151  {
2152  std::cout << e.what() << std::endl;
2153  }
2154  }
2155  }
2156 
2157  // Error parameters norm
2158  {
2159  const tinyxml2::XMLElement* element = root_element->FirstChildElement("ErrorParametersNorm");
2160 
2161  if(element)
2162  {
2163  const double new_error_parameters_norm = atof(element->GetText());
2164 
2165  try
2166  {
2167  set_error_parameters_norm(new_error_parameters_norm);
2168  }
2169  catch(const std::logic_error& e)
2170  {
2171  std::cout << e.what() << std::endl;
2172  }
2173  }
2174  }
2175 
2176  // Error gradient norm
2177  {
2178  const tinyxml2::XMLElement* element = root_element->FirstChildElement("ErrorGradientNorm");
2179 
2180  if(element)
2181  {
2182  const double new_error_gradient_norm = atof(element->GetText());
2183 
2184  try
2185  {
2186  set_error_gradient_norm(new_error_gradient_norm);
2187  }
2188  catch(const std::logic_error& e)
2189  {
2190  std::cout << e.what() << std::endl;
2191  }
2192  }
2193  }
2194 
2195  // Error training rate
2196  {
2197  const tinyxml2::XMLElement* element = root_element->FirstChildElement("ErrorTrainingRate");
2198 
2199  if(element)
2200  {
2201  const double new_error_training_rate = atof(element->GetText());
2202 
2203  try
2204  {
2205  set_error_training_rate(new_error_training_rate);
2206  }
2207  catch(const std::logic_error& e)
2208  {
2209  std::cout << e.what() << std::endl;
2210  }
2211  }
2212  }
2213 
2214  // Minimum parameters increment norm
2215  {
2216  const tinyxml2::XMLElement* element = root_element->FirstChildElement("MinimumParametersIncrementNorm");
2217 
2218  if(element)
2219  {
2220  const double new_minimum_parameters_increment_norm = atof(element->GetText());
2221 
2222  try
2223  {
2224  set_minimum_parameters_increment_norm(new_minimum_parameters_increment_norm);
2225  }
2226  catch(const std::logic_error& e)
2227  {
2228  std::cout << e.what() << std::endl;
2229  }
2230  }
2231  }
2232 
2233  // Minimum performance increase
2234  {
2235  const tinyxml2::XMLElement* element = root_element->FirstChildElement("MinimumPerformanceIncrease");
2236 
2237  if(element)
2238  {
2239  const double new_minimum_performance_increase = atof(element->GetText());
2240 
2241  try
2242  {
2243  set_minimum_performance_increase(new_minimum_performance_increase);
2244  }
2245  catch(const std::logic_error& e)
2246  {
2247  std::cout << e.what() << std::endl;
2248  }
2249  }
2250  }
2251 
2252  // Performance goal
2253  {
2254  const tinyxml2::XMLElement* element = root_element->FirstChildElement("PerformanceGoal");
2255 
2256  if(element)
2257  {
2258  const double new_performance_goal = atof(element->GetText());
2259 
2260  try
2261  {
2262  set_performance_goal(new_performance_goal);
2263  }
2264  catch(const std::logic_error& e)
2265  {
2266  std::cout << e.what() << std::endl;
2267  }
2268  }
2269  }
2270 
2271  // Gradient norm goal
2272  {
2273  const tinyxml2::XMLElement* element = root_element->FirstChildElement("GradientNormGoal");
2274 
2275  if(element)
2276  {
2277  const double new_gradient_norm_goal = atof(element->GetText());
2278 
2279  try
2280  {
2281  set_gradient_norm_goal(new_gradient_norm_goal);
2282  }
2283  catch(const std::logic_error& e)
2284  {
2285  std::cout << e.what() << std::endl;
2286  }
2287  }
2288  }
2289 
2290  // Maximum generalization performance decreases
2291  {
2292  const tinyxml2::XMLElement* element = root_element->FirstChildElement("MaximumGeneralizationPerformanceDecreases");
2293 
2294  if(element)
2295  {
2296  const size_t new_maximum_generalization_performance_decreases = atoi(element->GetText());
2297 
2298  try
2299  {
2300  set_maximum_generalization_performance_decreases(new_maximum_generalization_performance_decreases);
2301  }
2302  catch(const std::logic_error& e)
2303  {
2304  std::cout << e.what() << std::endl;
2305  }
2306  }
2307  }
2308 
2309  // Maximum iterations number
2310  {
2311  const tinyxml2::XMLElement* element = root_element->FirstChildElement("MaximumIterationsNumber");
2312 
2313  if(element)
2314  {
2315  const size_t new_maximum_iterations_number = atoi(element->GetText());
2316 
2317  try
2318  {
2319  set_maximum_iterations_number(new_maximum_iterations_number);
2320  }
2321  catch(const std::logic_error& e)
2322  {
2323  std::cout << e.what() << std::endl;
2324  }
2325  }
2326  }
2327 
2328  // Maximum time
2329  {
2330  const tinyxml2::XMLElement* element = root_element->FirstChildElement("MaximumTime");
2331 
2332  if(element)
2333  {
2334  const double new_maximum_time = atof(element->GetText());
2335 
2336  try
2337  {
2338  set_maximum_time(new_maximum_time);
2339  }
2340  catch(const std::logic_error& e)
2341  {
2342  std::cout << e.what() << std::endl;
2343  }
2344  }
2345  }
2346 
2347  // Reserve parameters history
2348  {
2349  const tinyxml2::XMLElement* element = root_element->FirstChildElement("ReserveParametersHistory");
2350 
2351  if(element)
2352  {
2353  const std::string new_reserve_parameters_history = element->GetText();
2354 
2355  try
2356  {
2357  set_reserve_parameters_history(new_reserve_parameters_history != "0");
2358  }
2359  catch(const std::logic_error& e)
2360  {
2361  std::cout << e.what() << std::endl;
2362  }
2363  }
2364  }
2365 
2366  // Reserve parameters norm history
2367  {
2368  const tinyxml2::XMLElement* element = root_element->FirstChildElement("ReserveParametersNormHistory");
2369 
2370  if(element)
2371  {
2372  const std::string new_reserve_parameters_norm_history = element->GetText();
2373 
2374  try
2375  {
2376  set_reserve_parameters_norm_history(new_reserve_parameters_norm_history != "0");
2377  }
2378  catch(const std::logic_error& e)
2379  {
2380  std::cout << e.what() << std::endl;
2381  }
2382  }
2383  }
2384 
2385  // Reserve performance history
2386  {
2387  const tinyxml2::XMLElement* element = root_element->FirstChildElement("ReservePerformanceHistory");
2388 
2389  if(element)
2390  {
2391  const std::string new_reserve_performance_history = element->GetText();
2392 
2393  try
2394  {
2395  set_reserve_performance_history(new_reserve_performance_history != "0");
2396  }
2397  catch(const std::logic_error& e)
2398  {
2399  std::cout << e.what() << std::endl;
2400  }
2401  }
2402  }
2403 
2404  // Reserve generalization performance history
2405  {
2406  const tinyxml2::XMLElement* element = root_element->FirstChildElement("ReserveGeneralizationPerformanceHistory");
2407 
2408  if(element)
2409  {
2410  const std::string new_reserve_generalization_performance_history = element->GetText();
2411 
2412  try
2413  {
2414  set_reserve_generalization_performance_history(new_reserve_generalization_performance_history != "0");
2415  }
2416  catch(const std::logic_error& e)
2417  {
2418  std::cout << e.what() << std::endl;
2419  }
2420  }
2421  }
2422 
2423  // Reserve gradient history
2424  {
2425  const tinyxml2::XMLElement* element = root_element->FirstChildElement("ReserveGradientHistory");
2426 
2427  if(element)
2428  {
2429  const std::string new_reserve_gradient_history = element->GetText();
2430 
2431  try
2432  {
2433  set_reserve_gradient_history(new_reserve_gradient_history != "0");
2434  }
2435  catch(const std::logic_error& e)
2436  {
2437  std::cout << e.what() << std::endl;
2438  }
2439  }
2440  }
2441 
2442  // Reserve gradient norm history
2443  {
2444  const tinyxml2::XMLElement* element = root_element->FirstChildElement("ReserveGradientNormHistory");
2445 
2446  if(element)
2447  {
2448  const std::string new_reserve_gradient_norm_history = element->GetText();
2449 
2450  try
2451  {
2452  set_reserve_gradient_norm_history(new_reserve_gradient_norm_history != "0");
2453  }
2454  catch(const std::logic_error& e)
2455  {
2456  std::cout << e.what() << std::endl;
2457  }
2458  }
2459  }
2460 
2461  // Reserve training direction history
2462  {
2463  const tinyxml2::XMLElement* element = root_element->FirstChildElement("ReserveTrainingDirectionHistory");
2464 
2465  if(element)
2466  {
2467  const std::string new_reserve_training_direction_history = element->GetText();
2468 
2469  try
2470  {
2471  set_reserve_training_direction_history(new_reserve_training_direction_history != "0");
2472  }
2473  catch(const std::logic_error& e)
2474  {
2475  std::cout << e.what() << std::endl;
2476  }
2477  }
2478  }
2479 
2480  // Reserve training rate history
2481  {
2482  const tinyxml2::XMLElement* element = root_element->FirstChildElement("ReserveTrainingRateHistory");
2483 
2484  if(element)
2485  {
2486  const std::string new_reserve_training_rate_history = element->GetText();
2487 
2488  try
2489  {
2490  set_reserve_training_rate_history(new_reserve_training_rate_history != "0");
2491  }
2492  catch(const std::logic_error& e)
2493  {
2494  std::cout << e.what() << std::endl;
2495  }
2496  }
2497  }
2498 
2499  // Reserve elapsed time history
2500  {
2501  const tinyxml2::XMLElement* element = root_element->FirstChildElement("ReserveElapsedTimeHistory");
2502 
2503  if(element)
2504  {
2505  const std::string new_reserve_elapsed_time_history = element->GetText();
2506 
2507  try
2508  {
2509  set_reserve_elapsed_time_history(new_reserve_elapsed_time_history != "0");
2510  }
2511  catch(const std::logic_error& e)
2512  {
2513  std::cout << e.what() << std::endl;
2514  }
2515  }
2516  }
2517 
2518  // Reserve generalization performance history
2519  {
2520  const tinyxml2::XMLElement* element = root_element->FirstChildElement("ReserveGeneralizationPerformanceHistory");
2521 
2522  if(element)
2523  {
2524  const std::string new_reserve_generalization_performance_history = element->GetText();
2525 
2526  try
2527  {
2528  set_reserve_generalization_performance_history(new_reserve_generalization_performance_history != "0");
2529  }
2530  catch(const std::logic_error& e)
2531  {
2532  std::cout << e.what() << std::endl;
2533  }
2534  }
2535  }
2536 
2537  // Display period
2538  {
2539  const tinyxml2::XMLElement* element = root_element->FirstChildElement("DisplayPeriod");
2540 
2541  if(element)
2542  {
2543  const size_t new_display_period = atoi(element->GetText());
2544 
2545  try
2546  {
2547  set_display_period(new_display_period);
2548  }
2549  catch(const std::logic_error& e)
2550  {
2551  std::cout << e.what() << std::endl;
2552  }
2553  }
2554  }
2555 
2556  // Save period
2557  {
2558  const tinyxml2::XMLElement* element = root_element->FirstChildElement("SavePeriod");
2559 
2560  if(element)
2561  {
2562  const size_t new_save_period = atoi(element->GetText());
2563 
2564  try
2565  {
2566  set_save_period(new_save_period);
2567  }
2568  catch(const std::logic_error& e)
2569  {
2570  std::cout << e.what() << std::endl;
2571  }
2572  }
2573  }
2574 
2575  // Neural network file name
2576  {
2577  const tinyxml2::XMLElement* element = root_element->FirstChildElement("NeuralNetworkFileName");
2578 
2579  if(element)
2580  {
2581  const std::string new_neural_network_file_name = element->GetText();
2582 
2583  try
2584  {
2585  set_neural_network_file_name(new_neural_network_file_name);
2586  }
2587  catch(const std::logic_error& e)
2588  {
2589  std::cout << e.what() << std::endl;
2590  }
2591  }
2592  }
2593 
2594  // Display
2595  {
2596  const tinyxml2::XMLElement* element = root_element->FirstChildElement("Display");
2597 
2598  if(element)
2599  {
2600  const std::string new_display = element->GetText();
2601 
2602  try
2603  {
2604  set_display(new_display != "0");
2605  }
2606  catch(const std::logic_error& e)
2607  {
2608  std::cout << e.what() << std::endl;
2609  }
2610  }
2611  }
2612 }
2613 
2614 }
2615 
2616 
2617 // OpenNN: Open Neural Networks Library.
2618 // Copyright (c) 2005-2015 Roberto Lopez.
2619 //
2620 // This library is free software; you can redistribute it and/or
2621 // modify it under the terms of the GNU Lesser General Public
2622 // License as published by the Free Software Foundation; either
2623 // version 2.1 of the License, or any later version.
2624 //
2625 // This library is distributed in the hope that it will be useful,
2626 // but WITHOUT ANY WARRANTY; without even the implied warranty of
2627 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2628 // Lesser General Public License for more details.
2629 
2630 // You should have received a copy of the GNU Lesser General Public
2631 // License along with this library; if not, write to the Free Software
2632 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2633 
virtual double calculate_generalization_performance(void) const
const bool & get_reserve_elapsed_time_history(void) const
Returns true if the elapsed time history vector is to be reserved, and false otherwise.
bool reserve_training_direction_history
True if the training direction history matrix is to be reserved, false otherwise. ...
bool reserve_training_rate_history
True if the training rate history vector is to be reserved, false otherwise.
Vector< double > training_rate_history
History of the random search training rate over the training iterations.
void set_reserve_all_training_history(const bool &)
void set_performance_goal(const double &)
size_t count_parameters_number(void) const
const bool & get_reserve_gradient_norm_history(void) const
Returns true if the gradient norm history vector is to be reserved, and false otherwise.
void set_reserve_elapsed_time_history(const bool &)
const double & get_minimum_performance_increase(void) const
Returns the minimum performance improvement during training.
TrainingRateAlgorithm * get_training_rate_algorithm_pointer(void)
Returns a pointer to the training rate algorithm object inside the gradient descent object...
Vector< double > final_training_direction
Final gradient descent training direction.
Vector< double > calculate_gradient(void) const
Returns the performance function gradient, as the sum of the objective and the regularization gradien...
Matrix< std::string > to_string_matrix(void) const
size_t maximum_iterations_number
Maximum number of iterations to perform_training. It is used as a stopping criterion.
double warning_parameters_norm
Value for the parameters norm at which a warning message is written to the screen.
double minimum_performance_increase
Minimum performance improvement between two successive iterations. It is used as a stopping criterion...
Vector< double > arrange_parameters(void) const
bool reserve_parameters_norm_history
True if the parameters norm history vector is to be reserved, false otherwise.
Matrix< std::string > write_final_results(const size_t &precision=3) const
Returns a default (empty) string matrix with the final results from training.
size_t iterations_number
Maximum number of training iterations.
void set_performance_functional_pointer(PerformanceFunctional *)
const bool & get_reserve_training_rate_history(void) const
Returns true if the training rate history vector is to be reserved, and false otherwise.
Vector< Vector< double > > gradient_history
History of the performance function gradient over the training iterations.
void set_minimum_performance_increase(const double &)
void set_maximum_generalization_performance_decreases(const size_t &)
double final_parameters_norm
Final neural network parameters norm.
const double & get_gradient_norm_goal(void) const
void set_display_period(const size_t &)
bool display
Display messages to screen.
NeuralNetwork * get_neural_network_pointer(void) const
Returns a pointer to the neural network associated to the performance functional. ...
double maximum_time
Maximum training time. It is used as a stopping criterion.
void set_maximum_iterations_number(const size_t &)
const double & get_warning_gradient_norm(void) const
bool reserve_gradient_history
True if the gradient history matrix is to be reserved, false otherwise.
std::string to_string(void) const
Returns a string representation of the results structure.
const double & get_error_gradient_norm(void) const
void set_warning_parameters_norm(const double &)
const TrainingRateAlgorithm & get_training_rate_algorithm(void) const
Returns a constant reference to the training rate algorithm object inside the gradient descent object...
void set_warning_gradient_norm(const double &)
std::string write_training_rate_method(void) const
Returns a string with the name of the training rate method to be used.
tinyxml2::XMLDocument * to_XML(void) const
void set_reserve_training_rate_history(const bool &)
void set_reserve_gradient_norm_history(const bool &)
double error_gradient_norm
Value for the gradient norm at which the training process is assumed to fail.
bool reserve_gradient_norm_history
True if the gradient norm history vector is to be reserved, false otherwise.
void set_warning_training_rate(const double &)
void set_save_period(const size_t &)
Vector< double > generalization_performance_history
History of the generalization performance over the training iterations.
void set_minimum_parameters_increment_norm(const double &)
double warning_training_rate
Training rate value at wich a warning message is written to the screen.
std::string write_training_algorithm_type(void) const
This method writes a string with the type of training algoritm.
GradientDescentResults * perform_training(void)
const double & get_error_training_rate(void) const
Vector< Vector< double > > training_direction_history
History of the random search training direction over the training iterations.
Vector< Vector< double > > parameters_history
History of the neural network parameters over the training iterations.
void set_default(void)
Sets the members of the training algorithm object to their default values.
const bool & get_reserve_training_direction_history(void) const
Returns true if the training direction history matrix is to be reserved, and false otherwise...
size_t save_period
Number of iterations between the training saving progress.
Vector< double > calculate_directional_point(const double &, const Vector< double > &, const double &) const
double warning_gradient_norm
Value for the gradient norm at which a warning message is written to the screen.
tinyxml2::XMLDocument * to_XML(void) const
double performance_goal
Goal value for the performance. It is used as a stopping criterion.
virtual std::string write_information(void)
bool reserve_parameters_history
True if the parameters history matrix is to be reserved, false otherwise.
double final_generalization_performance
Final generalization performance.
void set_error_training_rate(const double &)
double calculate_norm(void) const
Returns the vector norm.
Definition: vector.h:2358
const bool & get_reserve_gradient_history(void) const
Returns true if the gradient history vector of vectors is to be reserved, and false otherwise...
Vector< double > calculate_training_direction(const Vector< double > &) const
bool reserve_elapsed_time_history
True if the elapsed time history vector is to be reserved, false otherwise.
TrainingRateAlgorithm training_rate_algorithm
Training rate algorithm object for one-dimensional minimization.
void set_gradient_norm_goal(const double &)
std::string neural_network_file_name
Path where the neural network is saved.
const size_t & get_maximum_generalization_performance_decreases(void) const
Returns the maximum number of generalization failures during the training process.
double error_parameters_norm
Value for the parameters norm at which the training process is assumed to fail.
void set_neural_network_file_name(const std::string &)
void set_reserve_training_direction_history(const bool &)
void set_reserve_performance_history(const bool &)
void set_column(const size_t &, const Vector< T > &)
Definition: matrix.h:1774
void set_reserve_generalization_performance_history(const bool &)
Vector< T > calculate_normalized(void) const
Returns this vector divided by its norm.
Definition: vector.h:2530
double gradient_norm_goal
Goal value for the norm of the objective function gradient. It is used as a stopping criterion...
double elapsed_time
Elapsed time of the training process.
Vector< double > performance_history
History of the performance function performance over the training iterations.
void from_XML(const tinyxml2::XMLDocument &)
void set_maximum_time(const double &)
void set_reserve_parameters_norm_history(const bool &)
const double & get_minimum_parameters_increment_norm(void) const
Returns the minimum norm of the parameter increment vector used as a stopping criteria when training...
void from_XML(const tinyxml2::XMLDocument &)
void set_reserve_gradient_history(const bool &)
void set_error_gradient_norm(const double &)
const double & get_training_rate_tolerance(void) const
Returns the tolerance value in line minimization.
Vector< double > final_gradient
Final performance function gradient.
void save(const std::string &) const
const size_t & get_maximum_iterations_number(void) const
Returns the maximum number of iterations for training.
void set_performance_functional_pointer(PerformanceFunctional *)
const double & get_maximum_time(void) const
Returns the maximum training time.
virtual void check(void) const
Vector< double > elapsed_time_history
History of the elapsed time over the training iterations.
bool reserve_generalization_performance_history
True if the Generalization performance history vector is to be reserved, false otherwise.
std::string stopping_criterion
Stopping criterion.
const double & get_performance_goal(void) const
const bool & get_reserve_performance_history(void) const
Returns true if the performance history vector is to be reserved, and false otherwise.
double final_performance
Final performance function evaluation.
const double & get_warning_training_rate(void) const
const double & get_error_parameters_norm(void) const
size_t maximum_generalization_performance_decreases
const bool & get_reserve_generalization_performance_history(void) const
Returns true if the Generalization performance history vector is to be reserved, and false otherwise...
double minimum_parameters_increment_norm
Norm of the parameters increment vector at which training stops.
const bool & get_reserve_parameters_history(void) const
Returns true if the parameters history matrix is to be reserved, and false otherwise.
double error_training_rate
Training rate at wich the line minimization algorithm is assumed to be unable to bracket a minimum...
void set_error_parameters_norm(const double &)
const bool & get_reserve_parameters_norm_history(void) const
Returns true if the parameters norm history vector is to be reserved, and false otherwise.
Vector< double > parameters_norm_history
History of the parameters norm over the training iterations.
double final_training_rate
Final gradient descent training rate.
PerformanceFunctional * performance_functional_pointer
Pointer to a performance functional for a multilayer perceptron object.
const double & get_warning_parameters_norm(void) const
bool reserve_performance_history
True if the performance history vector is to be reserved, false otherwise.
virtual ~GradientDescent(void)
Destructor.
void set_training_rate_algorithm(const TrainingRateAlgorithm &)
size_t display_period
Number of iterations between the training showing progress.
Vector< double > final_parameters
Final neural network parameters vector.
Vector< double > gradient_norm_history
History of the gradient norm over the training iterations.
void set_reserve_parameters_history(const bool &)
void set_parameters(const Vector< double > &)