19 : neural_network_pointer(nullptr),
20 data_set_pointer(nullptr)
34 : neural_network_pointer(new_neural_network_pointer),
35 data_set_pointer(new_data_set_pointer)
45 delete non_blocking_thread_pool;
46 delete thread_pool_device;
175void LossIndex::set_threads_number(
const int& new_threads_number)
177 if(non_blocking_thread_pool !=
nullptr)
delete this->non_blocking_thread_pool;
178 if(thread_pool_device !=
nullptr)
delete this->thread_pool_device;
180 non_blocking_thread_pool =
new NonBlockingThreadPool(new_threads_number);
181 thread_pool_device =
new ThreadPoolDevice(non_blocking_thread_pool, new_threads_number);
206 delete non_blocking_thread_pool;
207 delete thread_pool_device;
209 const int n = omp_get_max_threads();
211 non_blocking_thread_pool =
new NonBlockingThreadPool(n);
212 thread_pool_device =
new ThreadPoolDevice(non_blocking_thread_pool, n);
223 if(new_regularization_method ==
"L1_NORM")
227 else if(new_regularization_method ==
"L2_NORM")
231 else if(new_regularization_method ==
"NO_REGULARIZATION")
237 ostringstream buffer;
239 buffer <<
"OpenNN Exception: LossIndex class.\n"
240 <<
"void set_regularization_method(const string&) const method.\n"
241 <<
"Unknown regularization method: " << new_regularization_method <<
".";
243 throw logic_error(buffer.str());
297 ostringstream buffer;
301 buffer <<
"OpenNN Exception: LossIndex class.\n"
302 <<
"void check() const.\n"
303 <<
"Pointer to neural network is nullptr.\n";
305 throw logic_error(buffer.str());
312 buffer <<
"OpenNN Exception: LossIndex class.\n"
313 <<
"void check() const method.\n"
314 <<
"Pointer to data set is nullptr.\n";
316 throw logic_error(buffer.str());
321void LossIndex::calculate_errors(
const DataSetBatch& batch,
327 switch(forward_propagation.layers(trainable_layers_number-1)->layer_pointer->get_type())
329 case Layer::Type::Perceptron:
331 back_propagation.errors.device(*thread_pool_device) =
337 case Layer::Type::Probabilistic:
339 back_propagation.errors.device(*thread_pool_device) =
340 static_cast<ProbabilisticLayerForwardPropagation*
>(forward_propagation.layers(trainable_layers_number-1))->activations -
345 case Layer::Type::Recurrent:
347 back_propagation.errors.device(*thread_pool_device) =
348 static_cast<RecurrentLayerForwardPropagation*
>(forward_propagation.layers(trainable_layers_number-1))->activations -
353 case Layer::Type::LongShortTermMemory:
355 back_propagation.errors.device(*thread_pool_device) =
356 static_cast<LongShortTermMemoryLayerForwardPropagation*
>(forward_propagation.layers(trainable_layers_number-1))->activations -
366void LossIndex::calculate_errors_lm(
const DataSetBatch& batch,
367 const NeuralNetworkForwardPropagation & neural_network_forward_propagation,
368 LossIndexBackPropagationLM & loss_index_back_propagation)
const
372 switch(neural_network_forward_propagation.layers(trainable_layers_number-1)->layer_pointer->get_type())
374 case Layer::Type::Perceptron:
376 loss_index_back_propagation.errors.device(*thread_pool_device) =
377 static_cast<PerceptronLayerForwardPropagation*
>(neural_network_forward_propagation.layers(trainable_layers_number-1))->activations -
382 case Layer::Type::Probabilistic:
384 loss_index_back_propagation.errors.device(*thread_pool_device) =
385 static_cast<ProbabilisticLayerForwardPropagation*
>(neural_network_forward_propagation.layers(trainable_layers_number-1))->activations -
390 case Layer::Type::Recurrent:
392 loss_index_back_propagation.errors.device(*thread_pool_device) =
393 static_cast<RecurrentLayerForwardPropagation*
>(neural_network_forward_propagation.layers(trainable_layers_number-1))->activations -
398 case Layer::Type::LongShortTermMemory:
400 loss_index_back_propagation.errors.device(*thread_pool_device) =
401 static_cast<LongShortTermMemoryLayerForwardPropagation*
>(neural_network_forward_propagation.layers(trainable_layers_number-1))->activations -
411void LossIndex::calculate_squared_errors_lm(
const DataSetBatch& ,
412 const NeuralNetworkForwardPropagation& ,
413 LossIndexBackPropagationLM& loss_index_back_propagation_lm)
const
415 loss_index_back_propagation_lm.squared_errors.device(*thread_pool_device) = loss_index_back_propagation_lm.errors.square().sum(rows_sum).sqrt();
419void LossIndex::back_propagate(
const DataSetBatch& batch,
420 NeuralNetworkForwardPropagation& forward_propagation,
421 LossIndexBackPropagation& back_propagation)
const
425 calculate_errors(batch, forward_propagation, back_propagation);
427 calculate_error(batch, forward_propagation, back_propagation);
429 calculate_layers_delta(batch, forward_propagation, back_propagation);
431 calculate_error_gradient(batch, forward_propagation, back_propagation);
435 back_propagation.loss = back_propagation.error;
447 back_propagation.gradient.device(*thread_pool_device) +=
regularization_weight*back_propagation.regularization_gradient;
461 calculate_errors_lm(batch, forward_propagation, loss_index_back_propagation_lm);
463 calculate_squared_errors_lm(batch, forward_propagation, loss_index_back_propagation_lm);
465 calculate_error_lm(batch, forward_propagation, loss_index_back_propagation_lm);
467 calculate_layers_delta_lm(batch, forward_propagation, loss_index_back_propagation_lm);
471 calculate_error_gradient_lm(batch, loss_index_back_propagation_lm);
473 calculate_error_hessian_lm(batch, loss_index_back_propagation_lm);
477 loss_index_back_propagation_lm.loss = loss_index_back_propagation_lm.error;
489 loss_index_back_propagation_lm.gradient.device(*thread_pool_device) +=
regularization_weight*loss_index_back_propagation_lm.regularization_gradient;
493 loss_index_back_propagation_lm.hessian +=
regularization_weight*loss_index_back_propagation_lm.regularization_hessian;
514 loss_index_back_propagation_lm.squared_errors_jacobian.setZero();
516 const Index batch_samples_number = batch.get_samples_number();
522 const Tensor<Index, 1> trainable_layers_parameters_number =
neural_network_pointer->get_trainable_layers_parameters_numbers();
526 if(trainable_layers_pointers(0)->get_type() != Layer::Type::Perceptron && trainable_layers_pointers(0)->get_type() != Layer::Type::Probabilistic)
528 ostringstream buffer;
530 buffer <<
"OpenNN Exception: LossIndex class.\n"
531 <<
"void calculate_squared_errors_jacobian_lm(const DataSetBatch&, NeuralNetworkForwardPropagation&, LossIndexBackPropagationLM&) const method "
532 <<
"Levenberg - Marquardt algorithm can only be used with Perceptron and Probabilistic layers.\n";
534 throw logic_error(buffer.str());
538 trainable_layers_pointers(0)->calculate_squared_errors_Jacobian_lm(batch.inputs_2d,
539 forward_propagation.layers(0),
540 loss_index_back_propagation_lm.neural_network.layers(0));
542 trainable_layers_pointers(0)->insert_squared_errors_Jacobian_lm(loss_index_back_propagation_lm.neural_network.layers(0),
544 loss_index_back_propagation_lm.squared_errors_jacobian);
546 mem_index += trainable_layers_parameters_number(0)*batch_samples_number;
551 for(Index i = 1; i < trainable_layers_number; i++)
553 switch (forward_propagation.layers(i-1)->layer_pointer->get_type())
555 case Layer::Type::Perceptron:
560 trainable_layers_pointers(i)->calculate_squared_errors_Jacobian_lm(perceptron_layer_forward_propagation->activations,
561 forward_propagation.layers(i),
562 loss_index_back_propagation_lm.neural_network.layers(i));
564 trainable_layers_pointers(i)->insert_squared_errors_Jacobian_lm(loss_index_back_propagation_lm.neural_network.layers(i),
566 loss_index_back_propagation_lm.squared_errors_jacobian);
568 mem_index += trainable_layers_parameters_number(i)*batch_samples_number;
572 case Layer::Type::Probabilistic:
574 ostringstream buffer;
576 buffer <<
"OpenNN Exception: LossIndex class.\n"
577 <<
"void calculate_squared_errors_jacobian_lm(const DataSetBatch&, NeuralNetworkForwardPropagation&, LossIndexBackPropagationLM&) const method "
578 <<
"Probabilistic layer can only occupy the last position in the neural network. Please, check network structure.\n";
580 throw logic_error(buffer.str());
585 ostringstream buffer;
587 buffer <<
"OpenNN Exception: LossIndex class.\n"
588 <<
"void calculate_squared_errors_jacobian_lm(const DataSetBatch&, NeuralNetworkForwardPropagation&, LossIndexBackPropagationLM&) const method "
589 <<
"Levenberg - Marquardt algorithm can only be used with Perceptron and Probabilistic layers.\n";
591 throw logic_error(buffer.str());
598void LossIndex::calculate_error_gradient_lm(
const DataSetBatch& batch,
601 loss_index_back_propagation_lm.gradient.device(*thread_pool_device)
602 = loss_index_back_propagation_lm.squared_errors_jacobian.contract(loss_index_back_propagation_lm.squared_errors, AT_B);
610 return "USER_ERROR_TERM";
618 return "USER_ERROR_TERM";
629 case RegularizationMethod::NoRegularization:
630 return "NO_REGULARIZATION";
632 case RegularizationMethod::L1:
635 case RegularizationMethod::L2:
652 case RegularizationMethod::NoRegularization:
return type(0);
654 case RegularizationMethod::L1:
return l1_norm(thread_pool_device, parameters);
656 case RegularizationMethod::L2:
return l2_norm(thread_pool_device, parameters);
673 case RegularizationMethod::L1: l1_norm_gradient(thread_pool_device, parameters, regularization_gradient);
return;
675 case RegularizationMethod::L2: l2_norm_gradient(thread_pool_device, parameters, regularization_gradient);
return;
692 case RegularizationMethod::L1: l1_norm_hessian(thread_pool_device, parameters, regularization_hessian);
return;
694 case RegularizationMethod::L2: l2_norm_hessian(thread_pool_device, parameters, regularization_hessian);
return;
701void LossIndex::calculate_layers_delta(
const DataSetBatch& batch,
707 if(trainable_layers_number == 0)
return;
713 calculate_output_delta(batch,
719 for(Index i =
static_cast<Index
>(trainable_layers_number)-2; i >= 0; i--)
721 trainable_layers_pointers(i)
722 ->calculate_hidden_delta(forward_propagation.layers(i+1),
723 back_propagation.neural_network.layers(i+1),
724 back_propagation.neural_network.layers(i));
729void LossIndex::calculate_layers_delta_lm(
const DataSetBatch& batch,
730 NeuralNetworkForwardPropagation& forward_propagation,
731 LossIndexBackPropagationLM& back_propagation)
const
735 if(trainable_layers_number == 0)
return;
741 calculate_output_delta_lm(batch,
747 for(Index i =
static_cast<Index
>(trainable_layers_number)-2; i >= 0; i--)
749 trainable_layers_pointers(i)
750 ->calculate_hidden_delta_lm(forward_propagation.layers(i+1),
751 back_propagation.neural_network.layers(i+1),
752 back_propagation.neural_network.layers(i));
757void LossIndex::calculate_error_gradient(
const DataSetBatch& batch,
758 const NeuralNetworkForwardPropagation& forward_propagation,
759 LossIndexBackPropagation& back_propagation)
const
769 const Index trainable_layers_number = trainable_layers_pointers.size();
771 const Tensor<Index, 1> trainable_layers_parameters_number
774 if(trainable_layers_pointers(0)->get_type() == Layer::Type::Convolutional)
776 trainable_layers_pointers(0)->calculate_error_gradient(batch.inputs_4d,
777 forward_propagation.layers(0),
778 back_propagation.neural_network.layers(0));
782 trainable_layers_pointers(0)->calculate_error_gradient(batch.inputs_2d,
783 forward_propagation.layers(0),
784 back_propagation.neural_network.layers(0));
789 trainable_layers_pointers(0)->insert_gradient(back_propagation.neural_network.layers(0),
791 back_propagation.gradient);
793 index += trainable_layers_parameters_number(0);
795 for(Index i = 1; i < trainable_layers_number; i++)
797 switch(forward_propagation.layers(i-1)->layer_pointer->get_type())
799 case Layer::Type::Perceptron:
801 PerceptronLayerForwardPropagation* perceptron_layer_forward_propagation
802 =
static_cast<PerceptronLayerForwardPropagation*
>(forward_propagation.layers(i-1));
804 trainable_layers_pointers(i)->
805 calculate_error_gradient(perceptron_layer_forward_propagation->activations,
806 forward_propagation.layers(i),
807 back_propagation.neural_network.layers(i));
811 case Layer::Type::Probabilistic:
813 ProbabilisticLayerForwardPropagation* probabilistic_layer_forward_propagation
814 =
static_cast<ProbabilisticLayerForwardPropagation*
>(forward_propagation.layers(i-1));
816 trainable_layers_pointers(i)->
817 calculate_error_gradient(probabilistic_layer_forward_propagation->activations,
818 forward_propagation.layers(i),
819 back_propagation.neural_network.layers(i));
823 case Layer::Type::Recurrent:
825 RecurrentLayerForwardPropagation* recurrent_layer_forward_propagation
826 =
static_cast<RecurrentLayerForwardPropagation*
>(forward_propagation.layers(i-1));
828 trainable_layers_pointers(i)->
829 calculate_error_gradient(recurrent_layer_forward_propagation->activations,
830 forward_propagation.layers(i),
831 back_propagation.neural_network.layers(i));
835 case Layer::Type::LongShortTermMemory:
837 LongShortTermMemoryLayerForwardPropagation* long_short_term_memory_layer_forward_propagation
838 =
static_cast<LongShortTermMemoryLayerForwardPropagation*
>(forward_propagation.layers(i-1));
840 trainable_layers_pointers(i)->
841 calculate_error_gradient(long_short_term_memory_layer_forward_propagation->activations,
842 forward_propagation.layers(i),
843 back_propagation.neural_network.layers(i));
847 case Layer::Type::Convolutional:
858 case Layer::Type::Pooling:
868 trainable_layers_pointers(i)->insert_gradient(back_propagation.neural_network.layers(i),
870 back_propagation.gradient);
872 index += trainable_layers_parameters_number(i);
883 ostringstream buffer;
885 file_stream.OpenElement(
"LossIndex");
897 ostringstream buffer;
899 buffer <<
"OpenNN Exception: LossIndex class.\n"
900 <<
"void from_XML(const tinyxml2::XMLDocument&) method.\n"
901 <<
"Regularization tag not found.\n";
903 throw logic_error(buffer.str());
906 const string new_regularization_method = root_element->Attribute(
"Type");
914 const type new_regularization_weight =
static_cast<type
>(atof(element->GetText()));
920 catch(
const logic_error& e)
922 cerr << e.what() << endl;
930 ostringstream buffer;
932 file_stream.OpenElement(
"Regularization");
938 case RegularizationMethod::L1:
944 case RegularizationMethod::L2:
950 case RegularizationMethod::NoRegularization:
959 file_stream.OpenElement(
"RegularizationWeight");
964 file_stream.
PushText(buffer.str().c_str());
985 ostringstream buffer;
987 buffer <<
"OpenNN Exception: MeanSquaredError class.\n"
988 <<
"void from_XML(const tinyxml2::XMLDocument&) method.\n"
989 <<
"Mean squared element is nullptr.\n";
991 throw logic_error(buffer.str());
999 const tinyxml2::XMLElement* regularization_element = root_element->FirstChildElement(
"Regularization");
1001 element_clone = regularization_element->DeepClone(®ularization_document);
1003 regularization_document.InsertFirstChild(element_clone);
1005 regularization_from_XML(regularization_document);
1016Tensor<type, 1> LossIndex::calculate_gradient_numerical_differentiation()
1025 batch.fill(samples_indices, input_variables_indices, target_variables_indices);
1033 const Index parameters_number = parameters.size();
1036 Tensor<type, 1> parameters_forward(parameters);
1037 Tensor<type, 1> parameters_backward(parameters);
1040 type error_backward;
1042 Tensor<type, 1> gradient_numerical_differentiation(parameters_number);
1044 for(Index i = 0; i < parameters_number; i++)
1048 parameters_forward(i) += h;
1052 calculate_errors(batch, forward_propagation, back_propagation);
1054 calculate_error(batch, forward_propagation, back_propagation);
1056 error_forward = back_propagation.error;
1058 parameters_forward(i) -= h;
1060 parameters_backward(i) -= h;
1063 calculate_errors(batch, forward_propagation, back_propagation);
1064 calculate_error(batch, forward_propagation, back_propagation);
1065 error_backward = back_propagation.error;
1067 parameters_backward(i) += h;
1069 gradient_numerical_differentiation(i) = (error_forward - error_backward)/(type(2)*h);
1072 return gradient_numerical_differentiation;
1076Tensor<type, 2> LossIndex::calculate_jacobian_numerical_differentiation()
1078 LossIndexBackPropagationLM back_propagation_lm;
1089 batch.fill(samples_indices, input_variables_indices, target_variables_indices);
1093 LossIndexBackPropagation back_propagation(samples_number,
this);
1097 const Index parameters_number = parameters.size();
1099 back_propagation_lm.set(samples_number,
this);
1102 calculate_errors_lm(batch, forward_propagation, back_propagation_lm);
1103 calculate_squared_errors_lm(batch, forward_propagation, back_propagation_lm);
1107 Tensor<type, 1> parameters_forward(parameters);
1108 Tensor<type, 1> parameters_backward(parameters);
1110 Tensor<type, 1> error_terms_forward(parameters_number);
1111 Tensor<type, 1> error_terms_backward(parameters_number);
1113 Tensor<type, 2> jacobian(samples_number,parameters_number);
1115 for(Index j = 0; j < parameters_number; j++)
1119 parameters_backward(j) -= h;
1121 calculate_errors_lm(batch, forward_propagation, back_propagation_lm);
1122 calculate_squared_errors_lm(batch, forward_propagation, back_propagation_lm);
1123 error_terms_backward = back_propagation_lm.squared_errors;
1124 parameters_backward(j) += h;
1126 parameters_forward(j) += h;
1128 calculate_errors_lm(batch, forward_propagation, back_propagation_lm);
1129 calculate_squared_errors_lm(batch, forward_propagation, back_propagation_lm);
1130 error_terms_forward = back_propagation_lm.squared_errors;
1131 parameters_forward(j) -= h;
1133 for(Index i = 0; i < samples_number; i++)
1135 jacobian(i,j) = (error_terms_forward(i) - error_terms_backward(i))/(
static_cast<type
>(2.0)*h);
1143type LossIndex::calculate_eta()
const
1145 const Index precision_digits = 6;
1147 return pow(
static_cast<type
>(10.0),
static_cast<type
>(-1.0*precision_digits));
1156 const type eta = calculate_eta();
1158 return sqrt(eta)*(
static_cast<type
>(1.0) +
abs(x));
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< Index, 1 > get_training_samples_indices() const
Returns the indices of the samples which will be used for training.
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.
Tensor< Index, 1 > get_input_variables_indices() const
Returns the indices of the input variables.
This abstract class represents the concept of loss index composed of an error term and a regularizati...
type calculate_h(const type &) const
void calculate_regularization_hessian(const Tensor< type, 1 > &, Tensor< type, 2 > &) const
DataSet * data_set_pointer
Pointer to a data set object.
void set_regularization_method(const RegularizationMethod &)
NeuralNetwork * neural_network_pointer
Pointer to a neural network object.
virtual void set_data_set_pointer(DataSet *)
Sets a new data set on which the error term is to be measured.
const bool & get_display() const
bool has_selection() const
Returns true if there are selection samples and false otherwise.
void from_XML(const tinyxml2::XMLDocument &)
void set_default()
Sets the members of the error term to their default values:
void calculate_squared_errors_jacobian_lm(const DataSetBatch &, NeuralNetworkForwardPropagation &, LossIndexBackPropagationLM &) const
bool display
Display messages to screen.
bool has_data_set() const
void back_propagate_lm(const DataSetBatch &, NeuralNetworkForwardPropagation &, LossIndexBackPropagationLM &) const
type regularization_weight
Regularization weight value.
bool has_neural_network() const
virtual string get_error_type() const
Returns a string with the default type of error term, "USER_PERFORMANCE_TERM".
RegularizationMethod get_regularization_method() const
Returns the regularization method.
virtual ~LossIndex()
Destructor.
type calculate_regularization(const Tensor< type, 1 > &) const
const type & get_regularization_weight() const
Returns regularization weight.
void set_neural_network_pointer(NeuralNetwork *)
string write_regularization_method() const
RegularizationMethod regularization_method
Pointer to a regularization method object.
void set_display(const bool &)
RegularizationMethod
Enumeration of available regularization methods.
virtual void write_XML(tinyxml2::XMLPrinter &) const
void calculate_regularization_gradient(const Tensor< type, 1 > &, Tensor< type, 1 > &) const
virtual string get_error_type_text() const
Returns a string with the default type of error term in text format, "USER_PERFORMANCE_TERM".
void set_regularization_weight(const type &)
Tensor< Layer *, 1 > get_trainable_layers_pointers() const
Returns a pointer to the trainable layers object composing this neural network object.
void forward_propagate(const DataSetBatch &, NeuralNetworkForwardPropagation &) const
Calculate forward propagation in neural network.
Tensor< type, 1 > get_parameters() const
void PushText(const char *text, bool cdata=false)
Add a text node.
void PushAttribute(const char *name, const char *value)
If streaming, add an attribute to an open element.
virtual void CloseElement(bool compactMode=false)
If streaming, close the Element.
HALF_CONSTEXPR half abs(half arg)
virtual ~LossIndexBackPropagation()
Destructor.
A loss index composed of several terms, this structure represent the First Order for this function.