PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // ClassErrorCostModule.cc 00004 // 00005 // Copyright (C) 2007 Pascal Lamblin 00006 // 00007 // Redistribution and use in source and binary forms, with or without 00008 // modification, are permitted provided that the following conditions are met: 00009 // 00010 // 1. Redistributions of source code must retain the above copyright 00011 // notice, this list of conditions and the following disclaimer. 00012 // 00013 // 2. Redistributions in binary form must reproduce the above copyright 00014 // notice, this list of conditions and the following disclaimer in the 00015 // documentation and/or other materials provided with the distribution. 00016 // 00017 // 3. The name of the authors may not be used to endorse or promote 00018 // products derived from this software without specific prior written 00019 // permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00022 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00023 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00024 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00025 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00026 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 // 00032 // This file is part of the PLearn library. For more information on the PLearn 00033 // library, go to the PLearn Web site at www.plearn.org 00034 00035 // Authors: Pascal Lamblin 00036 00041 #include "ClassErrorCostModule.h" 00042 #include <plearn/math/TMat_maths.h> 00043 00044 namespace PLearn { 00045 using namespace std; 00046 00047 PLEARN_IMPLEMENT_OBJECT( 00048 ClassErrorCostModule, 00049 "Multiclass classification error", 00050 "If input_size > 1, outputs 0 if target == argmax(input), 1 else\n" 00051 "If input_size == 1, outputs 0 if target is the closest integer to\n" 00052 "input[0], 1 else.\n" 00053 "There is no gradient to compute (it returns an error if you try), so if\n" 00054 "you use this module inside a CombiningCostsModule, put its weight to 0.\n" 00055 ); 00056 00057 ClassErrorCostModule::ClassErrorCostModule(): 00058 error_costs(Mat()) 00059 { 00060 output_size = 1; 00061 target_size = 1; 00062 } 00063 00064 void ClassErrorCostModule::declareOptions(OptionList& ol) 00065 { 00066 declareOption(ol, "error_costs", &ClassErrorCostModule::error_costs, 00067 OptionBase::buildoption, 00068 "A square matrix containing the cost for each type of error (default is 0/1 cost). " 00069 "The two dimensions correspond to: (true class, prediction)."); 00070 00071 // Now call the parent class' declareOptions 00072 inherited::declareOptions(ol); 00073 } 00074 00075 void ClassErrorCostModule::build_() 00076 { 00077 PLASSERT( output_size == 1 ); 00078 PLASSERT( target_size == 1 ); 00079 PLASSERT(error_costs.width() == error_costs.length()); 00080 if( !error_costs.isEmpty() && input_size > 1 ) 00081 PLASSERT(error_costs.length() == input_size); 00082 } 00083 00085 // build // 00087 void ClassErrorCostModule::build() 00088 { 00089 inherited::build(); 00090 build_(); 00091 } 00092 00094 // makeDeepCopyFromShallowCopy // 00096 void ClassErrorCostModule::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00097 { 00098 inherited::makeDeepCopyFromShallowCopy(copies); 00099 00100 deepCopyField(error_costs, copies); 00101 } 00102 00104 // fprop // 00106 void ClassErrorCostModule::fprop(const Vec& input, const Vec& target, 00107 Vec& cost) const 00108 { 00109 cost.resize( output_size ); 00110 fprop( input, target, cost[0] ); 00111 } 00112 00114 // fprop // 00116 void ClassErrorCostModule::fprop(const Vec& input, const Vec& target, 00117 real& cost) const 00118 { 00119 PLASSERT( input.size() == input_size ); 00120 PLASSERT( target.size() == target_size ); 00121 00122 if( error_costs.isEmpty() ) 00123 if( input_size == 1 ) // is target[0] the closest integer to input[0]? 00124 cost = ( round(input[0]) == round(target[0]) ) ? 0. : 1.; 00125 else // is target[0] equals to argmax(input)? 00126 cost = ( argmax(input) == int(round(target[0])) ) ? 0. : 1.; 00127 else 00128 if( input_size == 1 ) 00129 cost = error_costs( int(round(target[0])), int(round(input[0])) ); 00130 else 00131 cost = error_costs( int(round(target[0])), argmax(input) ); 00132 } 00133 00134 void ClassErrorCostModule::fprop(const Mat& inputs, const Mat& targets, 00135 Mat& costs) const 00136 { 00137 costs.resize( inputs.length(), output_size ); 00138 for (int i = 0; i < inputs.length(); i++) 00139 fprop(inputs(i), targets(i), costs(i, 0)); 00140 } 00141 00143 // bpropUpdate // 00145 void ClassErrorCostModule::bpropUpdate(const Vec& input, const Vec& target, 00146 real cost) 00147 { 00148 } 00149 00150 /* Not supposed to happen 00151 void ClassErrorCostModule::bpropUpdate(const Vec& input, const Vec& target, 00152 real cost, 00153 Vec& input_gradient, 00154 bool accumulate=false) 00155 { 00156 } 00157 */ 00158 00160 // bbpropUpdate // 00162 void ClassErrorCostModule::bbpropUpdate(const Vec& input, const Vec& target, 00163 real cost) 00164 { 00165 } 00166 00167 /* Not supposed to happen 00168 void ClassErrorCostModule::bbpropUpdate(const Vec& input, const Vec& target, 00169 real cost, 00170 Vec& input_gradient, 00171 Vec& input_diag_hessian, 00172 bool accumulate=false) 00173 { 00174 } 00175 */ 00176 00178 // forget // 00180 void ClassErrorCostModule::forget() 00181 { 00182 } 00183 00185 // name // 00187 TVec<string> ClassErrorCostModule::costNames() 00188 { 00189 if (name == "" || name == classname()) 00190 return TVec<string>(1, "class_error"); 00191 else 00192 return TVec<string>(1, name + ".class_error"); 00193 } 00194 00196 // bpropDoesNothing // 00198 bool ClassErrorCostModule::bpropDoesNothing() 00199 { 00200 return true; 00201 } 00202 00203 00204 } // end of namespace PLearn 00205 00206 00207 /* 00208 Local Variables: 00209 mode:c++ 00210 c-basic-offset:4 00211 c-file-style:"stroustrup" 00212 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00213 indent-tabs-mode:nil 00214 fill-column:79 00215 End: 00216 */ 00217 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :