00001 /****************************************************************************************************************/ 00002 /* */ 00003 /* OpenNN: Open Neural Networks Library */ 00004 /* www.opennn.cimne.com */ 00005 /* */ 00006 /* I N D E P E N D E N T P A R A M E T E R S E R R O R C L A S S */ 00007 /* */ 00008 /* Roberto Lopez */ 00009 /* International Center for Numerical Methods in Engineering (CIMNE) */ 00010 /* Technical University of Catalonia (UPC) */ 00011 /* Barcelona, Spain */ 00012 /* E-mail: rlopez@cimne.upc.edu */ 00013 /* */ 00014 /****************************************************************************************************************/ 00015 00016 // System includes 00017 00018 #include <iostream> 00019 #include <fstream> 00020 #include <cmath> 00021 #include <sstream> 00022 #include <string> 00023 #include <limits> 00024 00025 // OpenNN includes 00026 00027 #include "independent_parameters_error.h" 00028 00029 // TinyXml includes 00030 00031 #include "../../parsers/tinyxml/tinyxml.h" 00032 00033 00034 namespace OpenNN 00035 { 00036 00037 // DEFAULT CONSTRUCTOR 00038 00042 00043 IndependentParametersError::IndependentParametersError(void) 00044 : PerformanceTerm() 00045 { 00046 construct_numerical_differentiation(); 00047 00048 set_default(); 00049 } 00050 00051 00052 // NEURAL NETWORK CONSTRUCTOR 00053 00058 00059 IndependentParametersError::IndependentParametersError(NeuralNetwork* new_neural_network_pointer) 00060 : PerformanceTerm(new_neural_network_pointer) 00061 { 00062 construct_numerical_differentiation(); 00063 00064 set_default(); 00065 } 00066 00067 00068 // XML CONSTRUCTOR 00069 00074 00075 IndependentParametersError::IndependentParametersError(TiXmlElement* independent_parameters_error_element) 00076 : PerformanceTerm(independent_parameters_error_element) 00077 { 00078 construct_numerical_differentiation(); 00079 00080 set_default(); 00081 } 00082 00083 00084 // DESTRUCTOR 00085 00087 00088 IndependentParametersError::~IndependentParametersError(void) 00089 { 00090 } 00091 00092 00093 // ASSIGNMENT OPERATOR 00094 00095 // FinalSolutionsError& operator = (const FinalSolutionsError&) method 00096 00098 00099 IndependentParametersError& IndependentParametersError::operator = (const IndependentParametersError& other_independent_parameters_error) 00100 { 00101 if(this != &other_independent_parameters_error) 00102 { 00103 *neural_network_pointer = *other_independent_parameters_error.neural_network_pointer; 00104 *data_set_pointer = *other_independent_parameters_error.data_set_pointer; 00105 *mathematical_model_pointer = *other_independent_parameters_error.mathematical_model_pointer; 00106 *numerical_differentiation_pointer = *other_independent_parameters_error.numerical_differentiation_pointer; 00107 display = other_independent_parameters_error.display; 00108 00109 target_independent_parameters = other_independent_parameters_error.target_independent_parameters; 00110 independent_parameters_errors_weights = other_independent_parameters_error.independent_parameters_errors_weights; 00111 } 00112 00113 return(*this); 00114 } 00115 00116 00117 // EQUAL TO OPERATOR 00118 00119 // bool operator == (const FinalSolutionsError&) const method 00120 00122 00123 bool IndependentParametersError::operator == (const IndependentParametersError& other_independent_parameters_error) const 00124 { 00125 if(*neural_network_pointer == *other_independent_parameters_error.neural_network_pointer 00126 && *mathematical_model_pointer == *other_independent_parameters_error.mathematical_model_pointer 00127 && *numerical_differentiation_pointer == *other_independent_parameters_error.numerical_differentiation_pointer 00128 && display == other_independent_parameters_error.display 00129 && target_independent_parameters == other_independent_parameters_error.target_independent_parameters 00130 && independent_parameters_errors_weights == other_independent_parameters_error.independent_parameters_errors_weights) 00131 { 00132 return(true); 00133 } 00134 else 00135 { 00136 return(false); 00137 } 00138 } 00139 00140 00141 // METHODS 00142 00143 00144 // const Vector<double>& get_target_independent_parameters(void) const method 00145 00147 00148 const Vector<double>& IndependentParametersError::get_target_independent_parameters(void) const 00149 { 00150 return(target_independent_parameters); 00151 } 00152 00153 00154 // const double& get_target_independent_parameter(const unsigned int&) const method 00155 00158 00159 const double& IndependentParametersError::get_target_independent_parameter(const unsigned int& i) const 00160 { 00161 return(target_independent_parameters[i]); 00162 } 00163 00164 00165 // const Vector<double>& get_independent_parameters_errors_weights(void) const method 00166 00168 00169 const Vector<double>& IndependentParametersError::get_independent_parameters_errors_weights(void) const 00170 { 00171 return(independent_parameters_errors_weights); 00172 } 00173 00174 00175 // const double& get_independent_parameter_error_weight(const unsigned int&) const method 00176 00179 00180 const double& IndependentParametersError::get_independent_parameter_error_weight(const unsigned int& i) const 00181 { 00182 return(independent_parameters_errors_weights[i]); 00183 } 00184 00185 00186 // void set_target_independent_parameters(const Vector<double>&) method 00187 00190 00191 void IndependentParametersError::set_target_independent_parameters(const Vector<double>& new_target_independent_parameters) 00192 { 00193 target_independent_parameters = new_target_independent_parameters; 00194 } 00195 00196 00197 // void set_target_independent_parameter(const unsigned int&, const double&) method 00198 00202 00203 void IndependentParametersError::set_target_independent_parameter(const unsigned int& i, const double& new_target_independent_parameter) 00204 { 00205 target_independent_parameters[i] = new_target_independent_parameter; 00206 } 00207 00208 00209 // void set_independent_parameters_errors_weights(const Vector<double>&) method 00210 00213 00214 void IndependentParametersError::set_independent_parameters_errors_weights(const Vector<double>& new_independent_parameters_errors_weights) 00215 { 00216 independent_parameters_errors_weights = new_independent_parameters_errors_weights; 00217 } 00218 00219 00220 // void set_independent_parameter_error_weight(const unsigned int&, const double&) method 00221 00225 00226 void IndependentParametersError::set_independent_parameter_error_weight(const unsigned int& i, const double& new_independent_parameter_error_weight) 00227 { 00228 independent_parameters_errors_weights[i] = new_independent_parameter_error_weight; 00229 } 00230 00231 00232 // void set_default(void) method 00233 00240 00241 void IndependentParametersError::set_default(void) 00242 { 00243 if(neural_network_pointer) 00244 { 00245 const IndependentParameters* independent_parameters_pointer = neural_network_pointer->get_independent_parameters_pointer(); 00246 00247 if(independent_parameters_pointer) 00248 { 00249 const unsigned int independent_parameters_number = independent_parameters_pointer->count_parameters_number(); 00250 00251 target_independent_parameters.set(independent_parameters_number, 0.0); 00252 00253 independent_parameters_errors_weights.set(independent_parameters_number, 1.0); 00254 } 00255 } 00256 else 00257 { 00258 target_independent_parameters.set(); 00259 independent_parameters_errors_weights.set(); 00260 } 00261 00262 display = true; 00263 } 00264 00265 00266 // void check(void) const method 00267 00271 00272 void IndependentParametersError::check(void) const 00273 { 00274 std::ostringstream buffer; 00275 00276 // Neural network stuff 00277 00278 if(!neural_network_pointer) 00279 { 00280 buffer << "OpenNN Exception: IndependentParametersError class.\n" 00281 << "void check(void) const method.\n" 00282 << "Pointer to neural network is NULL.\n"; 00283 00284 throw std::logic_error(buffer.str().c_str()); 00285 } 00286 00287 const IndependentParameters* independent_parameters_pointer = neural_network_pointer->get_independent_parameters_pointer(); 00288 00289 if(!independent_parameters_pointer) 00290 { 00291 buffer << "OpenNN Exception: IndependentParametersError class.\n" 00292 << "void check(void) const method.\n" 00293 << "Pointer to independent parameters is NULL.\n"; 00294 00295 throw std::logic_error(buffer.str().c_str()); 00296 } 00297 00298 const unsigned int independent_parameters_number = independent_parameters_pointer->count_parameters_number(); 00299 00300 if(independent_parameters_number == 0) 00301 { 00302 buffer << "OpenNN Exception: IndependentParametersError class.\n" 00303 << "void check(void) const method.\n" 00304 << "Number of independent parameters is zero.\n"; 00305 00306 throw std::logic_error(buffer.str().c_str()); 00307 } 00308 00309 // Mathematical model stuff 00310 00311 if(!mathematical_model_pointer) 00312 { 00313 buffer << "OpenNN Exception: IndependentParametersError class.\n" 00314 << "void check(void) const method.\n" 00315 << "Pointer to mathematical model is NULL.\n"; 00316 00317 throw std::logic_error(buffer.str().c_str()); 00318 } 00319 00320 // Independent parameters error stuff 00321 00322 const unsigned int target_independent_parameters_size = target_independent_parameters.size(); 00323 00324 if(target_independent_parameters_size != independent_parameters_number) 00325 { 00326 buffer << "OpenNN Exception: IndependentParametersError class." << std::endl 00327 << "double calculate_evaluation(void) const method." << std::endl 00328 << "Size of target independent parameters must be equal to number of independent parameters." << std::endl; 00329 00330 throw std::logic_error(buffer.str().c_str()); 00331 } 00332 00333 const unsigned int independent_parameters_errors_weights_size = independent_parameters_errors_weights.size(); 00334 00335 if(independent_parameters_errors_weights_size != independent_parameters_number) 00336 { 00337 buffer << "OpenNN Exception: IndependentParametersError class." << std::endl 00338 << "double calculate_evaluation(void) const method." << std::endl 00339 << "Size of independent parameters errors weights must be equal to number of independent parameters." << std::endl; 00340 00341 throw std::logic_error(buffer.str().c_str()); 00342 } 00343 00344 } 00345 00346 00347 // double calculate_evaluation(void) const method 00348 00350 00351 double IndependentParametersError::calculate_evaluation(void) const 00352 { 00353 // Neural network stuff 00354 00355 #ifdef _DEBUG 00356 00357 check(); 00358 00359 #endif 00360 00361 // Neural network stuff 00362 00363 const IndependentParameters* independent_parameters_pointer = neural_network_pointer->get_independent_parameters_pointer(); 00364 00365 const Vector<double> independent_parameters = independent_parameters_pointer->get_parameters(); 00366 00367 const Vector<double> independent_parameters_error = independent_parameters - target_independent_parameters; 00368 00369 return((independent_parameters_errors_weights*independent_parameters_error*independent_parameters_error).calculate_sum()); 00370 } 00371 00372 00373 // double calculate_evaluation(const Vector<double>&) const method 00374 00376 00377 double IndependentParametersError::calculate_evaluation(const Vector<double>& parameters) const 00378 { 00379 // Neural network stuff 00380 00381 #ifdef _DEBUG 00382 00383 check(); 00384 00385 #endif 00386 00387 00388 #ifdef _DEBUG 00389 00390 const unsigned int size = parameters.size(); 00391 00392 const unsigned int parameters_number = neural_network_pointer->count_parameters_number(); 00393 00394 if(size != parameters_number) 00395 { 00396 std::ostringstream buffer; 00397 00398 buffer << "OpenNN Exception: IndependentParametersError class." << std::endl 00399 << "double calculate_evaluation(const Vector<double>&) const method." << std::endl 00400 << "Size of parameters (" << size << ") must be equal to number of parameters (" << parameters_number << ")." << std::endl; 00401 00402 throw std::logic_error(buffer.str().c_str()); 00403 } 00404 00405 #endif 00406 00407 NeuralNetwork neural_network_copy(*neural_network_pointer); 00408 00409 neural_network_copy.set_parameters(parameters); 00410 00411 IndependentParametersError independent_parameters_error_copy(*this); 00412 00413 independent_parameters_error_copy.set_neural_network_pointer(&neural_network_copy); 00414 00415 return(independent_parameters_error_copy.calculate_evaluation()); 00416 } 00417 00418 00419 // Vector<double> calculate_gradient(void) const method 00420 00421 Vector<double> IndependentParametersError::calculate_gradient(void) const 00422 { 00423 // Neural network stuff 00424 00425 #ifdef _DEBUG 00426 00427 check(); 00428 00429 #endif 00430 00431 const unsigned int parameters_number = neural_network_pointer->count_parameters_number(); 00432 00433 const IndependentParameters* independent_parameters_pointer = neural_network_pointer->get_independent_parameters_pointer(); 00434 00435 const unsigned int independent_parameters_number = independent_parameters_pointer->count_parameters_number(); 00436 00437 const unsigned int multilayer_perceptron_parameters_number = parameters_number - independent_parameters_number; 00438 00439 Vector<double> multilayer_perceptron_gradient(multilayer_perceptron_parameters_number, 0.0); 00440 00441 const Vector<double> independent_parameters = independent_parameters_pointer->get_parameters(); 00442 00443 const Vector<double> independent_parameters_gradient = (independent_parameters - target_independent_parameters)*2.0; 00444 00445 return(multilayer_perceptron_gradient.get_assembly(independent_parameters_gradient)); 00446 } 00447 00448 00449 // Matrix<double> calculate_Hessian(void) const method 00450 00451 Matrix<double> IndependentParametersError::calculate_Hessian(void) const 00452 { 00453 // Neural network stuff 00454 00455 #ifdef _DEBUG 00456 00457 check(); 00458 00459 #endif 00460 00461 const unsigned int parameters_number = neural_network_pointer->count_parameters_number(); 00462 00463 const IndependentParameters* independent_parameters_pointer = neural_network_pointer->get_independent_parameters_pointer(); 00464 00465 const unsigned int independent_parameters_number = independent_parameters_pointer->count_parameters_number(); 00466 00467 const unsigned int multilayer_perceptron_parameters_number = parameters_number - independent_parameters_number; 00468 00469 Matrix<double> Hessian(parameters_number, parameters_number, 0.0); 00470 00471 for(unsigned int i = multilayer_perceptron_parameters_number; i < parameters_number; i++) 00472 { 00473 for(unsigned int j = multilayer_perceptron_parameters_number; j < parameters_number; j++) 00474 { 00475 Hessian[i][j] = 2.0; 00476 } 00477 } 00478 00479 return(Hessian); 00480 } 00481 00482 00483 // std::string write_performance_term_type(void) const method 00484 00486 00487 std::string IndependentParametersError::write_performance_term_type(void) const 00488 { 00489 return("INDEPENDENT_PARAMETERS_ERROR"); 00490 } 00491 00492 00493 // std::string write_information(void) const method 00494 00495 std::string IndependentParametersError::write_information(void) const 00496 { 00497 std::ostringstream buffer; 00498 00499 buffer << "Independent parameters error: " << calculate_evaluation() << "\n"; 00500 00501 return(buffer.str()); 00502 } 00503 00504 00505 // TiXmlElement* to_XML(void) method method 00506 00508 00509 TiXmlElement* IndependentParametersError::to_XML(void) const 00510 { 00511 std::ostringstream buffer; 00512 00513 // Independent parameters error 00514 00515 TiXmlElement* independent_parameters_error_element = new TiXmlElement("IndependentParametersError"); 00516 independent_parameters_error_element->SetAttribute("Version", 4); 00517 00518 // Numerical differentiation 00519 00520 if(numerical_differentiation_pointer) 00521 { 00522 TiXmlElement* element = numerical_differentiation_pointer->to_XML(); 00523 independent_parameters_error_element->LinkEndChild(element); 00524 } 00525 00526 // Target independent parameters 00527 00528 { 00529 TiXmlElement* element = new TiXmlElement("TargetIndependentParamters"); 00530 independent_parameters_error_element->LinkEndChild(element); 00531 00532 buffer.str(""); 00533 buffer << target_independent_parameters; 00534 00535 TiXmlText* text = new TiXmlText(buffer.str().c_str()); 00536 element->LinkEndChild(text); 00537 } 00538 00539 // Independent parameters errors weights 00540 00541 { 00542 TiXmlElement* element = new TiXmlElement("IndependentParametersErrorsWeights"); 00543 independent_parameters_error_element->LinkEndChild(element); 00544 00545 buffer.str(""); 00546 buffer << independent_parameters_errors_weights; 00547 00548 TiXmlText* text = new TiXmlText(buffer.str().c_str()); 00549 element->LinkEndChild(text); 00550 } 00551 00552 // Display 00553 00554 { 00555 TiXmlElement* display_element = new TiXmlElement("Display"); 00556 independent_parameters_error_element->LinkEndChild(display_element); 00557 00558 buffer.str(""); 00559 buffer << display; 00560 00561 TiXmlText* display_text = new TiXmlText(buffer.str().c_str()); 00562 display_element->LinkEndChild(display_text); 00563 } 00564 00565 00566 return(independent_parameters_error_element); 00567 } 00568 00569 00570 // void from_XML(TiXmlElement*) method 00571 00572 // This method loads a sum squared error object from a XML file. 00573 // @param element Name of XML sum squared error file. 00574 00575 void IndependentParametersError::from_XML(TiXmlElement* independent_parameters_error_element) 00576 { 00577 if(independent_parameters_error_element) 00578 { 00579 // Display 00580 { 00581 TiXmlElement* display_element = independent_parameters_error_element->FirstChildElement("Display"); 00582 00583 if(display_element) 00584 { 00585 std::string new_display_string = display_element->GetText(); 00586 00587 try 00588 { 00589 set_display(new_display_string != "0"); 00590 } 00591 catch(std::exception& e) 00592 { 00593 std::cout << e.what() << std::endl; 00594 } 00595 } 00596 } 00597 } 00598 } 00599 00600 00601 } 00602 00603 00604 // OpenNN: Open Neural Networks Library. 00605 // Copyright (C) 2005-2012 Roberto Lopez 00606 // 00607 // This library is free software; you can redistribute it and/or 00608 // modify it under the terms of the GNU Lesser General Public 00609 // License as published by the Free Software Foundation; either 00610 // version 2.1 of the License, or any later version. 00611 // 00612 // This library is distributed in the hope that it will be useful, 00613 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00614 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00615 // Lesser General Public License for more details. 00616 // You should have received a copy of the GNU Lesser General Public 00617 // License along with this library; if not, write to the Free Software 00618 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA