levenberg_marquardt_algorithm.cpp
1// OpenNN: Open Neural Networks Library
2// www.opennn.net
3//
4// L E V E N B E R G - M A R Q U A R D T A L G O R I T H M C L A S S
5//
6// Artificial Intelligence Techniques SL
7// artelnics@artelnics.com
8
9#include "levenberg_marquardt_algorithm.h"
10
11namespace OpenNN
12{
13
17
20{
22}
23
24
29
31 : OptimizationAlgorithm(new_loss_index_pointer)
32{
34}
35
36
39
41{
42}
43
44
46
48{
50}
51
52
55
57{
58 return training_loss_goal;
59}
60
61
63
65{
67}
68
69
71
73{
75}
76
77
79
81{
82 return maximum_time;
83}
84
85
87
89{
90 return damping_parameter;
91}
92
93
95
97{
99}
100
101
103
105{
107}
108
109
111
113{
115}
116
117
133
135{
136 // Stopping criteria
137
138 minimum_loss_decrease = type(0);
139 training_loss_goal = type(0);
141
143 maximum_time = type(3600.0);
144
145 // UTILITIES
146
147 display_period = 10;
148
149 // Training parameters
150
151 damping_parameter = static_cast<type>(1.0e-3);
152
153 damping_parameter_factor = type(10.0);
154
155 minimum_damping_parameter = static_cast<type>(1.0e-6);
156 maximum_damping_parameter = static_cast<type>(1.0e6);
157}
158
159
162
163void LevenbergMarquardtAlgorithm::set_damping_parameter(const type& new_damping_parameter)
164{
165 if(new_damping_parameter <= minimum_damping_parameter)
166 {
168 }
169 else if(new_damping_parameter >= maximum_damping_parameter)
170 {
172 }
173 else
174 {
175 damping_parameter = new_damping_parameter;
176 }
177}
178
179
182
183void LevenbergMarquardtAlgorithm::set_damping_parameter_factor(const type& new_damping_parameter_factor)
184{
185#ifdef OPENNN_DEBUG
186
187 if(new_damping_parameter_factor <= static_cast<type>(0.0))
188 {
189 ostringstream buffer;
190
191 buffer << "OpenNN Exception: LevenbergMarquardtAlgorithm class." << endl
192 << "void set_damping_parameter_factor(const type&) method." << endl
193 << "Damping parameter factor must be greater than zero." << endl;
194
195 throw logic_error(buffer.str());
196 }
197
198#endif
199
200 damping_parameter_factor = new_damping_parameter_factor;
201}
202
203
206
207void LevenbergMarquardtAlgorithm::set_minimum_damping_parameter(const type& new_minimum_damping_parameter)
208{
209#ifdef OPENNN_DEBUG
210
211 if(new_minimum_damping_parameter <= static_cast<type>(0.0))
212 {
213 ostringstream buffer;
214
215 buffer << "OpenNN Exception: LevenbergMarquardtAlgorithm class." << endl
216 << "void set_minimum_damping_parameter(const type&) method." << endl
217 << "Minimum damping parameter must be greater than zero." << endl;
218
219 throw logic_error(buffer.str());
220 }
221
222#endif
223
224 minimum_damping_parameter = new_minimum_damping_parameter;
225}
226
227
230
231void LevenbergMarquardtAlgorithm::set_maximum_damping_parameter(const type& new_maximum_damping_parameter)
232{
233#ifdef OPENNN_DEBUG
234
235 if(new_maximum_damping_parameter <= static_cast<type>(0.0))
236 {
237 ostringstream buffer;
238
239 buffer << "OpenNN Exception: LevenbergMarquardtAlgorithm class." << endl
240 << "void set_maximum_damping_parameter(const type&) method." << endl
241 << "Maximum damping parameter must be greater than zero." << endl;
242
243 throw logic_error(buffer.str());
244 }
245
246#endif
247
248 maximum_damping_parameter = new_maximum_damping_parameter;
249}
250
251
254
255void LevenbergMarquardtAlgorithm::set_minimum_loss_decrease(const type& new_minimum_loss_decrease)
256{
257 minimum_loss_decrease = new_minimum_loss_decrease;
258}
259
260
264
265void LevenbergMarquardtAlgorithm::set_loss_goal(const type& new_loss_goal)
266{
267 training_loss_goal = new_loss_goal;
268}
269
270
274
276 const Index& new_maximum_selection_failures)
277{
278 maximum_selection_failures = new_maximum_selection_failures;
279}
280
281
284
285void LevenbergMarquardtAlgorithm::set_maximum_epochs_number(const Index& new_maximum_epochs_number)
286{
287 maximum_epochs_number = new_maximum_epochs_number;
288}
289
290
293
294void LevenbergMarquardtAlgorithm::set_maximum_time(const type& new_maximum_time)
295{
296#ifdef OPENNN_DEBUG
297
298 if(new_maximum_time < static_cast<type>(0.0))
299 {
300 ostringstream buffer;
301
302 buffer << "OpenNN Exception: OptimizationAlgorithm class.\n"
303 << "void set_maximum_time(const type&) method.\n"
304 << "Maximum time must be equal or greater than 0.\n";
305
306 throw logic_error(buffer.str());
307 }
308
309#endif
310
311 maximum_time = new_maximum_time;
312}
313
314
323
325{
326 ostringstream buffer;
327
329 {
330 buffer << "OpenNN Exception: LevenbergMarquardtAlgorithm class.\n"
331 << "void check() const method.\n"
332 << "Pointer to loss index is nullptr.\n";
333
334 throw logic_error(buffer.str());
335 }
336
337 const DataSet* data_set_pointer = loss_index_pointer->get_data_set_pointer();
338
339 if(!data_set_pointer)
340 {
341 buffer << "OpenNN Exception: LevenbergMarquardtAlgorithm class." << endl
342 << "void check() const method.\n"
343 << "The loss funcional has no data set." << endl;
344
345 throw logic_error(buffer.str());
346 }
347
348 const NeuralNetwork* neural_network_pointer = loss_index_pointer->get_neural_network_pointer();
349
350 if(!neural_network_pointer)
351 {
352 buffer << "OpenNN Exception: LevenbergMarquardtAlgorithm class." << endl
353 << "void check() const method.\n"
354 << "Pointer to neural network is nullptr." << endl;
355
356 throw logic_error(buffer.str());
357 }
358}
359
360
363
365{
366 if(loss_index_pointer->get_error_type() == "MINKOWSKI_ERROR")
367 {
368 throw logic_error("Levenberg-Marquard algorithm cannot work with Minkowski error.");
369 }
370 else if(loss_index_pointer->get_error_type() == "CROSS_ENTROPY_ERROR")
371 {
372 throw logic_error("Levenberg-Marquard algorithm cannot work with cross entropy error.");
373 }
374 else if(loss_index_pointer->get_error_type() == "WEIGHTED_SQUARED_ERROR")
375 {
376 throw logic_error("Levenberg-Marquard algorithm is not implemented yet with weighted squared error.");
377 }
378
379 ostringstream buffer;
380
381 // Control sentence
382
383#ifdef OPENNN_DEBUG
384
385 check();
386
387#endif
388
389 // Start training
390
391 if(display) cout << "Training with Levenberg-Marquardt algorithm...\n";
392
394
395 // Data set
396
397 DataSet* data_set_pointer = loss_index_pointer->get_data_set_pointer();
398
399 const bool has_selection = data_set_pointer->has_selection();
400
401 const Index training_samples_number = data_set_pointer->get_training_samples_number();
402 const Index selection_samples_number = data_set_pointer->get_selection_samples_number();
403
404 const Tensor<Index, 1> training_samples_indices = data_set_pointer->get_training_samples_indices();
405 const Tensor<Index, 1> selection_samples_indices = data_set_pointer->get_selection_samples_indices();
406
407 const Tensor<Index, 1> input_variables_indices = data_set_pointer->get_input_variables_indices();
408 const Tensor<Index, 1> target_variables_indices = data_set_pointer->get_target_variables_indices();
409
410 const Tensor<string, 1> inputs_names = data_set_pointer->get_input_variables_names();
411 const Tensor<string, 1> targets_names = data_set_pointer->get_target_variables_names();
412
413 const Tensor<Scaler, 1> input_variables_scalers = data_set_pointer->get_input_variables_scalers();
414 const Tensor<Scaler, 1> target_variables_scalers = data_set_pointer->get_target_variables_scalers();
415
416 Tensor<Descriptives, 1> input_variables_descriptives;
417 Tensor<Descriptives, 1> target_variables_descriptives;
418
419 // Neural network
420
422
423 neural_network_pointer->set_inputs_names(inputs_names);
424 neural_network_pointer->set_outputs_names(targets_names);
425
426 if(neural_network_pointer->has_scaling_layer())
427 {
428 input_variables_descriptives = data_set_pointer->scale_input_variables();
429
430 ScalingLayer* scaling_layer_pointer = neural_network_pointer->get_scaling_layer_pointer();
431 scaling_layer_pointer->set(input_variables_descriptives, input_variables_scalers);
432 }
433
434 if(neural_network_pointer->has_unscaling_layer())
435 {
436 target_variables_descriptives = data_set_pointer->scale_target_variables();
437
438 UnscalingLayer* unscaling_layer_pointer = neural_network_pointer->get_unscaling_layer_pointer();
439 unscaling_layer_pointer->set(target_variables_descriptives, target_variables_scalers);
440 }
441
442 DataSetBatch training_batch(training_samples_number, data_set_pointer);
443 training_batch.fill(training_samples_indices, input_variables_indices, target_variables_indices);
444
445 DataSetBatch selection_batch(selection_samples_number, data_set_pointer);
446 selection_batch.fill(selection_samples_indices, input_variables_indices, target_variables_indices);
447
448 NeuralNetworkForwardPropagation training_forward_propagation(training_samples_number, neural_network_pointer);
449 NeuralNetworkForwardPropagation selection_forward_propagation(selection_samples_number, neural_network_pointer);
450
451 // Loss index
452
453 loss_index_pointer->set_normalization_coefficient();
454
455 type old_loss = type(0);
456 type loss_decrease = numeric_limits<type>::max();
457
458 Index selection_failures = 0;
459
460 LossIndexBackPropagationLM training_back_propagation_lm(training_samples_number, loss_index_pointer);
461 LossIndexBackPropagationLM selection_back_propagation_lm(selection_samples_number, loss_index_pointer);
462
463 // Training strategy stuff
464
465 bool stop_training = false;
466
467 time_t beginning_time, current_time;
468 time(&beginning_time);
469 type elapsed_time = type(0);
470
471 LevenbergMarquardtAlgorithmData optimization_data(this);
472
473 // Main loop
474
475 for(Index epoch = 0; epoch <= maximum_epochs_number; epoch++)
476 {
477 if(display && epoch%display_period == 0) cout << "Epoch: " << epoch << endl;
478
479 optimization_data.epoch = epoch;
480
481 // Neural network
482
483 neural_network_pointer->forward_propagate(training_batch,
484 training_forward_propagation);
485
486 // Loss index
487
489 training_forward_propagation,
490 training_back_propagation_lm);
491
492 results.training_error_history(epoch) = training_back_propagation_lm.error;
493
494 if(has_selection)
495 {
496 neural_network_pointer->forward_propagate(selection_batch,
497 selection_forward_propagation);
498
499 loss_index_pointer->calculate_errors_lm(selection_batch,
500 selection_forward_propagation,
501 selection_back_propagation_lm);
502
503 loss_index_pointer->calculate_squared_errors_lm(selection_batch,
504 selection_forward_propagation,
505 selection_back_propagation_lm);
506
507 loss_index_pointer->calculate_error_lm(selection_batch,
508 selection_forward_propagation,
509 selection_back_propagation_lm);
510
511 results.selection_error_history(epoch) = selection_back_propagation_lm.error;
512
513 if(epoch != 0 && results.selection_error_history(epoch) > results.selection_error_history(epoch-1)) selection_failures++;
514 }
515
516 // Elapsed time
517
518 time(&current_time);
519 elapsed_time = static_cast<type>(difftime(current_time, beginning_time));
520
521 if(display && epoch%display_period == 0)
522 {
523 cout << "Training error: " << training_back_propagation_lm.error << endl;
524 if(has_selection) cout << "Selection error: " << selection_back_propagation_lm.error << endl;
525 cout << "Damping parameter: " << damping_parameter << endl;
526 cout << "Elapsed time: " << write_time(elapsed_time) << endl;
527 }
528
529 if(training_back_propagation_lm.loss <= training_loss_goal)
530 {
531 if(display) cout << "Epoch " << epoch << "Loss goal reached: " << training_back_propagation_lm.loss << endl;
532
533 stop_training = true;
534
535 results.stopping_condition = StoppingCondition::LossGoal;
536 }
537
538 if(epoch != 0) loss_decrease = old_loss - training_back_propagation_lm.loss;
539
540 if(loss_decrease < minimum_loss_decrease)
541 {
542 if(display) cout << "Epoch " << epoch << endl << "Minimum loss decrease reached: " << loss_decrease << endl;
543
544 stop_training = true;
545
546 results.stopping_condition = StoppingCondition::MinimumLossDecrease;
547 }
548
549 old_loss = training_back_propagation_lm.loss;
550
551 if(selection_failures >= maximum_selection_failures)
552 {
553 if(display) cout << "Epoch " << epoch << "Maximum selection failures reached: " << selection_failures << endl;
554
555 stop_training = true;
556
557 results.stopping_condition = StoppingCondition::MaximumSelectionErrorIncreases;
558 }
559
560 if(epoch == maximum_epochs_number)
561 {
562 if(display) cout << "Epoch " << epoch << endl << "Maximum number of epochs reached: " << epoch << endl;
563
564 stop_training = true;
565
566 results.stopping_condition = StoppingCondition::MaximumEpochsNumber;
567 }
568
569 if(elapsed_time >= maximum_time)
570 {
571 if(display) cout << "Epoch " << epoch << "Maximum training time reached: " << elapsed_time << endl;
572
573 stop_training = true;
574
575 results.stopping_condition = StoppingCondition::MaximumTime;
576 }
577
578 if(stop_training)
579 {
580 results.resize_training_error_history(epoch+1);
581
582 if(has_selection) results.resize_selection_error_history(epoch+1);
583 else results.resize_selection_error_history(0);
584
585 results.elapsed_time = write_time(elapsed_time);
586
587 break;
588 }
589
590 if(epoch != 0 && epoch%save_period == 0) neural_network_pointer->save(neural_network_file_name);
591
592 update_parameters(training_batch,
593 training_forward_propagation,
594 training_back_propagation_lm,
595 optimization_data);
596 }
597
598 if(neural_network_pointer->has_scaling_layer())
599 data_set_pointer->unscale_input_variables(input_variables_descriptives);
600
601 if(neural_network_pointer->has_unscaling_layer())
602 data_set_pointer->unscale_target_variables(target_variables_descriptives);
603
604 if(display) results.print();
605
606 return results;
607}
608
609
616
618 NeuralNetworkForwardPropagation& forward_propagation,
619 LossIndexBackPropagationLM& back_propagation_lm,
620 LevenbergMarquardtAlgorithmData& optimization_data)
621{
622 const type regularization_weight = loss_index_pointer->get_regularization_weight();
623
625
626 bool success = false;
627
628 do
629 {
630 sum_diagonal(back_propagation_lm.hessian, damping_parameter);
631
632 optimization_data.parameters_increment
633 = perform_Householder_QR_decomposition(back_propagation_lm.hessian,(type(-1))*back_propagation_lm.gradient);
634
635 optimization_data.potential_parameters.device(*thread_pool_device)
636 = back_propagation_lm.parameters + optimization_data.parameters_increment;
637
638 neural_network_pointer->forward_propagate(batch, optimization_data.potential_parameters, forward_propagation);
639
640 loss_index_pointer->calculate_errors_lm(batch, forward_propagation, back_propagation_lm);
641 loss_index_pointer->calculate_squared_errors_lm(batch, forward_propagation, back_propagation_lm);
642 loss_index_pointer->calculate_error_lm(batch, forward_propagation, back_propagation_lm);
643
644 const type new_loss = back_propagation_lm.error
645 + regularization_weight*loss_index_pointer->calculate_regularization(optimization_data.potential_parameters);
646
647 if(new_loss < back_propagation_lm.loss) // succesfull step
648 {
650
651 back_propagation_lm.parameters = optimization_data.potential_parameters;
652
653 back_propagation_lm.loss = new_loss;
654
655 success = true;
656
657 break;
658 }
659 else
660 {
661 sum_diagonal(back_propagation_lm.hessian, -damping_parameter);
662
664 }
666
667 if(!success)
668 {
669 const Index parameters_number = back_propagation_lm.parameters.size();
670
671 for(Index i = 0; i < parameters_number; i++)
672 {
673 if(abs(back_propagation_lm.gradient(i)) < type(NUMERIC_LIMITS_MIN))
674 {
675 back_propagation_lm.parameters(i) = back_propagation_lm.parameters(i);
676
677 optimization_data.parameters_increment(i) = type(0);
678 }
679 else if(back_propagation_lm.gradient(i) > type(0))
680 {
681 back_propagation_lm.parameters(i) -= numeric_limits<type>::epsilon();
682 //= nextafter(back_propagation_lm.parameters(i), back_propagation_lm.parameters(i)-1);
683
684 optimization_data.parameters_increment(i) = -numeric_limits<type>::epsilon();
685 }
686 else if(back_propagation_lm.gradient(i) < type(0))
687 {
688 back_propagation_lm.parameters(i) += numeric_limits<type>::epsilon();
689 //= nextafter(back_propagation_lm.parameters(i), back_propagation_lm.parameters(i)+1);
690
691 optimization_data.parameters_increment(i) = numeric_limits<type>::epsilon();
692 }
693 }
694 }
695
696 // Set parameters
697
698 neural_network_pointer->set_parameters(back_propagation_lm.parameters);
699}
700
701
703
705{
706 return "LEVENBERG_MARQUARDT_ALGORITHM";
707}
708
709
711
713{
714 Tensor<string, 2> labels_values(7, 2);
715
716 // Damping parameter factor
717
718 labels_values(0,0) = "Damping parameter factor";
719 labels_values(0,1) = to_string(double(damping_parameter_factor));
720
721 // Minimum loss decrease
722
723 labels_values(2,0) = "Minimum loss decrease";
724 labels_values(2,1) = to_string(double(minimum_loss_decrease));
725
726 // Loss goal
727
728 labels_values(3,0) = "Loss goal";
729 labels_values(3,1) = to_string(double(training_loss_goal));
730
731 // Maximum selection error increases
732
733 labels_values(4,0) = "Maximum selection error increases";
734 labels_values(4,1) = to_string(maximum_selection_failures);
735
736 // Maximum epochs number
737
738 labels_values(5,0) = "Maximum epochs number";
739 labels_values(5,1) = to_string(maximum_epochs_number);
740
741 // Maximum time
742
743 labels_values(6,0) = "Maximum time";
744 labels_values(6,1) = write_time(maximum_time);
745
746 return labels_values;
747}
748
749
753
755{
756 ostringstream buffer;
757
758 file_stream.OpenElement("LevenbergMarquardt");
759
760 // Damping paramterer factor.
761
762 file_stream.OpenElement("DampingParameterFactor");
763
764 buffer.str("");
765 buffer << damping_parameter_factor;
766
767 file_stream.PushText(buffer.str().c_str());
768
769 file_stream.CloseElement();
770
771 // Minimum loss decrease
772
773 file_stream.OpenElement("MinimumLossDecrease");
774
775 buffer.str("");
776 buffer << minimum_loss_decrease;
777
778 file_stream.PushText(buffer.str().c_str());
779
780 file_stream.CloseElement();
781
782 // Loss goal
783
784 file_stream.OpenElement("LossGoal");
785
786 buffer.str("");
787 buffer << training_loss_goal;
788
789 file_stream.PushText(buffer.str().c_str());
790
791 file_stream.CloseElement();
792
793 // Maximum selection error increases
794
795 file_stream.OpenElement("MaximumSelectionErrorIncreases");
796
797 buffer.str("");
799
800 file_stream.PushText(buffer.str().c_str());
801
802 file_stream.CloseElement();
803
804 // Maximum iterations number
805
806 file_stream.OpenElement("MaximumEpochsNumber");
807
808 buffer.str("");
809 buffer << maximum_epochs_number;
810
811 file_stream.PushText(buffer.str().c_str());
812
813 file_stream.CloseElement();
814
815 // Maximum time
816
817 file_stream.OpenElement("MaximumTime");
818
819 buffer.str("");
820 buffer << maximum_time;
821
822 file_stream.PushText(buffer.str().c_str());
823
824 file_stream.CloseElement();
825
826 // Hardware use
827
828 file_stream.OpenElement("HardwareUse");
829
830 buffer.str("");
831 buffer << hardware_use;
832
833 file_stream.PushText(buffer.str().c_str());
834
835 file_stream.CloseElement();
836
837 file_stream.CloseElement();
838}
839
840
844
846{
847 const tinyxml2::XMLElement* root_element = document.FirstChildElement("LevenbergMarquardt");
848
849 if(!root_element)
850 {
851 ostringstream buffer;
852
853 buffer << "OpenNN Exception: LevenbergMarquardtAlgorithm class.\n"
854 << "void from_XML(const tinyxml2::XMLDocument&) method.\n"
855 << "Levenberg-Marquardt algorithm element is nullptr.\n";
856
857 throw logic_error(buffer.str());
858 }
859
860 // Damping parameter factor
861
862 const tinyxml2::XMLElement* damping_parameter_factor_element
863 = root_element->FirstChildElement("DampingParameterFactor");
864
865 if(damping_parameter_factor_element)
866 {
867 const type new_damping_parameter_factor = static_cast<type>(atof(damping_parameter_factor_element->GetText()));
868
869 try
870 {
871 set_damping_parameter_factor(new_damping_parameter_factor);
872 }
873 catch(const logic_error& e)
874 {
875 cerr << e.what() << endl;
876 }
877 }
878
879 // Minimum loss decrease
880
881 const tinyxml2::XMLElement* minimum_loss_decrease_element = root_element->FirstChildElement("MinimumLossDecrease");
882
883 if(minimum_loss_decrease_element)
884 {
885 const type new_minimum_loss_decrease = static_cast<type>(atof(minimum_loss_decrease_element->GetText()));
886
887 try
888 {
889 set_minimum_loss_decrease(new_minimum_loss_decrease);
890 }
891 catch(const logic_error& e)
892 {
893 cerr << e.what() << endl;
894 }
895 }
896
897 // Loss goal
898
899 const tinyxml2::XMLElement* loss_goal_element = root_element->FirstChildElement("LossGoal");
900
901 if(loss_goal_element)
902 {
903 const type new_loss_goal = static_cast<type>(atof(loss_goal_element->GetText()));
904
905 try
906 {
907 set_loss_goal(new_loss_goal);
908 }
909 catch(const logic_error& e)
910 {
911 cerr << e.what() << endl;
912 }
913 }
914
915 // Maximum selection error increases
916
917 const tinyxml2::XMLElement* maximum_selection_failures_element
918 = root_element->FirstChildElement("MaximumSelectionErrorIncreases");
919
920 if(maximum_selection_failures_element)
921 {
922 const Index new_maximum_selection_failures
923 = static_cast<Index>(atoi(maximum_selection_failures_element->GetText()));
924
925 try
926 {
927 set_maximum_selection_failures(new_maximum_selection_failures);
928 }
929 catch(const logic_error& e)
930 {
931 cerr << e.what() << endl;
932 }
933 }
934
935 // Maximum epochs number
936
937 const tinyxml2::XMLElement* maximum_epochs_number_element = root_element->FirstChildElement("MaximumEpochsNumber");
938
939 if(maximum_epochs_number_element)
940 {
941 const Index new_maximum_epochs_number = static_cast<Index>(atoi(maximum_epochs_number_element->GetText()));
942
943 try
944 {
945 set_maximum_epochs_number(new_maximum_epochs_number);
946 }
947 catch(const logic_error& e)
948 {
949 cerr << e.what() << endl;
950 }
951 }
952
953 // Maximum time
954
955 const tinyxml2::XMLElement* maximum_time_element = root_element->FirstChildElement("MaximumTime");
956
957 if(maximum_time_element)
958 {
959 const type new_maximum_time = static_cast<type>(atof(maximum_time_element->GetText()));
960
961 try
962 {
963 set_maximum_time(new_maximum_time);
964 }
965 catch(const logic_error& e)
966 {
967 cerr << e.what() << endl;
968 }
969 }
970
971 // Hardware use
972 {
973 const tinyxml2::XMLElement* element = root_element->FirstChildElement("HardwareUse");
974
975 if(element)
976 {
977 const string new_hardware_use = element->GetText();
978
979 try
980 {
981 set_hardware_use(new_hardware_use);
982 }
983 catch(const logic_error& e)
984 {
985 cerr << e.what() << endl;
986 }
987 }
988 }
989}
990
991}
992
993// OpenNN: Open Neural Networks Library.
994// Copyright(C) 2005-2021 Artificial Intelligence Techniques, SL.
995//
996// This library is free software; you can redistribute it and/or
997// modify it under the terms of the GNU Lesser General Public
998// License as published by the Free Software Foundation; either
999// version 2.1 of the License, or any later version.
1000//
1001// This library is distributed in the hope that it will be useful,
1002// but WITHOUT ANY WARRANTY; without even the implied warranty of
1003// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1004// Lesser General Public License for more details.
1005
1006// You should have received a copy of the GNU Lesser General Public
1007// License along with this library; if not, write to the Free Software
1008// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
This class represents the concept of data set for data modelling problems, such as approximation,...
Definition: data_set.h:57
Index get_training_samples_number() const
Returns the number of samples in the data set which will be used for training.
Definition: data_set.cpp:1382
Tensor< Descriptives, 1 > scale_target_variables()
Definition: data_set.cpp:6298
Tensor< Index, 1 > get_training_samples_indices() const
Returns the indices of the samples which will be used for training.
Definition: data_set.cpp:1073
Tensor< Index, 1 > get_selection_samples_indices() const
Returns the indices of the samples which will be used for selection.
Definition: data_set.cpp:1098
void unscale_input_variables(const Tensor< Descriptives, 1 > &)
Definition: data_set.cpp:6351
Tensor< Index, 1 > get_target_variables_indices() const
Returns the indices of the target variables.
Definition: data_set.cpp:3094
Index get_selection_samples_number() const
Returns the number of samples in the data set which will be used for selection.
Definition: data_set.cpp:1402
void unscale_target_variables(const Tensor< Descriptives, 1 > &)
Definition: data_set.cpp:6397
Tensor< string, 1 > get_target_variables_names() const
Definition: data_set.cpp:2215
Tensor< Index, 1 > get_input_variables_indices() const
Returns the indices of the input variables.
Definition: data_set.cpp:3047
Tensor< string, 1 > get_input_variables_names() const
Definition: data_set.cpp:2184
Tensor< Descriptives, 1 > scale_input_variables()
Definition: data_set.cpp:6243
const type & get_minimum_damping_parameter() const
Returns the minimum damping parameter allowed in the algorithm.
const type & get_maximum_time() const
Returns the maximum training time.
void from_XML(const tinyxml2::XMLDocument &)
const Index & get_maximum_epochs_number() const
Returns the maximum number of iterations for training.
Tensor< string, 2 > to_string_matrix() const
Writes as matrix of strings the most representative atributes.
type minimum_loss_decrease
Minimum loss improvement between two successive iterations. It is used as a stopping criterion.
void update_parameters(const DataSetBatch &, NeuralNetworkForwardPropagation &, LossIndexBackPropagationLM &, LevenbergMarquardtAlgorithmData &)
LevenbergMarquardtAlgorithm::update_parameters.
string write_optimization_algorithm_type() const
Writes the optimization algorithm type.
type damping_parameter
Initial Levenberg-Marquardt parameter.
type maximum_time
Maximum training time. It is used as a stopping criterion.
type damping_parameter_factor
Damping parameter increase/decrease factor.
const type & get_damping_parameter_factor() const
Returns the damping parameter factor(beta in the User's Guide) for the hessian approximation.
type minimum_damping_parameter
Minimum Levenberg-Marquardt parameter.
type training_loss_goal
Goal value for the loss. It is used as a stopping criterion.
const type & get_maximum_damping_parameter() const
Returns the maximum damping parameter allowed in the algorithm.
Index maximum_epochs_number
Maximum number of epoch to perform_training. It is used as a stopping criterion.
void write_XML(tinyxml2::XMLPrinter &) const
const type & get_damping_parameter() const
Returns the damping parameter for the hessian approximation.
const Index & get_maximum_selection_failures() const
Returns the maximum number of selection failures during the training process.
type maximum_damping_parameter
Maximum Levenberg-Marquardt parameter.
const type & get_minimum_loss_decrease() const
Returns the minimum loss improvement during training.
This abstract class represents the concept of loss index composed of an error term and a regularizati...
Definition: loss_index.h:48
void back_propagate_lm(const DataSetBatch &, NeuralNetworkForwardPropagation &, LossIndexBackPropagationLM &) const
Definition: loss_index.cpp:457
virtual string get_error_type() const
Returns a string with the default type of error term, "USER_PERFORMANCE_TERM".
Definition: loss_index.cpp:608
NeuralNetwork * get_neural_network_pointer() const
Returns a pointer to the neural network object associated to the error term.
Definition: loss_index.h:70
type calculate_regularization(const Tensor< type, 1 > &) const
Definition: loss_index.cpp:648
const type & get_regularization_weight() const
Returns regularization weight.
Definition: loss_index.cpp:52
DataSet * get_data_set_pointer() const
Returns a pointer to the data set object associated to the error term.
Definition: loss_index.h:92
ScalingLayer * get_scaling_layer_pointer() const
Returns a pointer to the scaling layers object composing this neural network object.
bool has_scaling_layer() const
bool has_unscaling_layer() const
void forward_propagate(const DataSetBatch &, NeuralNetworkForwardPropagation &) const
Calculate forward propagation in neural network.
void save(const string &) const
void set_parameters(Tensor< type, 1 > &)
UnscalingLayer * get_unscaling_layer_pointer() const
Returns a pointer to the unscaling layers object composing this neural network object.
void set_inputs_names(const Tensor< string, 1 > &)
void set_outputs_names(const Tensor< string, 1 > &)
string neural_network_file_name
Path where the neural network is saved.
void set_hardware_use(const string &)
Set hardware to use. Default: Multi-core.
LossIndex * loss_index_pointer
Pointer to a loss index for a neural network object.
bool display
Display messages to screen.
const string write_time(const type &) const
Writes the time from seconds in format HH:mm:ss.
Index save_period
Number of iterations between the training saving progress.
Index display_period
Number of iterations between the training showing progress.
This class represents a layer of scaling neurons.
Definition: scaling_layer.h:38
void set()
Sets the scaling layer to be empty.
This class represents a layer of unscaling neurons.
void set()
Sets the unscaling layer to be empty.
void PushText(const char *text, bool cdata=false)
Add a text node.
Definition: tinyxml2.cpp:2878
virtual void CloseElement(bool compactMode=false)
If streaming, close the Element.
Definition: tinyxml2.cpp:2834
HALF_CONSTEXPR half abs(half arg)
Definition: half.hpp:2735
A loss index composed of several terms, this structure represent the First Order for this function.
Definition: loss_index.h:383
This structure contains the optimization algorithm results.
Tensor< type, 1 > selection_error_history
History of the selection error over the training iterations.
void resize_training_error_history(const Index &)
Resizes the training error history keeping the values.
OptimizationAlgorithm::StoppingCondition stopping_condition
Stopping condition of the algorithm.
void resize_selection_error_history(const Index &)
Resizes the selection error history keeping the values.
Tensor< type, 1 > training_error_history
History of the loss function loss over the training iterations.
string elapsed_time
Elapsed time of the training process.