OpenNN  2.2
Open Neural Networks Library
sum_squared_error.cpp
1 /****************************************************************************************************************/
2 /* */
3 /* OpenNN: Open Neural Networks Library */
4 /* www.artelnics.com/opennn */
5 /* */
6 /* S U M S Q U A R E D E R R O R C L A S S */
7 /* */
8 /* Roberto Lopez */
9 /* Artelnics - Making intelligent use of data */
11 /* */
12 /****************************************************************************************************************/
13 
14 // OpenNN includes
15 
16 #include "sum_squared_error.h"
17 
18 
19 namespace OpenNN
20 {
21 
22 // DEFAULT CONSTRUCTOR
23 
27 
29 {
30 }
31 
32 
33 // NEURAL NETWORK CONSTRUCTOR
34 
39 
40 SumSquaredError::SumSquaredError(NeuralNetwork* new_neural_network_pointer)
41 : PerformanceTerm(new_neural_network_pointer)
42 {
43 }
44 
45 
46 // DATA SET CONSTRUCTOR
47 
52 
54 : PerformanceTerm(new_data_set_pointer)
55 {
56 }
57 
58 
59 // NEURAL NETWORK AND DATA SET CONSTRUCTOR
60 
66 
67 SumSquaredError::SumSquaredError(NeuralNetwork* new_neural_network_pointer, DataSet* new_data_set_pointer)
68  : PerformanceTerm(new_neural_network_pointer, new_data_set_pointer)
69 {
70 }
71 
72 
73 // XML CONSTRUCTOR
74 
79 
80 SumSquaredError::SumSquaredError(const tinyxml2::XMLDocument& sum_squared_error_document)
81  : PerformanceTerm(sum_squared_error_document)
82 {
83 }
84 
85 
86 
87 // COPY CONSTRUCTOR
88 
93 
95  : PerformanceTerm(new_sum_squared_error)
96 {
97 
98 }
99 
100 
101 // DESTRUCTOR
102 
104 
106 {
107 }
108 
109 
110 // METHODS
111 
112 // void check(void) const method
113 
117 
118 void SumSquaredError::check(void) const
119 {
120  std::ostringstream buffer;
121 
122  // Neural network stuff
123 
125  {
126  buffer << "OpenNN Exception: SumSquaredError class.\n"
127  << "void check(void) const method.\n"
128  << "Pointer to neural network is NULL.\n";
129 
130  throw std::logic_error(buffer.str());
131  }
132 
133  const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
134 
135  if(!multilayer_perceptron_pointer)
136  {
137  buffer << "OpenNN Exception: SumSquaredError class.\n"
138  << "void check(void) const method.\n"
139  << "Pointer to multilayer perceptron is NULL.\n";
140 
141  throw std::logic_error(buffer.str());
142  }
143 
144  const size_t inputs_number = multilayer_perceptron_pointer->get_inputs_number();
145  const size_t outputs_number = multilayer_perceptron_pointer->get_outputs_number();
146 
147  // Data set stuff
148 
149  if(!data_set_pointer)
150  {
151  buffer << "OpenNN Exception: SumSquaredError class.\n"
152  << "void check(void) const method.\n"
153  << "Pointer to data set is NULL.\n";
154 
155  throw std::logic_error(buffer.str());
156  }
157 
158  // Sum squared error stuff
159 
160  const Variables& variables = data_set_pointer->get_variables();
161 
162  const size_t data_set_inputs_number = variables.count_inputs_number();
163  const size_t targets_number = variables.count_targets_number();
164 
165  if(data_set_inputs_number != inputs_number)
166  {
167  buffer << "OpenNN Exception: SumSquaredError class.\n"
168  << "void check(void) const method.\n"
169  << "Number of inputs in neural network must be equal to number of inputs in data set.\n";
170 
171  throw std::logic_error(buffer.str());
172  }
173 
174  if(outputs_number != targets_number)
175  {
176  buffer << "OpenNN Exception: SumSquaredError class.\n"
177  << "void check(void) const method.\n"
178  << "Number of outputs in neural network must be equal to number of targets in data set.\n";
179 
180  throw std::logic_error(buffer.str());
181  }
182 }
183 
184 
185 // double calculate_performance(void) const method
186 
188 
190 {
191  #ifndef NDEBUG
192 
193  check();
194 
195  #endif
196 
197  // Neural network stuff
198 
199  const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
200 
201  const size_t inputs_number = multilayer_perceptron_pointer->get_inputs_number();
202  const size_t outputs_number = multilayer_perceptron_pointer->get_outputs_number();
203 
204  // Data set stuff
205 
206  const Instances& instances = data_set_pointer->get_instances();
207 
208  const size_t training_instances_number = instances.count_training_instances_number();
209 
210  const Vector<size_t> training_indices = instances.arrange_training_indices();
211 
212  size_t training_index;
213 
214  const Variables& variables = data_set_pointer->get_variables();
215 
216  const Vector<size_t> inputs_indices = variables.arrange_inputs_indices();
217  const Vector<size_t> targets_indices = variables.arrange_targets_indices();
218 
219  const MissingValues& missing_values = data_set_pointer->get_missing_values();
220 
221  // Sum squared error stuff
222 
223  Vector<double> inputs(inputs_number);
224  Vector<double> outputs(outputs_number);
225  Vector<double> targets(outputs_number);
226 
227  int i = 0;
228  double sum_squared_error = 0.0;
229 
230  #pragma omp parallel for private(i, training_index, inputs, outputs, targets) reduction(+ : sum_squared_error)
231 
232  for(i = 0; i < (int)training_instances_number; i++)
233  {
234  training_index = training_indices[i];
235 
236  if(missing_values.has_missing_values(training_index))
237  {
238  continue;
239  }
240 
241  // Input vector
242 
243  inputs = data_set_pointer->get_instance(training_index, inputs_indices);
244 
245  // Target vector
246 
247  targets = data_set_pointer->get_instance(training_index, targets_indices);
248 
249  // Output vector
250 
251  outputs = multilayer_perceptron_pointer->calculate_outputs(inputs);
252 
253  // Sum squared error
254 
255  sum_squared_error += outputs.calculate_sum_squared_error(targets);
256  }
257 
258  return(sum_squared_error);
259 }
260 
261 
262 // double calculate_performance(const Vector<double>&) const method
263 
267 
269 {
270  // Neural network stuff
271 
272  #ifndef NDEBUG
273 
274  check();
275 
276  #endif
277 
278  // Sum squared error stuff
279 
280  #ifndef NDEBUG
281 
282  std::ostringstream buffer;
283 
284  const size_t size = parameters.size();
285 
286  const size_t parameters_number = neural_network_pointer->count_parameters_number();
287 
288  if(size != parameters_number)
289  {
290  buffer << "OpenNN Exception: SumSquaredError class." << std::endl
291  << "double calculate_performance(const Vector<double>&) const method." << std::endl
292  << "Size (" << size << ") must be equal to number of parameters (" << parameters_number << ")." << std::endl;
293 
294  throw std::logic_error(buffer.str());
295  }
296 
297  #endif
298 
299  // Neural network stuff
300 
301  const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
302 
303  const size_t inputs_number = multilayer_perceptron_pointer->get_inputs_number();
304  const size_t outputs_number = multilayer_perceptron_pointer->get_outputs_number();
305 
306  // Data set stuff
307 
308  const Instances& instances = data_set_pointer->get_instances();
309 
310  const size_t training_instances_number = instances.count_training_instances_number();
311 
312  const Vector<size_t> training_indices = instances.arrange_training_indices();
313 
314  size_t training_index;
315 
316  const Variables& variables = data_set_pointer->get_variables();
317 
318  const Vector<size_t> inputs_indices = variables.arrange_inputs_indices();
319  const Vector<size_t> targets_indices = variables.arrange_targets_indices();
320 
321  const MissingValues& missing_values = data_set_pointer->get_missing_values();
322 
323  // Sum squared error stuff
324 
325  Vector<double> inputs(inputs_number);
326  Vector<double> outputs(outputs_number);
327  Vector<double> targets(outputs_number);
328 
329  int i = 0;
330 
331  double sum_squared_error = 0.0;
332 
333  #pragma omp parallel for private(i, training_index, inputs, outputs, targets) reduction(+ : sum_squared_error)
334 
335  for(i = 0; i < (int)training_instances_number; i++)
336  {
337  training_index = training_indices[i];
338 
339  if(missing_values.has_missing_values(training_index))
340  {
341  continue;
342  }
343 
344  // Input vector
345 
346  inputs = data_set_pointer->get_instance(training_index, inputs_indices);
347 
348  // Output vector
349 
350  outputs = multilayer_perceptron_pointer->calculate_outputs(inputs, parameters);
351 
352  // Target vector
353 
354  targets = data_set_pointer->get_instance(training_index, targets_indices);
355 
356  // Sum squared error
357 
358  sum_squared_error += outputs.calculate_sum_squared_error(targets);
359  }
360 
361  return(sum_squared_error);
362 }
363 
364 
365 // double calculate_generalization_performance(void) const method
366 
368 
370 {
371  #ifndef NDEBUG
372 
373  check();
374 
375  #endif
376 
377  // Neural network stuff
378 
379  const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
380 
381  const size_t inputs_number = multilayer_perceptron_pointer->get_inputs_number();
382  const size_t outputs_number = multilayer_perceptron_pointer->get_outputs_number();
383 
384  // Data set stuff
385 
386  const Instances& instances = data_set_pointer->get_instances();
387  const size_t generalization_instances_number = instances.count_generalization_instances_number();
388 
389  const Vector<size_t> generalization_indices = instances.arrange_generalization_indices();
390 
391  size_t generalization_index;
392 
393  const Variables& variables = data_set_pointer->get_variables();
394 
395  const Vector<size_t> inputs_indices = variables.arrange_inputs_indices();
396  const Vector<size_t> targets_indices = variables.arrange_targets_indices();
397 
398  const MissingValues& missing_values = data_set_pointer->get_missing_values();
399 
400  // Sum squared error stuff
401 
402  Vector<double> inputs(inputs_number);
403  Vector<double> outputs(outputs_number);
404  Vector<double> targets(outputs_number);
405 
406  double generalization_performance = 0.0;
407 
408  int i = 0;
409 
410  #pragma omp parallel for private(i, generalization_index, inputs, outputs, targets) reduction(+ : generalization_performance)
411 
412  for(i = 0; i < (int)generalization_instances_number; i++)
413  {
414  generalization_index = generalization_indices[i];
415 
416  if(missing_values.has_missing_values(generalization_index))
417  {
418  continue;
419  }
420 
421  // Input vector
422 
423  inputs = data_set_pointer->get_instance(generalization_index, inputs_indices);
424 
425  // Output vector
426 
427  outputs = multilayer_perceptron_pointer->calculate_outputs(inputs);
428 
429  // Target vector
430 
431  targets = data_set_pointer->get_instance(generalization_index, targets_indices);
432 
433  // Sum of squares error
434 
435  generalization_performance += outputs.calculate_sum_squared_error(targets);
436  }
437 
438  return(generalization_performance);
439 }
440 
441 
442 // Vector<double> calculate_gradient(void) const method
443 
446 
448 {
449  #ifndef NDEBUG
450 
451  check();
452 
453  #endif
454 
455  // Neural network stuff
456 
457  const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
458 
459  // Neural network stuff
460 
461  const bool has_conditions_layer = neural_network_pointer->has_conditions_layer();
462 
463  const ConditionsLayer* conditions_layer_pointer = has_conditions_layer ? neural_network_pointer->get_conditions_layer_pointer() : NULL;
464 
465  const size_t inputs_number = multilayer_perceptron_pointer->get_inputs_number();
466  const size_t outputs_number = multilayer_perceptron_pointer->get_outputs_number();
467 
468  const size_t layers_number = multilayer_perceptron_pointer->get_layers_number();
469 
470  const size_t neural_parameters_number = multilayer_perceptron_pointer->count_parameters_number();
471 
472  Vector< Vector< Vector<double> > > first_order_forward_propagation(2);
473 
474  Vector<double> particular_solution;
475  Vector<double> homogeneous_solution;
476 
477  // Data set stuff
478 
479  const Instances& instances = data_set_pointer->get_instances();
480 
481  const size_t training_instances_number = instances.count_training_instances_number();
482 
483  const Vector<size_t> training_indices = instances.arrange_training_indices();
484 
485  size_t training_index;
486 
487  const Variables& variables = data_set_pointer->get_variables();
488 
489  const Vector<size_t> inputs_indices = variables.arrange_inputs_indices();
490  const Vector<size_t> targets_indices = variables.arrange_targets_indices();
491 
492  Vector<double> inputs(inputs_number);
493  Vector<double> targets(outputs_number);
494 
495  const MissingValues& missing_values = data_set_pointer->get_missing_values();
496 
497  // Sum squared error stuff
498 
499  Vector<double> output_gradient(outputs_number);
500 
501  Vector< Matrix<double> > layers_combination_parameters_Jacobian;
502 
503  Vector< Vector<double> > layers_inputs(layers_number);
504  Vector< Vector<double> > layers_delta;
505 
506  Vector<double> point_gradient(neural_parameters_number, 0.0);
507 
508  Vector<double> gradient(neural_parameters_number, 0.0);
509 
510  int i;
511 
512  #pragma omp parallel for private(i, training_index, inputs, targets, first_order_forward_propagation, layers_inputs, layers_combination_parameters_Jacobian,\
513  output_gradient, layers_delta, particular_solution, homogeneous_solution, point_gradient)
514 
515  for(i = 0; i < (int)training_instances_number; i++)
516  {
517  training_index = training_indices[i];
518 
519  if(missing_values.has_missing_values(training_index))
520  {
521  continue;
522  }
523 
524  inputs = data_set_pointer->get_instance(training_index, inputs_indices);
525 
526  targets = data_set_pointer->get_instance(training_index, targets_indices);
527 
528  first_order_forward_propagation = multilayer_perceptron_pointer->calculate_first_order_forward_propagation(inputs);
529 
530  const Vector< Vector<double> >& layers_activation = first_order_forward_propagation[0];
531  const Vector< Vector<double> >& layers_activation_derivative = first_order_forward_propagation[1];
532 
533  layers_inputs = multilayer_perceptron_pointer->arrange_layers_input(inputs, layers_activation);
534 
535  layers_combination_parameters_Jacobian = multilayer_perceptron_pointer->calculate_layers_combination_parameters_Jacobian(layers_inputs);
536 
537  if(!has_conditions_layer)
538  {
539  output_gradient = (layers_activation[layers_number-1]-targets)*2.0;
540 
541  layers_delta = calculate_layers_delta(layers_activation_derivative, output_gradient);
542  }
543  else
544  {
545  particular_solution = conditions_layer_pointer->calculate_particular_solution(inputs);
546  homogeneous_solution = conditions_layer_pointer->calculate_homogeneous_solution(inputs);
547 
548  output_gradient = (particular_solution+homogeneous_solution*layers_activation[layers_number-1] - targets)*2.0;
549 
550  layers_delta = calculate_layers_delta(layers_activation_derivative, homogeneous_solution, output_gradient);
551  }
552 
553  point_gradient = calculate_point_gradient(layers_combination_parameters_Jacobian, layers_delta);
554 
555  #pragma omp critical
556  gradient += point_gradient;
557  }
558 
559  return(gradient);
560 }
561 
562 
563 // Matrix<double> calculate_Hessian(void) const method
564 
567 
569 {
570  #ifndef NDEBUG
571 
572  check();
573 
574  #endif
575 
576  // Neural network stuff
577 
578  const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
579 
580  const bool has_conditions_layer = neural_network_pointer->has_conditions_layer();
581 
582  const ConditionsLayer* conditions_layer_pointer = has_conditions_layer ? neural_network_pointer->get_conditions_layer_pointer() : NULL;
583 
584  const size_t inputs_number = multilayer_perceptron_pointer->get_inputs_number();
585  const size_t outputs_number = multilayer_perceptron_pointer->get_outputs_number();
586 
587  const size_t layers_number = multilayer_perceptron_pointer->get_layers_number();
588 
589  const size_t parameters_number = multilayer_perceptron_pointer->count_parameters_number();
590 
591  const Vector<size_t> layers_perceptrons_number = multilayer_perceptron_pointer->arrange_layers_perceptrons_numbers();
592 
593  Vector< Vector< Vector<double> > > second_order_forward_propagation(3);
594 
595  Vector < Vector< Vector<double> > > perceptrons_combination_parameters_gradient(layers_number);
596  Matrix < Matrix<double> > interlayers_combination_combination_Jacobian;
597 
598  Vector<double> particular_solution;
599  Vector<double> homogeneous_solution;
600 
601  // Data set stuff
602 
603  const Instances& instances = data_set_pointer->get_instances();
604 
605  const size_t training_instances_number = instances.count_training_instances_number();
606 
607  const Vector<size_t> training_indices = instances.arrange_training_indices();
608 
609  size_t training_index;
610 
611  const MissingValues& missing_values = data_set_pointer->get_missing_values();
612 
613  const Variables& variables = data_set_pointer->get_variables();
614 
615  const Vector<size_t> inputs_indices = variables.arrange_inputs_indices();
616  const Vector<size_t> targets_indices = variables.arrange_targets_indices();
617 
618  Vector<double> inputs(inputs_number);
619  Vector<double> targets(outputs_number);
620 
621  // Sum squared error stuff
622 
623  Vector< Vector<double> > layers_delta(layers_number);
624  Matrix< Matrix<double> > interlayers_Delta(layers_number, layers_number);
625 
626  Vector<double> output_gradient(outputs_number);
627  Matrix<double> output_Hessian(outputs_number, outputs_number);
628 
629  Matrix<double> Hessian(parameters_number, parameters_number, 0.0);
630 
631  for(size_t i = 0; i < training_instances_number; i++)
632  {
633  training_index = training_indices[i];
634 
635  if(missing_values.has_missing_values(training_index))
636  {
637  continue;
638  }
639 
640  inputs = data_set_pointer->get_instance(training_index, inputs_indices);
641 
642  targets = data_set_pointer->get_instance(training_index, targets_indices);
643 
644  second_order_forward_propagation = multilayer_perceptron_pointer->calculate_second_order_forward_propagation(inputs);
645 
646  Vector< Vector<double> >& layers_activation = second_order_forward_propagation[0];
647  Vector< Vector<double> >& layers_activation_derivative = second_order_forward_propagation[1];
648  Vector< Vector<double> >& layers_activation_second_derivative = second_order_forward_propagation[2];
649 
650  Vector< Vector<double> > layers_inputs(layers_number);
651 
652  layers_inputs[0] = inputs;
653 
654  for(size_t j = 1; j < layers_number; j++)
655  {
656  layers_inputs[j] = layers_activation[j-1];
657  }
658 
659  perceptrons_combination_parameters_gradient = multilayer_perceptron_pointer->calculate_perceptrons_combination_parameters_gradient(layers_inputs);
660 
661  interlayers_combination_combination_Jacobian = multilayer_perceptron_pointer->calculate_interlayers_combination_combination_Jacobian(inputs);
662 
663  if(!has_conditions_layer)
664  {
665  output_gradient = (layers_activation[layers_number-1] - targets)*2.0;
666  output_Hessian.initialize_diagonal(2.0);
667 
668  layers_delta = calculate_layers_delta(layers_activation_derivative, output_gradient);
669  interlayers_Delta = calculate_interlayers_Delta(layers_activation_derivative, layers_activation_second_derivative, interlayers_combination_combination_Jacobian, output_gradient, output_Hessian, layers_delta);
670  }
671  else
672  {
673  particular_solution = conditions_layer_pointer->calculate_particular_solution(inputs);
674  homogeneous_solution = conditions_layer_pointer->calculate_homogeneous_solution(inputs);
675 
676  output_gradient = (particular_solution+homogeneous_solution*layers_activation[layers_number-1] - targets)*2.0;
677 
678  layers_delta = calculate_layers_delta(layers_activation_derivative, homogeneous_solution, output_gradient);
679  }
680 
681  Hessian += calculate_point_Hessian(layers_activation_derivative, perceptrons_combination_parameters_gradient, interlayers_combination_combination_Jacobian, layers_delta, interlayers_Delta);
682  }
683 
684  return(Hessian);
685 }
686 
687 
688 // Vector<double> calculate_terms(void) const method
689 
691 
693 {
694  // Control sentence (if debug)
695 
696  #ifndef NDEBUG
697 
698  check();
699 
700  #endif
701 
702  // Neural network stuff
703 
704  const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
705 
706  const size_t inputs_number = multilayer_perceptron_pointer->get_inputs_number();
707  const size_t outputs_number = multilayer_perceptron_pointer->get_outputs_number();
708 
709  // Data set stuff
710 
711  const Instances& instances = data_set_pointer->get_instances();
712 
713  const size_t training_instances_number = instances.count_training_instances_number();
714 
715  const Vector<size_t> training_indices = instances.arrange_training_indices();
716 
717  size_t training_index;
718 
719  const Variables& variables = data_set_pointer->get_variables();
720 
721  const Vector<size_t> inputs_indices = variables.arrange_inputs_indices();
722  const Vector<size_t> targets_indices = variables.arrange_targets_indices();
723 
724  const MissingValues& missing_values = data_set_pointer->get_missing_values();
725 
726  // Performance functional stuff
727 
728  Vector<double> performance_terms(training_instances_number);
729 
730  Vector<double> inputs(inputs_number);
731  Vector<double> outputs(outputs_number);
732  Vector<double> targets(outputs_number);
733 
734  int i = 0;
735 
736  #pragma omp parallel for private(i, training_index, inputs, outputs, targets)
737 
738  for(i = 0; i < (int)training_instances_number; i++)
739  {
740  training_index = training_indices[i];
741 
742  if(missing_values.has_missing_values(training_index))
743  {
744  continue;
745  }
746 
747  // Input vector
748 
749  inputs = data_set_pointer->get_instance(training_index, inputs_indices);
750 
751  // Output vector
752 
753  outputs = multilayer_perceptron_pointer->calculate_outputs(inputs);
754 
755  // Target vector
756 
757  targets = data_set_pointer->get_instance(training_index, targets_indices);
758 
759  // Error
760 
761  performance_terms[i] = outputs.calculate_distance(targets);
762  }
763 
764  return(performance_terms);
765 }
766 
767 
768 // Vector<double> calculate_terms(const Vector<double>&) const method
769 
772 
774 {
775  // Control sentence (if debug)
776 
777  #ifndef NDEBUG
778 
779  check();
780 
781  #endif
782 
783 
784  #ifndef NDEBUG
785 
786  const size_t size = parameters.size();
787 
788  const size_t parameters_number = neural_network_pointer->count_parameters_number();
789 
790  if(size != parameters_number)
791  {
792  std::ostringstream buffer;
793 
794  buffer << "OpenNN Exception: SumSquaredError class." << std::endl
795  << "double calculate_terms(const Vector<double>&) const method." << std::endl
796  << "Size (" << size << ") must be equal to number of neural network parameters (" << parameters_number << ")." << std::endl;
797 
798  throw std::logic_error(buffer.str());
799  }
800 
801  #endif
802 
803  NeuralNetwork neural_network_copy(*neural_network_pointer);
804 
805  neural_network_copy.set_parameters(parameters);
806 
807  SumSquaredError sum_squared_error_copy(*this);
808 
809  sum_squared_error_copy.set_neural_network_pointer(&neural_network_copy);
810 
811  return(sum_squared_error_copy.calculate_terms());
812 }
813 
814 
815 // Matrix<double> calculate_terms_Jacobian(void) const method
816 
820 
822 {
823  #ifndef NDEBUG
824 
825  check();
826 
827  #endif
828 
829  const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
830 
831  const size_t inputs_number = multilayer_perceptron_pointer->get_inputs_number();
832  const size_t outputs_number = multilayer_perceptron_pointer->get_outputs_number();
833  const size_t layers_number = multilayer_perceptron_pointer->get_layers_number();
834 
835  const size_t neural_parameters_number = multilayer_perceptron_pointer->count_parameters_number();
836 
837  Vector< Vector< Vector<double> > > first_order_forward_propagation(2);
838 
839  Vector< Vector<double> > layers_inputs(layers_number);
840  Vector< Matrix<double> > layers_combination_parameters_Jacobian(layers_number);
841 
842  Vector<double> particular_solution;
843  Vector<double> homogeneous_solution;
844 
845  const bool has_conditions_layer = neural_network_pointer->has_conditions_layer();
846 
847  const ConditionsLayer* conditions_layer_pointer = has_conditions_layer ? neural_network_pointer->get_conditions_layer_pointer() : NULL;
848 
849  // Data set
850 
851  const Instances& instances = data_set_pointer->get_instances();
852 
853  const size_t training_instances_number = instances.count_training_instances_number();
854 
855  const Vector<size_t> training_indices = instances.arrange_training_indices();
856 
857  size_t training_index;
858 
859  const Variables& variables = data_set_pointer->get_variables();
860 
861  const Vector<size_t> inputs_indices = variables.arrange_inputs_indices();
862  const Vector<size_t> targets_indices = variables.arrange_targets_indices();
863 
864  const MissingValues missing_values = data_set_pointer->get_missing_values();
865 
866  Vector<double> inputs(inputs_number);
867  Vector<double> targets(outputs_number);
868 
869  // Performance functional
870 
871  Vector<double> term(outputs_number);
872  double term_norm;
873 
874  Vector<double> output_gradient(outputs_number);
875 
876  Vector< Vector<double> > layers_delta(layers_number);
877  Vector<double> point_gradient(neural_parameters_number);
878 
879  Matrix<double> terms_Jacobian(training_instances_number, neural_parameters_number);
880 
881  // Main loop
882 
883  int i = 0;
884 
885  #pragma omp parallel for private(i, training_index, inputs, targets, first_order_forward_propagation, layers_inputs, \
886  layers_combination_parameters_Jacobian, term, term_norm, output_gradient, layers_delta, particular_solution, homogeneous_solution, point_gradient)
887 
888  for(i = 0; i < (int)training_instances_number; i++)
889  {
890  training_index = training_indices[i];
891 
892  if(missing_values.has_missing_values(training_index))
893  {
894  continue;
895  }
896 
897  inputs = data_set_pointer->get_instance(training_index, inputs_indices);
898 
899  targets = data_set_pointer->get_instance(training_index, targets_indices);
900 
901  first_order_forward_propagation = multilayer_perceptron_pointer->calculate_first_order_forward_propagation(inputs);
902 
903  layers_inputs = multilayer_perceptron_pointer->arrange_layers_input(inputs, first_order_forward_propagation);
904 
905  // const Vector< Vector<double> >& layers_activation_derivative = first_order_forward_propagation[1];
906 
907  layers_combination_parameters_Jacobian = multilayer_perceptron_pointer->calculate_layers_combination_parameters_Jacobian(layers_inputs);
908 
909  if(!has_conditions_layer)
910  {
911  //const Vector<double>& outputs = first_order_forward_propagation[0][layers_number-1];
912 
913  term = first_order_forward_propagation[0][layers_number-1] - targets;
914  term_norm = term.calculate_norm();
915 
916  if(term_norm == 0.0)
917  {
918  output_gradient.set(outputs_number, 0.0);
919  }
920  else
921  {
922  output_gradient = term/term_norm;
923  }
924 
925  layers_delta = calculate_layers_delta(first_order_forward_propagation[1], output_gradient);
926  }
927  else
928  {
929 
930  particular_solution = conditions_layer_pointer->calculate_particular_solution(inputs);
931  homogeneous_solution = conditions_layer_pointer->calculate_homogeneous_solution(inputs);
932 
933  //const Vector<double>& output_layer_activation = first_order_forward_propagation[0][layers_number-1];
934 
935  term = (particular_solution+homogeneous_solution*first_order_forward_propagation[0][layers_number-1] - targets);
936  term_norm = term.calculate_norm();
937 
938  if(term_norm == 0.0)
939  {
940  output_gradient.set(outputs_number, 0.0);
941  }
942  else
943  {
944  output_gradient = term/term_norm;
945  }
946 
947  layers_delta = calculate_layers_delta(first_order_forward_propagation[1], homogeneous_solution, output_gradient);
948  }
949 
950  point_gradient = calculate_point_gradient(layers_combination_parameters_Jacobian, layers_delta);
951 
952  terms_Jacobian.set_row(i, point_gradient);
953  }
954 
955  return(terms_Jacobian);
956 }
957 
958 
959 // FirstOrderTerms calculate_first_order_terms(void) const method
960 
963 
965 {
966  FirstOrderTerms first_order_terms;
967 
968  first_order_terms.terms = calculate_terms();
969  first_order_terms.Jacobian = calculate_terms_Jacobian();
970 
971  return(first_order_terms);
972 }
973 
974 
975 // Vector<double> calculate_squared_errors(void) const method
976 
978 
980 {
981  // Control sentence (if debug)
982 
983  #ifndef NDEBUG
984 
985  check();
986 
987  #endif
988 
989  // Neural network stuff
990 
991  const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
992 
993  const size_t inputs_number = multilayer_perceptron_pointer->get_inputs_number();
994  const size_t outputs_number = multilayer_perceptron_pointer->get_outputs_number();
995 
996  // Data set stuff
997 
998  const Instances& instances = data_set_pointer->get_instances();
999 
1000  const size_t training_instances_number = instances.count_training_instances_number();
1001 
1002  const Vector<size_t> training_indices = instances.arrange_training_indices();
1003 
1004  size_t training_index;
1005 
1006  const Variables& variables = data_set_pointer->get_variables();
1007 
1008  const Vector<size_t> inputs_indices = variables.arrange_inputs_indices();
1009  const Vector<size_t> targets_indices = variables.arrange_targets_indices();
1010 
1011  const MissingValues missing_values = data_set_pointer->get_missing_values();
1012 
1013  // Performance functional
1014 
1015  Vector<double> squared_errors(training_instances_number);
1016 
1017  Vector<double> inputs(inputs_number);
1018  Vector<double> outputs(outputs_number);
1019  Vector<double> targets(outputs_number);
1020 
1021  int i = 0;
1022 
1023  #pragma omp parallel for private(i, training_index, inputs, outputs, targets)
1024 
1025  for(i = 0; i < (int)training_instances_number; i++)
1026  {
1027  training_index = training_indices[i];
1028 
1029  if(missing_values.has_missing_values(training_index))
1030  {
1031  continue;
1032  }
1033 
1034  // Input vector
1035 
1036  inputs = data_set_pointer->get_instance(training_index, inputs_indices);
1037 
1038  // Output vector
1039 
1040  outputs = multilayer_perceptron_pointer->calculate_outputs(inputs);
1041 
1042  // Target vector
1043 
1044  targets = data_set_pointer->get_instance(training_index, targets_indices);
1045 
1046  // Error
1047 
1048  squared_errors[i] = outputs.calculate_sum_squared_error(targets);
1049  }
1050 
1051  return(squared_errors);
1052 }
1053 
1054 
1055 // Vector<double> calculate_gradient(const Vector<double>&) const method
1056 
1058 
1060 {
1061  Vector<double> gradient;
1062 
1063  return(gradient);
1064 }
1065 
1066 
1067 // Matrix<double> calculate_Hessian(const Vector<double>&) const metod
1068 
1070 
1072 {
1073  Matrix<double> Hessian;
1074 
1075  return(Hessian);
1076 }
1077 
1078 
1079 // std::string write_performance_term_type(void) const method
1080 
1082 
1084 {
1085  return("SUM_SQUARED_ERROR");
1086 }
1087 
1088 
1089 // tinyxml2::XMLDocument* to_XML(void) method method
1090 
1092 
1093 tinyxml2::XMLDocument* SumSquaredError::to_XML(void) const
1094 {
1095  std::ostringstream buffer;
1096 
1097  tinyxml2::XMLDocument* document = new tinyxml2::XMLDocument;
1098 
1099  // Sum squared error
1100 
1101  tinyxml2::XMLElement* root_element = document->NewElement("SumSquaredError");
1102 
1103  document->InsertFirstChild(root_element);
1104 
1105  // Display
1106 
1107  {
1108  tinyxml2::XMLElement* display_element = document->NewElement("Display");
1109  root_element->LinkEndChild(display_element);
1110 
1111  buffer.str("");
1112  buffer << display;
1113 
1114  tinyxml2::XMLText* display_text = document->NewText(buffer.str().c_str());
1115  display_element->LinkEndChild(display_text);
1116  }
1117 
1118  return(document);
1119 }
1120 
1121 
1122 // void load(const tinyxml2::XMLDocument&) method
1123 
1126 
1127 void SumSquaredError::from_XML(const tinyxml2::XMLDocument& document)
1128 {
1129  const tinyxml2::XMLElement* root_element = document.FirstChildElement("SumSquaredError");
1130 
1131  if(!root_element)
1132  {
1133  std::ostringstream buffer;
1134 
1135  buffer << "OpenNN Exception: SumSquaredError class.\n"
1136  << "void from_XML(const tinyxml2::XMLDocument&) method.\n"
1137  << "Sum squared error element is NULL.\n";
1138 
1139  throw std::logic_error(buffer.str());
1140  }
1141 
1142  // Display
1143  {
1144  const tinyxml2::XMLElement* element = root_element->FirstChildElement("Display");
1145 
1146  if(element)
1147  {
1148  const std::string new_display_string = element->GetText();
1149 
1150  try
1151  {
1152  set_display(new_display_string != "0");
1153  }
1154  catch(const std::logic_error& e)
1155  {
1156  std::cout << e.what() << std::endl;
1157  }
1158  }
1159  }
1160 }
1161 
1162 }
1163 
1164 // OpenNN: Open Neural Networks Library.
1165 // Copyright (c) 2005-2015 Roberto Lopez.
1166 //
1167 // This library is free software; you can redistribute it and/or
1168 // modify it under the terms of the GNU Lesser General Public
1169 // License as published by the Free Software Foundation; either
1170 // version 2.1 of the License, or any later version.
1171 //
1172 // This library is distributed in the hope that it will be useful,
1173 // but WITHOUT ANY WARRANTY; without even the implied warranty of
1174 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1175 // Lesser General Public License for more details.
1176 // You should have received a copy of the GNU Lesser General Public
1177 // License along with this library; if not, write to the Free Software
1178 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
size_t count_parameters_number(void) const
double calculate_performance(void) const
Returns the performance value of a neural network according to the sum squared error on a data set...
double calculate_generalization_performance(void) const
Returns the sum squared error of the neural network measured on the generalization instances of the d...
const Variables & get_variables(void) const
Returns a constant reference to the variables object composing this data set object.
Definition: data_set.cpp:202
Vector< double > terms
Subterms performance vector.
tinyxml2::XMLDocument * to_XML(void) const
Returns a representation of the sum squared error object, in XML format.
Matrix< Matrix< double > > calculate_interlayers_Delta(const Vector< Vector< double > > &, const Vector< Vector< double > > &, const Matrix< Matrix< double > > &, const Vector< double > &, const Matrix< double > &, const Vector< Vector< double > > &) const
size_t count_training_instances_number(void) const
Returns the number of instances in the data set which will be used for training.
Definition: instances.cpp:387
size_t get_inputs_number(void) const
Returns the number of inputs to the multilayer perceptron.
virtual ~SumSquaredError(void)
Destructor.
Vector< double > calculate_point_gradient(const Vector< double > &, const Vector< Vector< double > > &, const Vector< Vector< double > > &) const
Matrix< Matrix< double > > calculate_interlayers_combination_combination_Jacobian(const Vector< double > &) const
void set(void)
Sets the size of a vector to zero.
Definition: vector.h:656
size_t get_layers_number(void) const
Returns the number of layers in the multilayer perceptron.
bool has_missing_values(void) const
void initialize_diagonal(const size_t &, const T &)
Definition: matrix.h:1943
Vector< size_t > arrange_layers_perceptrons_numbers(void) const
Returns a vector with the size of each layer.
size_t get_outputs_number(void) const
Returns the number of outputs neurons in the multilayer perceptron.
Vector< double > calculate_outputs(const Vector< double > &) const
Vector< double > calculate_gradient(void) const
Matrix< double > Jacobian
Subterms Jacobian matrix.
const MissingValues & get_missing_values(void) const
Returns a reference to the missing values object in the data set.
Definition: data_set.cpp:275
void set_display(const bool &)
virtual void set_neural_network_pointer(NeuralNetwork *)
Vector< Vector< Vector< double > > > calculate_perceptrons_combination_parameters_gradient(const Vector< Vector< double > > &) const
Vector< size_t > arrange_targets_indices(void) const
Returns the indices of the target variables.
Definition: variables.cpp:519
Vector< size_t > arrange_training_indices(void) const
Returns the indices of the instances which will be used for training.
Definition: instances.cpp:489
size_t count_generalization_instances_number(void) const
Returns the number of instances in the data set which will be used for generalization.
Definition: instances.cpp:409
Vector< double > get_instance(const size_t &) const
Definition: data_set.cpp:684
bool has_conditions_layer(void) const
Matrix< double > calculate_Hessian(void) const
Matrix< double > calculate_terms_Jacobian(void) const
MultilayerPerceptron * get_multilayer_perceptron_pointer(void) const
Returns a pointer to the multilayer perceptron composing this neural network.
double calculate_norm(void) const
Returns the vector norm.
Definition: vector.h:2358
double calculate_sum_squared_error(const Vector< double > &) const
Definition: vector.h:2569
virtual Vector< double > calculate_homogeneous_solution(const Vector< double > &) const
Returns the homogeneous solution for applying boundary conditions.
Vector< Matrix< double > > calculate_layers_combination_parameters_Jacobian(const Vector< Vector< double > > &) const
NeuralNetwork * neural_network_pointer
Pointer to a multilayer perceptron object.
Matrix< double > calculate_point_Hessian(const Vector< Vector< double > > &, const Vector< Vector< Vector< double > > > &, const Matrix< Matrix< double > > &, const Vector< Vector< double > > &, const Matrix< Matrix< double > > &) const
virtual Vector< double > calculate_particular_solution(const Vector< double > &) const
Returns the particular solution for applying boundary conditions.
void from_XML(const tinyxml2::XMLDocument &)
bool display
Display messages to screen.
double calculate_distance(const Vector< double > &) const
Definition: vector.h:2557
ConditionsLayer * get_conditions_layer_pointer(void) const
Returns a pointer to the conditions layer composing this neural network.
size_t count_inputs_number(void) const
Returns the number of input variables of the data set.
Definition: variables.cpp:249
Vector< Vector< Vector< double > > > calculate_first_order_forward_propagation(const Vector< double > &) const
DataSet * data_set_pointer
Pointer to a data set object.
size_t count_targets_number(void) const
Returns the number of target variables of the data set.
Definition: variables.cpp:271
Vector< double > calculate_terms(void) const
Calculates the squared error terms for each instance, and returns it in a vector of size the number t...
PerformanceTerm::FirstOrderTerms calculate_first_order_terms(void) const
std::string write_performance_term_type(void) const
Returns a string with the name of the sum squared error performance type, "SUM_SQUARED_ERROR".
void set_row(const size_t &, const Vector< T > &)
Definition: matrix.h:1691
Vector< Vector< Vector< double > > > calculate_second_order_forward_propagation(const Vector< double > &) const
Vector< Vector< double > > calculate_layers_delta(const Vector< Vector< double > > &, const Vector< double > &) const
Vector< size_t > arrange_generalization_indices(void) const
Returns the indices of the instances which will be used for generalization.
Definition: instances.cpp:516
Vector< double > calculate_squared_errors(void) const
Returns the squared errors of the training instances.
Vector< Vector< double > > arrange_layers_input(const Vector< double > &, const Vector< Vector< double > > &) const
void set_parameters(const Vector< double > &)
Vector< size_t > arrange_inputs_indices(void) const
Returns the indices of the input variables.
Definition: variables.cpp:493
const Instances & get_instances(void) const
Returns a constant reference to the instances object composing this data set object.
Definition: data_set.cpp:222
size_t count_parameters_number(void) const
Returns the number of parameters (biases and synaptic weights) in the multilayer perceptron.