00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <string>
00019 #include <sstream>
00020 #include <iostream>
00021 #include <cmath>
00022
00023
00024
00025 #include "../utilities/vector.h"
00026 #include "../utilities/matrix.h"
00027
00028 #include "../utilities/numerical_differentiation.h"
00029
00030 #include "performance_term.h"
00031
00032
00033
00034 #include "../../parsers/tinyxml/tinyxml.h"
00035
00036
00037 namespace OpenNN
00038 {
00039
00040
00041
00045
00046 PerformanceTerm::PerformanceTerm(void)
00047 : neural_network_pointer(NULL),
00048 data_set_pointer(NULL),
00049 mathematical_model_pointer(NULL),
00050 numerical_differentiation_pointer(NULL)
00051 {
00052 set_default();
00053 }
00054
00055
00056
00057
00063
00064 PerformanceTerm::PerformanceTerm(NeuralNetwork* new_neural_network_pointer)
00065 : neural_network_pointer(new_neural_network_pointer),
00066 data_set_pointer(NULL),
00067 mathematical_model_pointer(NULL),
00068 numerical_differentiation_pointer(NULL)
00069 {
00070 set_default();
00071 }
00072
00073
00074
00075
00081
00082 PerformanceTerm::PerformanceTerm(DataSet* new_data_set_pointer)
00083 : neural_network_pointer(NULL),
00084 data_set_pointer(new_data_set_pointer),
00085 mathematical_model_pointer(NULL),
00086 numerical_differentiation_pointer(NULL)
00087 {
00088 set_default();
00089 }
00090
00091
00092
00093
00099
00100 PerformanceTerm::PerformanceTerm(MathematicalModel* new_mathematical_model_pointer)
00101 : neural_network_pointer(NULL),
00102 data_set_pointer(NULL),
00103 mathematical_model_pointer(new_mathematical_model_pointer),
00104 numerical_differentiation_pointer(NULL)
00105 {
00106 set_default();
00107 }
00108
00109
00110
00111
00118
00119 PerformanceTerm::PerformanceTerm(NeuralNetwork* new_neural_network_pointer, DataSet* new_data_set_pointer)
00120 : neural_network_pointer(new_neural_network_pointer),
00121 data_set_pointer(new_data_set_pointer),
00122 mathematical_model_pointer(NULL),
00123 numerical_differentiation_pointer(NULL)
00124 {
00125 set_default();
00126 }
00127
00128
00129
00130
00137
00138 PerformanceTerm::PerformanceTerm(NeuralNetwork* new_neural_network_pointer, MathematicalModel* new_mathematical_model_pointer)
00139 : neural_network_pointer(new_neural_network_pointer),
00140 data_set_pointer(NULL),
00141 mathematical_model_pointer(new_mathematical_model_pointer),
00142 numerical_differentiation_pointer(NULL)
00143 {
00144 set_default();
00145 }
00146
00147
00148
00149
00157
00158 PerformanceTerm::PerformanceTerm(NeuralNetwork* new_neural_network_pointer, MathematicalModel* new_mathematical_model_pointer, DataSet* new_data_set_pointer)
00159 : neural_network_pointer(new_neural_network_pointer),
00160 data_set_pointer(new_data_set_pointer),
00161 mathematical_model_pointer(new_mathematical_model_pointer),
00162 numerical_differentiation_pointer(NULL)
00163 {
00164 set_default();
00165 }
00166
00167
00168
00169
00174
00175 PerformanceTerm::PerformanceTerm(TiXmlElement* performance_term_element)
00176 : neural_network_pointer(NULL),
00177 data_set_pointer(NULL),
00178 mathematical_model_pointer(NULL),
00179 numerical_differentiation_pointer(NULL)
00180 {
00181 set_default();
00182
00183 from_XML(performance_term_element);
00184 }
00185
00186
00187
00188
00192
00193 PerformanceTerm::PerformanceTerm(const PerformanceTerm& other_performance_term)
00194 : neural_network_pointer(NULL),
00195 data_set_pointer(NULL),
00196 mathematical_model_pointer(NULL),
00197 numerical_differentiation_pointer(NULL)
00198 {
00199 neural_network_pointer = other_performance_term.neural_network_pointer;
00200
00201 data_set_pointer = other_performance_term.data_set_pointer;
00202 mathematical_model_pointer = other_performance_term.mathematical_model_pointer;
00203
00204 if(other_performance_term.numerical_differentiation_pointer)
00205 {
00206 numerical_differentiation_pointer = new NumericalDifferentiation(*other_performance_term.numerical_differentiation_pointer);
00207 }
00208
00209 display = other_performance_term.display;
00210 }
00211
00212
00213
00214
00217
00218 PerformanceTerm::~PerformanceTerm(void)
00219 {
00220 delete numerical_differentiation_pointer;
00221 }
00222
00223
00224
00225
00226
00227
00231
00232 PerformanceTerm& PerformanceTerm::operator = (const PerformanceTerm& other_performance_term)
00233 {
00234 if(this != &other_performance_term)
00235 {
00236 neural_network_pointer = other_performance_term.neural_network_pointer;
00237 data_set_pointer = other_performance_term.data_set_pointer;
00238 mathematical_model_pointer = other_performance_term.mathematical_model_pointer;
00239 numerical_differentiation_pointer = other_performance_term.numerical_differentiation_pointer;
00240 display = other_performance_term.display;
00241 }
00242
00243 return(*this);
00244 }
00245
00246
00247
00248
00249
00250
00254
00255 bool PerformanceTerm::operator == (const PerformanceTerm& other_performance_term) const
00256 {
00257 if(*neural_network_pointer == *other_performance_term.neural_network_pointer
00258 && *data_set_pointer == *other_performance_term.data_set_pointer
00259 && *mathematical_model_pointer == *other_performance_term.mathematical_model_pointer
00260
00261 && display == other_performance_term.display)
00262 {
00263 return(true);
00264 }
00265 else
00266 {
00267 return(false);
00268 }
00269 }
00270
00271
00272
00273
00274
00275
00278
00279 const bool& PerformanceTerm::get_display(void) const
00280 {
00281 return(display);
00282 }
00283
00284
00285
00286
00289
00290 void PerformanceTerm::set(void)
00291 {
00292 neural_network_pointer = NULL;
00293 data_set_pointer = NULL;
00294 mathematical_model_pointer = NULL;
00295 numerical_differentiation_pointer = NULL;
00296
00297 set_default();
00298 }
00299
00300
00301
00302
00306
00307 void PerformanceTerm::set(NeuralNetwork* new_neural_network_pointer)
00308 {
00309 neural_network_pointer = new_neural_network_pointer;
00310 data_set_pointer = NULL;
00311 mathematical_model_pointer = NULL;
00312 numerical_differentiation_pointer = NULL;
00313
00314 set_default();
00315 }
00316
00317
00318
00319
00323
00324 void PerformanceTerm::set(DataSet* new_data_set_pointer)
00325 {
00326 neural_network_pointer = NULL;
00327 data_set_pointer = new_data_set_pointer;
00328 mathematical_model_pointer = NULL;
00329 numerical_differentiation_pointer = NULL;
00330
00331 set_default();
00332 }
00333
00334
00335
00336
00340
00341 void PerformanceTerm::set(MathematicalModel* new_mathematical_model_pointer)
00342 {
00343 neural_network_pointer = NULL;
00344 data_set_pointer = NULL;
00345 mathematical_model_pointer = new_mathematical_model_pointer;
00346 numerical_differentiation_pointer = NULL;
00347
00348 set_default();
00349 }
00350
00351
00352
00353
00359
00360 void PerformanceTerm::set(NeuralNetwork* new_neural_network_pointer, DataSet* new_data_set_pointer)
00361 {
00362 neural_network_pointer = new_neural_network_pointer;
00363 data_set_pointer = new_data_set_pointer;
00364 mathematical_model_pointer = NULL;
00365 numerical_differentiation_pointer = NULL;
00366
00367 set_default();
00368 }
00369
00370
00371
00372
00378
00379 void PerformanceTerm::set(NeuralNetwork* new_neural_network_pointer, MathematicalModel* new_mathematical_model_pointer)
00380 {
00381 neural_network_pointer = new_neural_network_pointer;
00382 data_set_pointer = NULL;
00383 mathematical_model_pointer = new_mathematical_model_pointer;
00384 numerical_differentiation_pointer = NULL;
00385
00386 set_default();
00387 }
00388
00389
00390
00391
00398
00399 void PerformanceTerm::set(NeuralNetwork* new_neural_network_pointer, MathematicalModel* new_mathematical_model_pointer, DataSet* new_data_set_pointer)
00400 {
00401 neural_network_pointer = new_neural_network_pointer;
00402 data_set_pointer = new_data_set_pointer;
00403 mathematical_model_pointer = new_mathematical_model_pointer;
00404 numerical_differentiation_pointer = NULL;
00405
00406 set_default();
00407 }
00408
00409
00410
00411
00414
00415 void PerformanceTerm::set(const PerformanceTerm& other_performance_term)
00416 {
00417 neural_network_pointer = other_performance_term.neural_network_pointer;
00418
00419 data_set_pointer = other_performance_term.data_set_pointer;
00420
00421 mathematical_model_pointer = other_performance_term.mathematical_model_pointer;
00422
00423 if(other_performance_term.numerical_differentiation_pointer)
00424 {
00425 numerical_differentiation_pointer = new NumericalDifferentiation(*other_performance_term.numerical_differentiation_pointer);
00426 }
00427
00428 display = other_performance_term.display;
00429 }
00430
00431
00432
00433
00436
00437 void PerformanceTerm::set_neural_network_pointer(NeuralNetwork* new_neural_network_pointer)
00438 {
00439 neural_network_pointer = new_neural_network_pointer;
00440 }
00441
00442
00443
00444
00446
00447 void PerformanceTerm::set_mathematical_model_pointer(MathematicalModel* new_mathematical_model_pointer)
00448 {
00449 mathematical_model_pointer = new_mathematical_model_pointer;
00450 }
00451
00452
00453
00454
00456
00457 void PerformanceTerm::set_data_set_pointer(DataSet* new_data_set_pointer)
00458 {
00459 data_set_pointer = new_data_set_pointer;
00460 }
00461
00462
00463
00464
00467
00468 void PerformanceTerm::set_numerical_differentiation_pointer(NumericalDifferentiation* new_numerical_differentiation_pointer)
00469 {
00470 numerical_differentiation_pointer = new_numerical_differentiation_pointer;
00471 }
00472
00473
00474
00475
00480
00481 void PerformanceTerm::set_default(void)
00482 {
00483 display = true;
00484 }
00485
00486
00487
00488
00493
00494 void PerformanceTerm::set_display(const bool& new_display)
00495 {
00496 display = new_display;
00497 }
00498
00499
00500
00501
00503
00504 void PerformanceTerm::construct_numerical_differentiation(void)
00505 {
00506 if(!numerical_differentiation_pointer)
00507 {
00508 numerical_differentiation_pointer = new NumericalDifferentiation();
00509 }
00510 }
00511
00512
00513
00514
00516
00517 void PerformanceTerm::delete_numerical_differentiation_pointer(void)
00518 {
00519 delete numerical_differentiation_pointer;
00520
00521 numerical_differentiation_pointer = NULL;
00522 }
00523
00524
00525
00526
00529
00530 void PerformanceTerm::check(void) const
00531 {
00532 std::ostringstream buffer;
00533
00534 if(!neural_network_pointer)
00535 {
00536 buffer << "OpenNN Exception: PerformanceTerm class.\n"
00537 << "void check(void) const.\n"
00538 << "Pointer to neural network is NULL.\n";
00539
00540 throw std::logic_error(buffer.str().c_str());
00541 }
00542 }
00543
00544
00545
00546
00551
00552 Vector< Vector<double> > PerformanceTerm::calculate_layers_delta
00553 (const Vector< Vector<double> >& layers_activation_derivative,
00554 const Vector<double>& output_objective_gradient) const
00555 {
00556
00557
00558 #ifdef _DEBUG
00559
00560 check();
00561
00562 #endif
00563
00564 const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
00565
00566 #ifdef _DEBUG
00567
00568 std::ostringstream buffer;
00569
00570 if(!multilayer_perceptron_pointer)
00571 {
00572 buffer << "OpenNN Exception: PerformanceTerm class.\n"
00573 << "Vector< Vector<double> > calculate_layers_delta(const Vector< Vector<double> >&, const Vector<double>&) const method.\n"
00574 << "Pointer to multilayer perceptron in neural network is NULL.\n";
00575
00576 throw std::logic_error(buffer.str().c_str());
00577 }
00578
00579 #endif
00580
00581 const unsigned int layers_number = multilayer_perceptron_pointer->count_layers_number();
00582 const Vector<unsigned int> layers_perceptrons_number = multilayer_perceptron_pointer->arrange_layers_perceptrons_numbers();
00583
00584
00585
00586 #ifdef _DEBUG
00587
00588
00589
00590 const unsigned int layers_activation_derivative_size = layers_activation_derivative.size();
00591
00592 if(layers_activation_derivative_size != layers_number)
00593 {
00594 buffer << "OpenNN Exception: PerformanceTerm class.\n"
00595 << "Vector< Vector<double> > calculate_layers_delta(const Vector< Vector<double> >&, const Vector<double>&) method.\n"
00596 << "Size of forward propagation activation derivative vector must be equal to number of layers.\n";
00597
00598 throw std::logic_error(buffer.str().c_str());
00599 }
00600
00601 if(layers_number > 0)
00602 {
00603 const unsigned int output_objective_gradient_size = output_objective_gradient.size();
00604
00605 if(output_objective_gradient_size != layers_perceptrons_number[layers_number-1])
00606 {
00607 buffer << "OpenNN Exception: PerformanceTerm class.\n"
00608 << "Vector<double> calculate_layers_delta(const Vector< Vector<double> >&, const Vector<double>&) method.\n"
00609 << "Size of outputs objective gradient (" << output_objective_gradient_size << ") must be equal to "
00610 << "number of outputs (" << layers_perceptrons_number[layers_number-1] << ").\n";
00611
00612 throw std::logic_error(buffer.str().c_str());
00613 }
00614 }
00615
00616 #endif
00617
00618
00619
00620 Matrix<double> layer_synaptic_weights;
00621
00622
00623
00624 Vector< Vector<double> > layers_delta(layers_number);
00625
00626
00627
00628 if(layers_number > 0)
00629 {
00630 layers_delta[layers_number-1] = layers_activation_derivative[layers_number-1]*output_objective_gradient;
00631
00632
00633
00634 for(int i = layers_number-2; i >= 0; i--)
00635 {
00636 layer_synaptic_weights = neural_network_pointer->get_multilayer_perceptron_pointer()->get_layer(i+1).arrange_synaptic_weights();
00637
00638 layers_delta[i] = layers_activation_derivative[i]*(layers_delta[i+1].dot(layer_synaptic_weights));
00639 }
00640 }
00641
00642 return(layers_delta);
00643 }
00644
00645
00646
00647
00653
00654 Vector< Vector<double> > PerformanceTerm::calculate_layers_delta
00655 (const Vector< Vector<double> >& layers_activation_derivative,
00656 const Vector<double>& homogeneous_solution,
00657 const Vector<double>& output_objective_gradient) const
00658 {
00659 const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
00660
00661 unsigned int layers_number = multilayer_perceptron_pointer->count_layers_number();
00662 const Vector<unsigned int> layers_perceptrons_number = multilayer_perceptron_pointer->arrange_layers_perceptrons_numbers();
00663
00664
00665
00666 #ifdef _DEBUG
00667
00668
00669
00670 const unsigned int layers_activation_derivative_size = layers_activation_derivative.size();
00671
00672 if(layers_activation_derivative_size != layers_number)
00673 {
00674 std::ostringstream buffer;
00675
00676 buffer << "OpenNN Exception: PerformanceTerm class.\n"
00677 << "Vector< Vector<double> > calculate_layers_delta(const Vector< Vector<double> >&, const Vector<double>&) const method.\n"
00678 << "Size of forward propagation activation derivative vector must be equal to number of layers.\n";
00679
00680 throw std::logic_error(buffer.str().c_str());
00681 }
00682
00683 const unsigned int objective_function_output_gradient_size = output_objective_gradient.size();
00684
00685 if(objective_function_output_gradient_size != layers_perceptrons_number[layers_number-1])
00686 {
00687 std::ostringstream buffer;
00688
00689 buffer << "OpenNN Exception: PerformanceTerm class.\n"
00690 << "Vector<double> calculate_layers_delta(const Vector< Vector<double> >&, const Vector<double>&) const method.\n"
00691 << "Size of objective function outputs derivative (" << objective_function_output_gradient_size << ")must be equal to "
00692 << "number of outputs (" << layers_perceptrons_number[layers_number-1] << ").\n";
00693
00694 throw std::logic_error(buffer.str().c_str());
00695 }
00696
00697 #endif
00698
00699 const Vector<PerceptronLayer>& layers = multilayer_perceptron_pointer->get_layers();
00700
00701 Matrix<double> synaptic_weights;
00702
00703 double sum;
00704
00705
00706
00707 Vector< Vector<double> > layers_delta(layers_number);
00708
00709 for(unsigned int i = 0; i < layers_number; i++)
00710 {
00711 layers_delta[i].set(layers_perceptrons_number[i]);
00712 }
00713
00714
00715
00716 layers_delta[layers_number-1] = layers_activation_derivative[layers_number-1]*homogeneous_solution*output_objective_gradient;
00717
00718
00719
00720 for(int h = layers_number-2; h >= 0; h--)
00721 {
00722 for(unsigned int i = 0; i < layers_perceptrons_number[h]; i++)
00723 {
00724 sum = 0.0;
00725
00726 for(unsigned int j = 0; j < layers_perceptrons_number[h+1]; j++)
00727 {
00728 synaptic_weights = layers[h+1].arrange_synaptic_weights();
00729
00730 sum += (synaptic_weights[i][j])*layers_delta[h+1][j];
00731 }
00732
00733 layers_delta[h][i] = layers_activation_derivative[h][i]*sum;
00734 }
00735 }
00736
00737 return(layers_delta);
00738 }
00739
00740
00741
00742
00747
00748 Vector<double> PerformanceTerm::calculate_point_gradient
00749 (const Vector<double>& inputs,
00750 const Vector< Vector<double> >& layers_activation,
00751 const Vector< Vector<double> >& layers_delta) const
00752 {
00753
00754
00755 #ifdef _DEBUG
00756
00757 check();
00758
00759 #endif
00760
00761 const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
00762
00763 #ifdef _DEBUG
00764
00765 std::ostringstream buffer;
00766
00767 if(!multilayer_perceptron_pointer)
00768 {
00769 buffer << "OpenNN Exception: PerformanceTerm class.\n"
00770 << "Vector<double> calculate_point_gradient(const Vector<double>&, const Vector< Vector<double> >&, const Vector<double>&) const method.\n"
00771 << "Pointer to multilayer perceptron is NULL.\n";
00772
00773 throw std::logic_error(buffer.str().c_str());
00774 }
00775
00776 #endif
00777
00778 const unsigned int inputs_number = multilayer_perceptron_pointer->count_inputs_number();
00779 const unsigned int layers_number = multilayer_perceptron_pointer->count_layers_number();
00780 const Vector<unsigned int> layers_perceptrons_number = multilayer_perceptron_pointer->arrange_layers_perceptrons_numbers();
00781
00782
00783
00784 #ifdef _DEBUG
00785
00786
00787
00788 const unsigned int inputs_size = inputs.size();
00789
00790 if(inputs_size != inputs_number)
00791 {
00792 buffer << "OpenNN Exception: PerformanceTerm class.\n"
00793 << "Vector< Vector<double> > calculate_layers_objective_gradient(const Vector< Vector<double> >&, const Vector<double>&, const Vector<double>&) method.\n"
00794 << "Size of inputs (" << inputs_size << ") must be equal to inputs number (" << inputs_number << ").\n";
00795
00796 throw std::logic_error(buffer.str().c_str());
00797 }
00798
00799
00800
00801 const unsigned int layers_activation_size = layers_activation.size();
00802
00803 if(layers_activation_size != layers_number)
00804 {
00805 buffer << "OpenNN Exception: PerformanceTerm class.\n"
00806 << "Vector< Vector<double> > calculate_layers_objective_gradient(const Vector< Vector<double> >&, const Vector<double>&, const Vector<double>&) method.\n"
00807 << "Size of forward propagation activation (" << layers_activation_size << ") must be equal to number of layers (" << layers_number << ").\n";
00808
00809 throw std::logic_error(buffer.str().c_str());
00810 }
00811
00812
00813
00814 const unsigned int layers_delta_size = layers_delta.size();
00815
00816 if(layers_delta_size != layers_number)
00817 {
00818 buffer << "OpenNN Exception: PerformanceTerm class.\n"
00819 << "Vector< Vector<double> > calculate_layers_objective_gradient(const Vector< Vector<double> >&, const Vector<double>&) method.\n"
00820 << "Size of layers delta ("<< layers_delta_size << ") must be equal to number of layers (" << layers_number << ").\n";
00821
00822 throw std::logic_error(buffer.str().c_str());
00823 }
00824
00825 #endif
00826
00827 const unsigned int parameters_number = neural_network_pointer->count_parameters_number();
00828
00829 Vector<double> point_gradient(parameters_number);
00830
00831 unsigned int index = 0;
00832
00833 const Vector< Vector<double> > layers_inputs = multilayer_perceptron_pointer->arrange_layers_input(inputs, layers_activation);
00834
00835 const Vector< Matrix<double> > layers_combination_parameters_Jacobian = multilayer_perceptron_pointer->calculate_layers_combination_parameters_Jacobian(layers_inputs);
00836
00837 for(unsigned int i = 0; i < layers_number; i++)
00838 {
00839 point_gradient.tuck_in(index, layers_delta[i].dot(layers_combination_parameters_Jacobian[i]));
00840
00841 index += multilayer_perceptron_pointer->get_layer(i).count_parameters_number();
00842 }
00843
00844 if(layers_number != 0)
00845 {
00846 Vector<double> synaptic_weights;
00847
00848 unsigned int index = 0;
00849
00850
00851
00852 for(unsigned int i = 0; i < layers_perceptrons_number[0]; i++)
00853 {
00854
00855
00856 point_gradient[index] = layers_delta[0][i];
00857 index++;
00858
00859
00860
00861 synaptic_weights = multilayer_perceptron_pointer->get_layer(0).get_perceptron(i).arrange_synaptic_weights();
00862
00863 for(unsigned int j = 0; j < inputs_number; j++)
00864 {
00865 point_gradient[index] = layers_delta[0][i]*inputs[j];
00866 index++;
00867 }
00868 }
00869
00870
00871
00872 for(unsigned int h = 1; h < layers_number; h++)
00873 {
00874 for(unsigned int i = 0; i < layers_perceptrons_number[h]; i++)
00875 {
00876
00877
00878 point_gradient[index] = layers_delta[h][i];
00879 index++;
00880
00881
00882
00883 synaptic_weights = multilayer_perceptron_pointer->get_layer(h).get_perceptron(i).arrange_synaptic_weights();
00884
00885 for(unsigned int j = 0; j < layers_perceptrons_number[h-1]; j++)
00886 {
00887 point_gradient[index] = layers_delta[h][i]*layers_activation[h-1][j];
00888 index++;
00889 }
00890 }
00891 }
00892
00893 }
00894
00895 return(point_gradient);
00896 }
00897
00898
00899
00900
00904
00905 Vector<double> PerformanceTerm::calculate_point_gradient
00906 (const Vector< Matrix<double> >& layers_combination_parameters_Jacobian,
00907 const Vector< Vector<double> >& layers_delta) const
00908 {
00909
00910
00911 #ifdef _DEBUG
00912
00913 check();
00914
00915 #endif
00916
00917 const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
00918
00919
00920
00921 #ifdef _DEBUG
00922
00923 std::ostringstream buffer;
00924
00925 if(!multilayer_perceptron_pointer)
00926 {
00927 buffer << "OpenNN Exception: PerformanceTerm class.\n"
00928 << "Vector<double> calculate_point_gradient(const Vector<double>&, const Vector< Vector<double> >&, const Vector<double>&) const method.\n"
00929 << "Pointer to network is NULL.\n";
00930
00931 throw std::logic_error(buffer.str().c_str());
00932 }
00933
00934 #endif
00935
00936 const unsigned int layers_number = multilayer_perceptron_pointer->count_layers_number();
00937 const Vector<unsigned int> layers_size = multilayer_perceptron_pointer->arrange_layers_perceptrons_numbers();
00938
00939
00940
00941 #ifdef _DEBUG
00942
00943
00944
00945 const unsigned int layers_combination_parameters_Jacobian_size = layers_combination_parameters_Jacobian.size();
00946
00947 if(layers_combination_parameters_Jacobian_size != layers_number)
00948 {
00949 buffer << "OpenNN Exception: PerformanceTerm class.\n"
00950 << "Vector< Vector<double> > calculate_layers_objective_gradient(const Vector< Vector<double> >&, const Vector<double>&, const Vector<double>&) method.\n"
00951 << "Size of forward propagation activation (" << layers_combination_parameters_Jacobian_size << ") must be equal to number of layers (" << layers_number << ").\n";
00952
00953 throw std::logic_error(buffer.str().c_str());
00954 }
00955
00956
00957
00958 const unsigned int layers_delta_size = layers_delta.size();
00959
00960 if(layers_delta_size != layers_number)
00961 {
00962 buffer << "OpenNN Exception: PerformanceTerm class.\n"
00963 << "Vector< Vector<double> > calculate_layers_objective_gradient(const Vector< Vector<double> >&, const Vector<double>&) method.\n"
00964 << "Size of layers delta ("<< layers_delta_size << ") must be equal to number of layers (" << layers_number << ").\n";
00965
00966 throw std::logic_error(buffer.str().c_str());
00967 }
00968
00969 #endif
00970
00971 const unsigned int parameters_number = multilayer_perceptron_pointer->count_parameters_number();
00972
00973 Vector<double> point_gradient(parameters_number);
00974
00975 unsigned int index = 0;
00976
00977 for(unsigned int i = 0; i < layers_number; i++)
00978 {
00979 point_gradient.tuck_in(index, layers_delta[i].dot(layers_combination_parameters_Jacobian[i]));
00980
00981 index += neural_network_pointer->get_multilayer_perceptron_pointer()->get_layer(i).count_parameters_number();
00982 }
00983
00984 return(point_gradient);
00985 }
00986
00987
00988
00989
00999
01000 Matrix< Matrix<double> > PerformanceTerm::calculate_interlayers_Delta
01001 (const Vector< Vector<double> >& layers_activation_derivative,
01002 const Vector< Vector<double> >& layers_activation_second_derivative,
01003 const Matrix< Matrix<double> >& interlayers_combination_combination_Jacobian_form,
01004 const Vector<double>& output_objective_gradient,
01005 const Matrix<double>& output_objective_Hessian,
01006 const Vector< Vector<double> >& layers_delta) const
01007 {
01008
01009
01010 #ifdef _DEBUG
01011
01012 check();
01013
01014 #endif
01015
01016 const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
01017
01018 #ifdef _DEBUG
01019
01020 std::ostringstream buffer;
01021
01022 if(!multilayer_perceptron_pointer)
01023 {
01024 buffer << "OpenNN Exception: PerformanceTerm class.\n"
01025 << "Matrix< Matrix<double> > calculate_interlayers_Delta(const Vector< Vector<double> >&, const Vector< Vector<double> >&, const Vector<double>&, const Matrix<double>&) method.\n"
01026 << "Multilayer perceptron pointer is NULL.\n";
01027
01028 throw std::logic_error(buffer.str().c_str());
01029 }
01030
01031 #endif
01032
01033 const unsigned int layers_number = multilayer_perceptron_pointer->count_layers_number();
01034 const Vector<unsigned int> layers_size = multilayer_perceptron_pointer->arrange_layers_perceptrons_numbers();
01035
01036
01037
01038 #ifdef _DEBUG
01039
01040 if(layers_number != 0)
01041 {
01042 const unsigned int output_objective_gradient_size = output_objective_gradient.size();
01043
01044 if(output_objective_gradient_size != layers_size[layers_number-1])
01045 {
01046 buffer << "OpenNN Exception: PerformanceTerm class.\n"
01047
01048
01049 << std::endl;
01050
01051 throw std::logic_error(buffer.str().c_str());
01052 }
01053
01054 const unsigned int output_objective_Hessian_rows_number = output_objective_Hessian.get_rows_number();
01055 const unsigned int output_objective_Hessian_columns_number = output_objective_Hessian.get_columns_number();
01056
01057 if(output_objective_Hessian_rows_number != layers_size[layers_number-1])
01058 {
01059 buffer << "OpenNN Exception: PerformanceTerm class.\n"
01060
01061
01062 << std::endl;
01063
01064 throw std::logic_error(buffer.str().c_str());
01065 }
01066
01067 if(output_objective_Hessian_columns_number != layers_size[layers_number-1])
01068 {
01069 buffer << "OpenNN Exception: PerformanceTerm class.\n"
01070
01071
01072 << std::endl;
01073
01074 throw std::logic_error(buffer.str().c_str());
01075 }
01076 }
01077
01078 #endif
01079
01080 const Vector< Matrix<double> > layers_synaptic_weights = multilayer_perceptron_pointer->arrange_layers_synaptic_weights();
01081
01082
01083
01084 Matrix< Matrix<double> > interlayers_Delta(layers_number, layers_number);
01085
01086 for(unsigned int i = 0; i < layers_number; i++)
01087 {
01088 for(unsigned int j = 0; j < layers_number; j++)
01089 {
01090 interlayers_Delta[i][j].set(layers_size[i], layers_size[j]);
01091 }
01092 }
01093
01094 if(layers_number > 0)
01095 {
01096
01097
01098 interlayers_Delta[layers_number-1][layers_number-1] = (output_objective_Hessian*(layers_activation_derivative[layers_number-1]*layers_activation_derivative[layers_number-1])).sum_diagonal(output_objective_gradient*layers_activation_second_derivative[layers_number-1]);
01099
01100
01101
01102 for(int i = layers_number-1; i >= 0; i--)
01103 {
01104 for(int j = layers_number-1; j >= 0; j--)
01105 {
01106 if((unsigned int)i != layers_number-1 && (unsigned int)j != layers_number-1)
01107 {
01108 interlayers_Delta[i][j] = layers_activation_second_derivative[j]*interlayers_combination_combination_Jacobian_form[i][j]*(layers_delta[j+1].dot(layers_synaptic_weights[j+1]))
01109 + layers_activation_second_derivative[j]*(interlayers_Delta[i][j+1].dot(layers_synaptic_weights[j+1]));
01110 }
01111 }
01112 }
01113 }
01114
01115 return(interlayers_Delta);
01116 }
01117
01118
01119
01120
01128
01129 Matrix<double> PerformanceTerm::calculate_point_Hessian
01130 (const Vector< Vector<double> >& layers_activation_derivative,
01131 const Vector< Vector< Vector<double> > >& perceptrons_combination_parameters_gradient,
01132 const Matrix< Matrix<double> >& interlayers_combination_combination_Jacobian,
01133 const Vector< Vector<double> >& layers_delta,
01134 const Matrix< Matrix<double> >& interlayers_Delta) const
01135 {
01136
01137
01138 #ifdef _DEBUG
01139
01140 check();
01141
01142 #endif
01143
01144 const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
01145
01146 #ifdef _DEBUG
01147
01148 std::ostringstream buffer;
01149
01150 if(!multilayer_perceptron_pointer)
01151 {
01152 buffer << "OpenNN Exception: PerformanceTerm class.\n"
01153 << "Matrix<double> calculate_point_Hessian(const Vector<double>&, const Matrix< Matrix<double> >&, const Vector< Vector<double> >&, const Matrix< Matrix<double> >&) const method.\n"
01154 << "Multilayer perceptron pointer is NULL.\n";
01155
01156 throw std::logic_error(buffer.str().c_str());
01157 }
01158
01159 #endif
01160
01161 const unsigned int layers_number = multilayer_perceptron_pointer->count_layers_number();
01162
01163 const unsigned int parameters_number = multilayer_perceptron_pointer->count_parameters_number();
01164
01165 #ifdef _DEBUG
01166
01167 const unsigned int layers_activation_derivative_size = layers_activation_derivative.size();
01168
01169 if(layers_activation_derivative_size != layers_number)
01170 {
01171 buffer << "OpenNN Exception: PerformanceTerm class.\n"
01172 << "Matrix<double> calculate_point_Hessian(const Vector<double>&, const Matrix< Matrix<double> >&, const Vector< Vector<double> >&, const Matrix< Matrix<double> >&) const method.\n"
01173 << "Size of layers activation derivative must be equal to number of layers in multilayer perceptron.\n";
01174
01175 throw std::logic_error(buffer.str().c_str());
01176 }
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188 #endif
01189
01190
01191
01192 Matrix<double> point_Hessian(parameters_number, parameters_number, 0.0);
01193
01194 Vector<unsigned int> parameter_indices(3);
01195
01196 unsigned int layer_index_i;
01197 unsigned int neuron_index_i;
01198 unsigned int parameter_index_i;
01199
01200 unsigned int layer_index_j;
01201 unsigned int neuron_index_j;
01202 unsigned int parameter_index_j;
01203
01204 if(layers_number > 0)
01205 {
01206 for(unsigned int i = 0; i < parameters_number; i++)
01207 {
01208 parameter_indices = multilayer_perceptron_pointer->arrange_parameter_indices(i);
01209 layer_index_i = parameter_indices[0];
01210 neuron_index_i = parameter_indices[1];
01211 parameter_index_i = parameter_indices[2];
01212
01213 for(unsigned int j = 0; j < parameters_number; j++)
01214 {
01215 parameter_indices = multilayer_perceptron_pointer->arrange_parameter_indices(j);
01216 layer_index_j = parameter_indices[0];
01217 neuron_index_j = parameter_indices[1];
01218 parameter_index_j = parameter_indices[2];
01219
01220 point_Hessian[i][j]
01221 = perceptrons_combination_parameters_gradient[layer_index_i][neuron_index_i][parameter_index_i]*perceptrons_combination_parameters_gradient[layer_index_j][neuron_index_j][parameter_index_j]*interlayers_Delta[layer_index_j][layer_index_i][neuron_index_j][neuron_index_i]
01222 + perceptrons_combination_parameters_gradient[layer_index_i][neuron_index_i][parameter_index_i]*layers_delta[layer_index_j][neuron_index_j]*layers_activation_derivative[layer_index_j][neuron_index_j]*interlayers_combination_combination_Jacobian[layer_index_j][layer_index_i][neuron_index_j][neuron_index_i];
01223 }
01224 }
01225
01226 for(unsigned int i = 0; i < parameters_number; i++)
01227 {
01228 for(unsigned int j = 0; j < i; j++)
01229 {
01230 point_Hessian[i][j] = point_Hessian[j][i];
01231 }
01232 }
01233 }
01234
01235 return(point_Hessian);
01236 }
01237
01238
01239
01240
01243
01244 Vector<double> PerformanceTerm::calculate_gradient(void) const
01245 {
01246
01247
01248 #ifdef _DEBUG
01249
01250 check();
01251
01252 #endif
01253
01254
01255
01256 #ifdef _DEBUG
01257
01258 std::ostringstream buffer;
01259
01260 if(!numerical_differentiation_pointer)
01261 {
01262 buffer << "OpenNN Exception: PerformanceTerm class.\n"
01263 << "Vector<double> calculate_gradient(void) const method.\n"
01264 << "Numerical differentiation pointer is NULL.\n";
01265
01266 throw std::logic_error(buffer.str().c_str());
01267 }
01268
01269 #endif
01270
01271 const Vector<double> parameters = neural_network_pointer->arrange_parameters();
01272
01273 return(numerical_differentiation_pointer->calculate_gradient(*this, &PerformanceTerm::calculate_evaluation, parameters));
01274 }
01275
01276
01277
01278
01280
01281 Matrix<double> PerformanceTerm::calculate_Hessian(void) const
01282 {
01283
01284
01285 #ifdef _DEBUG
01286
01287 check();
01288
01289 #endif
01290
01291 const Vector<double> parameters = neural_network_pointer->arrange_parameters();
01292
01293 return(numerical_differentiation_pointer->calculate_Hessian(*this, &PerformanceTerm::calculate_evaluation, parameters));
01294 }
01295
01296
01297
01298
01300
01301 Vector<double> PerformanceTerm::calculate_evaluation_terms(void) const
01302 {
01303 Vector<double> v;
01304
01305 return(v);
01306 }
01307
01308
01309
01310
01312
01313 Vector<double> PerformanceTerm::calculate_evaluation_terms(const Vector<double>&) const
01314 {
01315 Vector<double> v;
01316
01317 return(v);
01318 }
01319
01320
01321
01322
01324
01325 Matrix<double> PerformanceTerm::calculate_Jacobian_terms(void) const
01326 {
01327 Matrix<double> m;
01328
01329 return(m);
01330 }
01331
01332
01333
01334
01336
01337 PerformanceTerm::FirstOrderEvaluationTerms PerformanceTerm::calculate_first_order_evaluation_terms(void) const
01338 {
01339 FirstOrderEvaluationTerms a;
01340
01341 return(a);
01342 }
01343
01344
01345
01346
01348
01349 std::string PerformanceTerm::write_performance_term_type(void) const
01350 {
01351 return("USER_PERFORMANCE_TERM");
01352 }
01353
01354
01355
01356
01360
01361 std::string PerformanceTerm::write_information(void) const
01362 {
01363 return("");
01364 }
01365
01366
01367
01368
01370
01371 std::string PerformanceTerm::to_string(void) const
01372 {
01373 std::ostringstream buffer;
01374
01375 buffer << "Performance term\n"
01376 << "Display: " << display << "\n";
01377
01378 return(buffer.str());
01379 }
01380
01381
01382
01383
01386
01387 TiXmlElement* PerformanceTerm::to_XML(void) const
01388 {
01389 std::ostringstream buffer;
01390
01391
01392
01393 TiXmlElement* objective_term_element = new TiXmlElement("PerformanceTerm");
01394 objective_term_element->SetAttribute("Version", 4);
01395
01396 return(objective_term_element);
01397 }
01398
01399
01400
01401
01404
01405 void PerformanceTerm::from_XML(TiXmlElement* objective_term_element)
01406 {
01407
01408
01409 if(!objective_term_element)
01410 {
01411 return;
01412 }
01413
01414
01415
01416 TiXmlElement* display_element = objective_term_element->FirstChildElement("Display");
01417
01418 if(display_element)
01419 {
01420 std::string new_display_string = display_element->GetText();
01421
01422 try
01423 {
01424 set_display(new_display_string != "0");
01425 }
01426 catch(std::exception& e)
01427 {
01428 std::cout << e.what() << std::endl;
01429 }
01430 }
01431 }
01432
01433
01434
01435
01439
01440 unsigned int PerformanceTerm::calculate_Kronecker_delta(const unsigned int& a, const unsigned int& b) const
01441 {
01442 if(a == b)
01443 {
01444 return(1);
01445 }
01446 else
01447 {
01448 return(0);
01449 }
01450 }
01451
01452 }
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470