PLearn 0.1
SquaredErrorCostModule.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // SquaredErrorCostModule.cc
00004 //
00005 // Copyright (C) 2006 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 "SquaredErrorCostModule.h"
00042 #include <plearn/math/TMat_maths.h>
00043 
00044 namespace PLearn {
00045 using namespace std;
00046 
00047 PLEARN_IMPLEMENT_OBJECT(
00048     SquaredErrorCostModule,
00049     "Computes the sum of squared difference between input and target.",
00050     "");
00051 
00052 SquaredErrorCostModule::SquaredErrorCostModule()
00053 {
00054     output_size = 1;
00055 }
00056 
00057 void SquaredErrorCostModule::declareOptions(OptionList& ol)
00058 {
00059     // declareOption(ol, "myoption", &SquaredErrorCostModule::myoption,
00060     //               OptionBase::buildoption,
00061     //               "Help text describing this option");
00062 
00063     // Now call the parent class' declareOptions
00064     inherited::declareOptions(ol);
00065 }
00066 
00068 // build_ //
00070 void SquaredErrorCostModule::build_()
00071 {
00072     target_size = input_size;
00073 }
00074 
00076 // build //
00078 void SquaredErrorCostModule::build()
00079 {
00080     inherited::build();
00081     build_();
00082 }
00083 
00084 
00086 // makeDeepCopyFromShallowCopy //
00088 void SquaredErrorCostModule::makeDeepCopyFromShallowCopy(CopiesMap& copies)
00089 {
00090     inherited::makeDeepCopyFromShallowCopy(copies);
00091 }
00092 
00093 
00095 // fprop //
00097 void SquaredErrorCostModule::fprop(const TVec<Mat*>& ports_value)
00098 {
00099     PLASSERT( ports_value.length() == 3 );
00100     Mat* pred = ports_value[0];
00101     Mat* target = ports_value[1];
00102     Mat* mse = ports_value[2];
00103     if (mse && mse->isEmpty()) {
00104         PLASSERT( pred && !pred->isEmpty() && target && !target->isEmpty() );
00105         mse->resize(pred->length(), 1);
00106         // TODO It may be possible to come up with a more efficient
00107         // implementation.
00108         for (int i = 0; i < pred->length(); i++) {
00109             (*mse)(i, 0) = powdistance( (*pred)(i), (*target)(i) );
00110         }
00111     }
00112     checkProp(ports_value);
00113 }
00114 
00115 void SquaredErrorCostModule::fprop(const Vec& input, const Vec& target,
00116                                    Vec& cost) const
00117 {
00118     PLASSERT( input.size() == input_size );
00119     PLASSERT( target.size() == target_size );
00120     cost.resize( output_size );
00121 
00122     cost[0] = powdistance( input, target );
00123 }
00124 
00126 // bpropUpdate //
00128 void SquaredErrorCostModule::bpropUpdate(const Vec& input, const Vec& target,
00129                                          real cost, Vec& input_gradient,
00130                                          bool accumulate)
00131 {
00132     PLASSERT( input.size() == input_size );
00133     PLASSERT( target.size() == target_size );
00134 
00135     if( accumulate )
00136     {
00137         PLASSERT_MSG( input_gradient.size() == input_size,
00138                       "Cannot resize input_gradient AND accumulate into it" );
00139     }
00140     else
00141     {
00142         input_gradient.resize( input_size );
00143         input_gradient.clear();
00144     }
00145 
00146     // input_gradient = 2*(input - target)
00147     for( int i=0 ; i<input_size ; i++ )
00148     {
00149         input_gradient[i] += 2*(input[i] - target[i]);
00150     }
00151 }
00152 
00153 void SquaredErrorCostModule::bpropUpdate(const Mat& inputs, const Mat& targets,
00154             const Vec& costs, Mat& input_gradients, bool accumulate)
00155 {
00156     PLASSERT( inputs.width() == input_size );
00157     PLASSERT( targets.width() == target_size );
00158 
00159     if( accumulate )
00160     {
00161         PLASSERT_MSG( input_gradients.width() == input_size &&
00162                       input_gradients.length() == inputs.length(),
00163                       "Cannot resize input_gradients AND accumulate into it" );
00164     }
00165     else
00166     {
00167         input_gradients.resize( inputs.length(), input_size );
00168         input_gradients.clear();
00169     }
00170 
00171     // input_gradient = 2*(input - target)
00172     // TODO This is a dumb unefficient implementation, for testing purpose.
00173     for (int k = 0; k < inputs.length(); k++)
00174         for( int i=0 ; i<input_size ; i++ )
00175         {
00176             input_gradients(k, i) += 2*(inputs(k, i) - targets(k, i));
00177         }
00178 }
00179 
00181 // bbpropUpdate //
00183 void SquaredErrorCostModule::bbpropUpdate(const Vec& input, const Vec& target,
00184                                           real cost,
00185                                           Vec& input_gradient,
00186                                           Vec& input_diag_hessian,
00187                                           bool accumulate)
00188 {
00189     if( accumulate )
00190     {
00191         PLASSERT_MSG( input_diag_hessian.size() == input_size,
00192                       "Cannot resize input_diag_hessian AND accumulate into it"
00193                     );
00194         input_diag_hessian += real(2.);
00195     }
00196     else
00197     {
00198         input_diag_hessian.resize( input_size );
00199         input_diag_hessian.fill( 2. );
00200     }
00201 
00202     bpropUpdate( input, target, cost, input_gradient, accumulate );
00203 }
00204 
00205 TVec<string> SquaredErrorCostModule::costNames()
00206 {
00207     if (name == "" || name == classname())
00208         return TVec<string>(1, "mse");
00209     else
00210         return TVec<string>(1, name + ".mse");
00211 }
00212 
00213 } // end of namespace PLearn
00214 
00215 
00216 /*
00217   Local Variables:
00218   mode:c++
00219   c-basic-offset:4
00220   c-file-style:"stroustrup"
00221   c-file-offsets:((innamespace . 0)(inline-open . 0))
00222   indent-tabs-mode:nil
00223   fill-column:79
00224   End:
00225 */
00226 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines