00001 /****************************************************************************************************************/ 00002 /* */ 00003 /* OpenNN: Open Neural Networks Library */ 00004 /* www.opennn.cimne.com */ 00005 /* */ 00006 /* I N V E R S E S U M S Q U A R E D 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 // OpenNN includes 00017 00018 #include "../opennn.h" 00019 00020 #include "../neural_network/independent_parameters.h" 00021 00022 #include "inverse_sum_squared_error.h" 00023 00024 // System includes 00025 00026 #include <string> 00027 #include <sstream> 00028 #include <iostream> 00029 #include <fstream> 00030 #include <cmath> 00031 00032 namespace OpenNN 00033 { 00034 00035 // DEFAULT CONSTRUCTOR 00036 00040 00041 InverseSumSquaredError::InverseSumSquaredError(void) : PerformanceTerm() 00042 { 00043 construct_numerical_differentiation(); 00044 00045 set_default(); 00046 } 00047 00048 // NEURAL NETWORK CONSTRUCTOR 00049 00054 00055 InverseSumSquaredError::InverseSumSquaredError(NeuralNetwork* new_neural_network_pointer) 00056 : PerformanceTerm(new_neural_network_pointer) 00057 { 00058 construct_numerical_differentiation(); 00059 00060 set_default(); 00061 } 00062 00063 00064 // GENERAL CONSTRUCTOR 00065 00072 00073 InverseSumSquaredError::InverseSumSquaredError(NeuralNetwork* new_neural_network_pointer, MathematicalModel* new_mathematical_model_pointer, DataSet* new_data_set_pointer) 00074 : PerformanceTerm(new_neural_network_pointer, new_mathematical_model_pointer, new_data_set_pointer) 00075 { 00076 construct_numerical_differentiation(); 00077 00078 set_default(); 00079 } 00080 00081 00082 // XML CONSTRUCTOR 00083 00088 00089 InverseSumSquaredError::InverseSumSquaredError(TiXmlElement* inverse_sum_squared_error_element) : PerformanceTerm(inverse_sum_squared_error_element) 00090 { 00091 construct_numerical_differentiation(); 00092 00093 set_default(); 00094 } 00095 00096 00097 // DESTRUCTOR 00098 00101 00102 InverseSumSquaredError::~InverseSumSquaredError(void) 00103 { 00104 } 00105 00106 00107 // METHODS 00108 00109 // const UnknownsMethod& get_unknowns_method(void) const method 00110 00112 00113 const InverseSumSquaredError::UnknownsMethod& InverseSumSquaredError::get_unknowns_method(void) const 00114 { 00115 return(unknowns_method); 00116 } 00117 00118 00119 // std::string write_unknowns_method(void) const method 00120 00122 00123 std::string InverseSumSquaredError::write_unknowns_method(void) const 00124 { 00125 switch(unknowns_method) 00126 { 00127 case LookUpTable: 00128 { 00129 return("LookUpTable"); 00130 } 00131 break; 00132 00133 case IndependentParametersValues: 00134 { 00135 return("IndependentParametersValues"); 00136 } 00137 break; 00138 00139 default: 00140 { 00141 std::ostringstream buffer; 00142 00143 buffer << "OpenNN Exception: InverseSumSquaredError class.\n" 00144 << "std::string write_unknowns_method(void) const method.\n" 00145 << "Unknown property method.\n"; 00146 00147 throw std::logic_error(buffer.str()); 00148 } 00149 break; 00150 } 00151 } 00152 00153 00154 // void set_unknowns_method(const UnknownsMethod&) method 00155 00158 00159 void InverseSumSquaredError::set_unknowns_method(const UnknownsMethod& new_unknowns_method) 00160 { 00161 unknowns_method = new_unknowns_method; 00162 } 00163 00164 00165 // void set_unknowns_method(const std::string&) method 00166 00169 00170 void InverseSumSquaredError::set_unknowns_method(const std::string& new_unknowns_method) 00171 { 00172 if(new_unknowns_method == "LookUpTable") 00173 { 00174 set_unknowns_method(LookUpTable); 00175 } 00176 else if(new_unknowns_method == "IndependentParametersValues") 00177 { 00178 set_unknowns_method(IndependentParametersValues); 00179 } 00180 else 00181 { 00182 std::ostringstream buffer; 00183 00184 buffer << "OpenNN Exception: ScalingLayer class.\n" 00185 << "void set_unknowns_method(const std::string&) method.\n" 00186 << "Unknown property method: " << new_unknowns_method << ".\n"; 00187 00188 throw std::logic_error(buffer.str()); 00189 } 00190 } 00191 00192 00193 // void set_default(void) method 00194 00200 00201 void InverseSumSquaredError::set_default(void) 00202 { 00203 unknowns_method = IndependentParametersValues; 00204 00205 display = true; 00206 } 00207 00208 00209 // void check(void) const method 00210 00213 00214 void InverseSumSquaredError::check(void) const 00215 { 00216 std::ostringstream buffer; 00217 00218 // Neural network stuff 00219 00220 if(!neural_network_pointer) 00221 { 00222 buffer << "OpenNN Exception: InverseSumSquaredError class.\n" 00223 << "void check(void) const method.\n" 00224 << "Pointer to neural network is NULL.\n"; 00225 00226 throw std::logic_error(buffer.str().c_str()); 00227 } 00228 00229 const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer(); 00230 00231 if(!multilayer_perceptron_pointer) 00232 { 00233 buffer << "OpenNN Exception: InverseSumSquaredError class.\n" 00234 << "void check(void) const method.\n" 00235 << "Pointer to multilayer perceptron is NULL.\n"; 00236 00237 throw std::logic_error(buffer.str().c_str()); 00238 } 00239 00240 const unsigned int inputs_number = multilayer_perceptron_pointer->count_inputs_number(); 00241 const unsigned int outputs_number = multilayer_perceptron_pointer->count_outputs_number(); 00242 00243 if(inputs_number == 0) 00244 { 00245 buffer << "OpenNN Exception: InverseSumSquaredError class.\n" 00246 << "void check(void) const method.\n" 00247 << "Number of inputs in multilayer perceptron object is zero.\n"; 00248 00249 throw std::logic_error(buffer.str().c_str()); 00250 } 00251 00252 if(outputs_number == 0) 00253 { 00254 buffer << "OpenNN Exception: InverseSumSquaredError class.\n" 00255 << "void check(void) const method.\n" 00256 << "Number of outputs in multilayer perceptron object is zero.\n"; 00257 00258 throw std::logic_error(buffer.str().c_str()); 00259 } 00260 00261 // Mathematical model stuff 00262 00263 if(!mathematical_model_pointer) 00264 { 00265 buffer << "OpenNN Exception: InverseSumSquaredError class.\n" 00266 << "void check(void) const method.\n" 00267 << "Pointer to mathematical model is NULL.\n"; 00268 00269 throw std::logic_error(buffer.str().c_str()); 00270 } 00271 00272 // Data set stuff 00273 00274 if(!data_set_pointer) 00275 { 00276 buffer << "OpenNN Exception: InverseSumSquaredError class.\n" 00277 << "void check(void) const method.\n" 00278 << "Pointer to data set is NULL.\n"; 00279 00280 throw std::logic_error(buffer.str().c_str()); 00281 } 00282 00283 // Final solutions error stuff 00284 00285 } 00286 00287 00288 // double calculate_evaluation(void) const method 00289 00291 00292 double InverseSumSquaredError::calculate_evaluation(void) const 00293 { 00294 // Control sentence 00295 00296 #ifdef _DEBUG 00297 00298 check(); 00299 00300 #endif 00301 00302 // Data set stuff 00303 00304 const Matrix<double> training_input_data = data_set_pointer->arrange_training_input_data(); 00305 const Matrix<double> training_target_data = data_set_pointer->arrange_training_target_data(); 00306 00307 const unsigned int training_instances_number = training_input_data.get_rows_number(); 00308 00309 // Mathematical model stuff 00310 00311 const Matrix<double> training_solution_data = mathematical_model_pointer->calculate_dependent_variables(*neural_network_pointer, training_input_data); 00312 00313 return(training_solution_data.calculate_sum_squared_error(training_target_data)/(double)training_instances_number); 00314 } 00315 00316 00317 // double calculate_evaluation(const Vector<double>&) const method 00318 00319 double InverseSumSquaredError::calculate_evaluation(const Vector<double>& potential_parameters) const 00320 { 00321 // Control sentence (if debug) 00322 00323 #ifdef _DEBUG 00324 00325 check(); 00326 00327 #endif 00328 00329 #ifdef _DEBUG 00330 00331 const unsigned int size = potential_parameters.size(); 00332 00333 const unsigned int parameters_number = neural_network_pointer->count_parameters_number(); 00334 00335 if(size != parameters_number) 00336 { 00337 std::ostringstream buffer; 00338 00339 buffer << "OpenNN Exception: InverseSumSquaredError class.\n" 00340 << "double calculate_potential_objective(const Vector<double>&) const method.\n" 00341 << "Size (" << size << ") must be equal to number of parameters (" << parameters_number << ").\n"; 00342 00343 throw std::logic_error(buffer.str().c_str()); 00344 } 00345 00346 #endif 00347 00348 NeuralNetwork neural_network_copy(*neural_network_pointer); 00349 00350 neural_network_copy.set_parameters(potential_parameters); 00351 00352 InverseSumSquaredError inverse_sum_squared_error_copy(*this); 00353 00354 inverse_sum_squared_error_copy.set_neural_network_pointer(&neural_network_copy); 00355 00356 return(inverse_sum_squared_error_copy.calculate_evaluation()); 00357 } 00358 00359 00360 // double calculate_generalization_evaluation(void) const method 00361 00363 00364 double InverseSumSquaredError::calculate_generalization_evaluation(void) const 00365 { 00366 // Control sentence (if debug) 00367 00368 #ifdef _DEBUG 00369 00370 check(); 00371 00372 #endif 00373 00374 const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer(); 00375 00376 const unsigned int inputs_number = multilayer_perceptron_pointer->count_inputs_number(); 00377 const unsigned int outputs_number = multilayer_perceptron_pointer->count_outputs_number(); 00378 00379 const InstancesInformation& instances_information = data_set_pointer->get_instances_information(); 00380 00381 const unsigned int generalization_instances_number = instances_information.count_generalization_instances_number(); 00382 00383 Vector<double> inputs(inputs_number); 00384 Vector<double> outputs(outputs_number); 00385 Vector<double> targets(outputs_number); 00386 00387 double generalization_objective = 0.0; 00388 00389 for(unsigned int i = 0; i < generalization_instances_number; i++) 00390 { 00391 // Input vector 00392 00393 inputs = data_set_pointer->get_generalization_input_instance(i); 00394 00395 // Output vector 00396 00397 outputs = multilayer_perceptron_pointer->calculate_outputs(inputs); 00398 00399 // Target vector 00400 00401 targets = data_set_pointer->get_generalization_target_instance(i); 00402 00403 // Sum of squares error 00404 00405 generalization_objective += outputs.calculate_sum_squared_error(targets); 00406 } 00407 00408 return(generalization_objective); 00409 } 00410 00411 00412 // std::string write_performance_term_type(void) const method 00413 00415 00416 std::string InverseSumSquaredError::write_performance_term_type(void) const 00417 { 00418 return("INVERSE_SUM_SQUARED_ERROR"); 00419 } 00420 00421 00422 // TiXmlElement* to_XML(void) const method 00423 00426 00427 TiXmlElement* InverseSumSquaredError::to_XML(void) const 00428 { 00429 std::ostringstream buffer; 00430 00431 // Inverse sum squared error 00432 00433 TiXmlElement* inverse_sum_squared_error_element = new TiXmlElement("InverseSumSquaredError"); 00434 inverse_sum_squared_error_element->SetAttribute("Version", 4); 00435 00436 // Numerical differentiation 00437 00438 if(numerical_differentiation_pointer) 00439 { 00440 TiXmlElement* element = numerical_differentiation_pointer->to_XML(); 00441 inverse_sum_squared_error_element->LinkEndChild(element); 00442 } 00443 00444 // Unknowns method 00445 { 00446 TiXmlElement* element = new TiXmlElement("UnknownsMethod"); 00447 inverse_sum_squared_error_element->LinkEndChild(element); 00448 00449 TiXmlText* text = new TiXmlText(write_unknowns_method().c_str()); 00450 element->LinkEndChild(text); 00451 } 00452 00453 // Display 00454 00455 { 00456 TiXmlElement* display_element = new TiXmlElement("Display"); 00457 inverse_sum_squared_error_element->LinkEndChild(display_element); 00458 00459 buffer.str(""); 00460 buffer << display; 00461 00462 TiXmlText* display_text = new TiXmlText(buffer.str().c_str()); 00463 display_element->LinkEndChild(display_text); 00464 } 00465 00466 return(inverse_sum_squared_error_element); 00467 00468 } 00469 00470 00471 // void from_XML(TiXmlElement*) method 00472 00474 00475 void InverseSumSquaredError::from_XML(TiXmlElement*) 00476 { 00477 00478 } 00479 00480 } 00481 00482 00483 // OpenNN: Open Neural Networks Library. 00484 // Copyright (C) 2005-2012 Roberto Lopez 00485 // 00486 // This library is free software; you can redistribute it and/or 00487 // modify it under the terms of the GNU Lesser General Public 00488 // License as published by the Free Software Foundation; either 00489 // version 2.1 of the License, or any later version. 00490 // 00491 // This library is distributed in the hope that it will be useful, 00492 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00493 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00494 // Lesser General Public License for more details. 00495 // You should have received a copy of the GNU Lesser General Public 00496 // License along with this library; if not, write to the Free Software 00497 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA