9#include "levenberg_marquardt_algorithm.h"
187 if(new_damping_parameter_factor <=
static_cast<type
>(0.0))
189 ostringstream buffer;
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;
195 throw logic_error(buffer.str());
211 if(new_minimum_damping_parameter <=
static_cast<type
>(0.0))
213 ostringstream buffer;
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;
219 throw logic_error(buffer.str());
235 if(new_maximum_damping_parameter <=
static_cast<type
>(0.0))
237 ostringstream buffer;
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;
243 throw logic_error(buffer.str());
276 const Index& new_maximum_selection_failures)
298 if(new_maximum_time <
static_cast<type
>(0.0))
300 ostringstream buffer;
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";
306 throw logic_error(buffer.str());
326 ostringstream buffer;
330 buffer <<
"OpenNN Exception: LevenbergMarquardtAlgorithm class.\n"
331 <<
"void check() const method.\n"
332 <<
"Pointer to loss index is nullptr.\n";
334 throw logic_error(buffer.str());
339 if(!data_set_pointer)
341 buffer <<
"OpenNN Exception: LevenbergMarquardtAlgorithm class." << endl
342 <<
"void check() const method.\n"
343 <<
"The loss funcional has no data set." << endl;
345 throw logic_error(buffer.str());
350 if(!neural_network_pointer)
352 buffer <<
"OpenNN Exception: LevenbergMarquardtAlgorithm class." << endl
353 <<
"void check() const method.\n"
354 <<
"Pointer to neural network is nullptr." << endl;
356 throw logic_error(buffer.str());
368 throw logic_error(
"Levenberg-Marquard algorithm cannot work with Minkowski error.");
372 throw logic_error(
"Levenberg-Marquard algorithm cannot work with cross entropy error.");
376 throw logic_error(
"Levenberg-Marquard algorithm is not implemented yet with weighted squared error.");
379 ostringstream buffer;
391 if(
display) cout <<
"Training with Levenberg-Marquardt algorithm...\n";
399 const bool has_selection = data_set_pointer->has_selection();
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();
416 Tensor<Descriptives, 1> input_variables_descriptives;
417 Tensor<Descriptives, 1> target_variables_descriptives;
431 scaling_layer_pointer->
set(input_variables_descriptives, input_variables_scalers);
439 unscaling_layer_pointer->
set(target_variables_descriptives, target_variables_scalers);
442 DataSetBatch training_batch(training_samples_number, data_set_pointer);
443 training_batch.fill(training_samples_indices, input_variables_indices, target_variables_indices);
445 DataSetBatch selection_batch(selection_samples_number, data_set_pointer);
446 selection_batch.fill(selection_samples_indices, input_variables_indices, target_variables_indices);
455 type old_loss = type(0);
456 type loss_decrease = numeric_limits<type>::max();
458 Index selection_failures = 0;
465 bool stop_training =
false;
467 time_t beginning_time, current_time;
468 time(&beginning_time);
469 type elapsed_time = type(0);
479 optimization_data.epoch = epoch;
484 training_forward_propagation);
489 training_forward_propagation,
490 training_back_propagation_lm);
497 selection_forward_propagation);
500 selection_forward_propagation,
501 selection_back_propagation_lm);
504 selection_forward_propagation,
505 selection_back_propagation_lm);
508 selection_forward_propagation,
509 selection_back_propagation_lm);
519 elapsed_time =
static_cast<type
>(difftime(current_time, beginning_time));
523 cout <<
"Training error: " << training_back_propagation_lm.error << endl;
524 if(has_selection) cout <<
"Selection error: " << selection_back_propagation_lm.error << endl;
526 cout <<
"Elapsed time: " <<
write_time(elapsed_time) << endl;
531 if(
display) cout <<
"Epoch " << epoch <<
"Loss goal reached: " << training_back_propagation_lm.loss << endl;
533 stop_training =
true;
538 if(epoch != 0) loss_decrease = old_loss - training_back_propagation_lm.loss;
542 if(
display) cout <<
"Epoch " << epoch << endl <<
"Minimum loss decrease reached: " << loss_decrease << endl;
544 stop_training =
true;
549 old_loss = training_back_propagation_lm.loss;
553 if(
display) cout <<
"Epoch " << epoch <<
"Maximum selection failures reached: " << selection_failures << endl;
555 stop_training =
true;
562 if(
display) cout <<
"Epoch " << epoch << endl <<
"Maximum number of epochs reached: " << epoch << endl;
564 stop_training =
true;
571 if(
display) cout <<
"Epoch " << epoch <<
"Maximum training time reached: " << elapsed_time << endl;
573 stop_training =
true;
593 training_forward_propagation,
594 training_back_propagation_lm,
626 bool success =
false;
632 optimization_data.parameters_increment
633 = perform_Householder_QR_decomposition(back_propagation_lm.hessian,(type(-1))*back_propagation_lm.gradient);
635 optimization_data.potential_parameters.device(*thread_pool_device)
636 = back_propagation_lm.parameters + optimization_data.parameters_increment;
638 neural_network_pointer->
forward_propagate(batch, optimization_data.potential_parameters, forward_propagation);
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);
644 const type new_loss = back_propagation_lm.error
647 if(new_loss < back_propagation_lm.loss)
651 back_propagation_lm.parameters = optimization_data.potential_parameters;
653 back_propagation_lm.loss = new_loss;
669 const Index parameters_number = back_propagation_lm.parameters.size();
671 for(Index i = 0; i < parameters_number; i++)
673 if(
abs(back_propagation_lm.gradient(i)) < type(NUMERIC_LIMITS_MIN))
675 back_propagation_lm.parameters(i) = back_propagation_lm.parameters(i);
677 optimization_data.parameters_increment(i) = type(0);
679 else if(back_propagation_lm.gradient(i) > type(0))
681 back_propagation_lm.parameters(i) -= numeric_limits<type>::epsilon();
684 optimization_data.parameters_increment(i) = -numeric_limits<type>::epsilon();
686 else if(back_propagation_lm.gradient(i) < type(0))
688 back_propagation_lm.parameters(i) += numeric_limits<type>::epsilon();
691 optimization_data.parameters_increment(i) = numeric_limits<type>::epsilon();
698 neural_network_pointer->
set_parameters(back_propagation_lm.parameters);
706 return "LEVENBERG_MARQUARDT_ALGORITHM";
714 Tensor<string, 2> labels_values(7, 2);
718 labels_values(0,0) =
"Damping parameter factor";
723 labels_values(2,0) =
"Minimum loss decrease";
728 labels_values(3,0) =
"Loss goal";
733 labels_values(4,0) =
"Maximum selection error increases";
738 labels_values(5,0) =
"Maximum epochs number";
743 labels_values(6,0) =
"Maximum time";
746 return labels_values;
756 ostringstream buffer;
758 file_stream.OpenElement(
"LevenbergMarquardt");
762 file_stream.OpenElement(
"DampingParameterFactor");
767 file_stream.
PushText(buffer.str().c_str());
773 file_stream.OpenElement(
"MinimumLossDecrease");
778 file_stream.
PushText(buffer.str().c_str());
784 file_stream.OpenElement(
"LossGoal");
789 file_stream.
PushText(buffer.str().c_str());
795 file_stream.OpenElement(
"MaximumSelectionErrorIncreases");
800 file_stream.
PushText(buffer.str().c_str());
806 file_stream.OpenElement(
"MaximumEpochsNumber");
811 file_stream.
PushText(buffer.str().c_str());
817 file_stream.OpenElement(
"MaximumTime");
822 file_stream.
PushText(buffer.str().c_str());
828 file_stream.OpenElement(
"HardwareUse");
833 file_stream.
PushText(buffer.str().c_str());
851 ostringstream buffer;
853 buffer <<
"OpenNN Exception: LevenbergMarquardtAlgorithm class.\n"
854 <<
"void from_XML(const tinyxml2::XMLDocument&) method.\n"
855 <<
"Levenberg-Marquardt algorithm element is nullptr.\n";
857 throw logic_error(buffer.str());
863 = root_element->FirstChildElement(
"DampingParameterFactor");
865 if(damping_parameter_factor_element)
867 const type new_damping_parameter_factor =
static_cast<type
>(atof(damping_parameter_factor_element->GetText()));
873 catch(
const logic_error& e)
875 cerr << e.what() << endl;
881 const tinyxml2::XMLElement* minimum_loss_decrease_element = root_element->FirstChildElement(
"MinimumLossDecrease");
883 if(minimum_loss_decrease_element)
885 const type new_minimum_loss_decrease =
static_cast<type
>(atof(minimum_loss_decrease_element->GetText()));
891 catch(
const logic_error& e)
893 cerr << e.what() << endl;
901 if(loss_goal_element)
903 const type new_loss_goal =
static_cast<type
>(atof(loss_goal_element->GetText()));
909 catch(
const logic_error& e)
911 cerr << e.what() << endl;
918 = root_element->FirstChildElement(
"MaximumSelectionErrorIncreases");
920 if(maximum_selection_failures_element)
922 const Index new_maximum_selection_failures
923 =
static_cast<Index
>(atoi(maximum_selection_failures_element->GetText()));
929 catch(
const logic_error& e)
931 cerr << e.what() << endl;
937 const tinyxml2::XMLElement* maximum_epochs_number_element = root_element->FirstChildElement(
"MaximumEpochsNumber");
939 if(maximum_epochs_number_element)
941 const Index new_maximum_epochs_number =
static_cast<Index
>(atoi(maximum_epochs_number_element->GetText()));
947 catch(
const logic_error& e)
949 cerr << e.what() << endl;
955 const tinyxml2::XMLElement* maximum_time_element = root_element->FirstChildElement(
"MaximumTime");
957 if(maximum_time_element)
959 const type new_maximum_time =
static_cast<type
>(atof(maximum_time_element->GetText()));
965 catch(
const logic_error& e)
967 cerr << e.what() << endl;
977 const string new_hardware_use = element->GetText();
983 catch(
const logic_error& e)
985 cerr << e.what() << endl;
This class represents the concept of data set for data modelling problems, such as approximation,...
Index get_training_samples_number() const
Returns the number of samples in the data set which will be used for training.
Tensor< Descriptives, 1 > scale_target_variables()
Tensor< Index, 1 > get_training_samples_indices() const
Returns the indices of the samples which will be used for training.
Tensor< Index, 1 > get_selection_samples_indices() const
Returns the indices of the samples which will be used for selection.
void unscale_input_variables(const Tensor< Descriptives, 1 > &)
Tensor< Index, 1 > get_target_variables_indices() const
Returns the indices of the target variables.
Index get_selection_samples_number() const
Returns the number of samples in the data set which will be used for selection.
void unscale_target_variables(const Tensor< Descriptives, 1 > &)
Tensor< string, 1 > get_target_variables_names() const
Tensor< Index, 1 > get_input_variables_indices() const
Returns the indices of the input variables.
Tensor< string, 1 > get_input_variables_names() const
Tensor< Descriptives, 1 > scale_input_variables()
TrainingResults perform_training()
virtual ~LevenbergMarquardtAlgorithm()
void set_maximum_selection_failures(const Index &)
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.
const type & get_loss_goal() const
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.
void set_maximum_time(const type &)
void set_loss_goal(const type &)
void set_damping_parameter(const type &)
type maximum_time
Maximum training time. It is used as a stopping criterion.
type damping_parameter_factor
Damping parameter increase/decrease factor.
void set_maximum_epochs_number(const Index &)
const type & get_damping_parameter_factor() const
Returns the damping parameter factor(beta in the User's Guide) for the hessian approximation.
void set_minimum_loss_decrease(const type &)
LevenbergMarquardtAlgorithm()
type minimum_damping_parameter
Minimum Levenberg-Marquardt parameter.
void set_minimum_damping_parameter(const type &)
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.
void set_maximum_damping_parameter(const type &)
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.
Index maximum_selection_failures
void set_damping_parameter_factor(const type &)
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...
void back_propagate_lm(const DataSetBatch &, NeuralNetworkForwardPropagation &, LossIndexBackPropagationLM &) const
virtual string get_error_type() const
Returns a string with the default type of error term, "USER_PERFORMANCE_TERM".
NeuralNetwork * get_neural_network_pointer() const
Returns a pointer to the neural network object associated to the error term.
type calculate_regularization(const Tensor< type, 1 > &) const
const type & get_regularization_weight() const
Returns regularization weight.
DataSet * get_data_set_pointer() const
Returns a pointer to the data set object associated to the error term.
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.
string hardware_use
Hardware use.
Index display_period
Number of iterations between the training showing progress.
This class represents a layer of scaling neurons.
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.
virtual void CloseElement(bool compactMode=false)
If streaming, close the Element.
HALF_CONSTEXPR half abs(half arg)
A loss index composed of several terms, this structure represent the First Order for this function.
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.