PLearn 0.1
CompareLearner.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // CompareLearner.cc
00004 //
00005 // Copyright (C) 2004 Hugo Larochelle 
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 /* *******************************************************      
00036  * $Id: CompareLearner.cc 3994 2005-08-25 13:35:03Z chapados $ 
00037  ******************************************************* */
00038 
00039 // Authors: Hugo Larochelle
00040 
00044 #include "CompareLearner.h"
00045 #include <plearn/io/fileutils.h>
00046 
00047 namespace PLearn {
00048 using namespace std;
00049 
00050 CompareLearner::CompareLearner() 
00051     : learners(0)
00052 {
00053     build_();
00054 }
00055 
00056 PLEARN_IMPLEMENT_OBJECT(CompareLearner, "Learner that trains and compares different learners ", 
00057                         "This learner takes different learners, trains them and computes their\n"
00058                         "common costs in order to compare them. The learners and the names of the \n"
00059                         "learners are given by the user, and the common costs shared by all the \n" 
00060                         "learners are also specified by the user. The cost name [LEARNER]::[COST] \n"
00061                         "is the name of the cost [COST] for the learner named [LEARNER]. If a specifed learner \n"
00062                         "doesn't use this cost, its cost value is always MISSING_VALUE. Also, \n"
00063                         "the cost names difference_[COST]_[LEARNER1]_VS_[LEARNER2] and \n"
00064                         "abs_difference_[COST]_[LEARNER1]_VS_[LEARNER2] are the difference and \n"
00065                         "absolute difference of [COST]::[LEARNER1] and [COST]::[LEARNER2]. Note that \n"
00066                         "[LEARNER1] must appear before [LEARNER2] in the learner_names vector."
00067     );
00068 void CompareLearner::declareOptions(OptionList& ol)
00069 {
00070     declareOption(ol, "learners", &CompareLearner::learners, OptionBase::buildoption,
00071                   "learners to compare");
00072     declareOption(ol, "common_costs", &CompareLearner::common_costs, OptionBase::buildoption,
00073                   "common costs of the learners to compare");
00074     declareOption(ol, "learner_names", &CompareLearner::learner_names, OptionBase::buildoption,
00075                   "names of the learners");
00076 
00077     inherited::declareOptions(ol);
00078 }
00079 
00080 void CompareLearner::build_()
00081 {
00082     n_learners = learners.length();
00083     if(n_learners > 0)
00084     {
00085         learners_outputsize = learners[0]->outputsize();
00086         if(learner_names.length() != n_learners) PLERROR("Number of learner names is different from number of learners");
00087         costs_indexes.resize(n_learners,common_costs.length());
00088         TVec<string> test_costs;
00089         for(int i=0; i<n_learners; i++)
00090         {
00091             learners[i]->build();
00092             test_costs = learners[i]->getTestCostNames();
00093             for(int c=0; c<common_costs.length(); c++)
00094             {
00095                 costs_indexes(i,c) = test_costs.find(common_costs[c]);
00096             }
00097         }
00098     }
00099 }
00100 
00101 void CompareLearner::build()
00102 {
00103     inherited::build();
00104     build_();
00105 }
00106 
00107 
00108 void CompareLearner::makeDeepCopyFromShallowCopy(CopiesMap& copies)
00109 {
00110     inherited::makeDeepCopyFromShallowCopy(copies);
00111 
00112     deepCopyField(learners, copies);
00113     deepCopyField(learner_names, copies);
00114     deepCopyField(common_costs, copies);
00115     deepCopyField(costs_indexes, copies);
00116 
00117     //PLERROR("CompareLearner::makeDeepCopyFromShallowCopy not fully (correctly) implemented yet!");
00118 }
00119 
00120 
00121 int CompareLearner::outputsize() const
00122 {
00123     if(n_learners == 0) return 0;
00124     else return n_learners * learners_outputsize;
00125 }
00126 
00127 void CompareLearner::forget()
00128 {
00129     for(int i=0; i<learners.length(); i++)
00130         learners[i]->forget();
00131 }
00132     
00133 void CompareLearner::train()
00134 {
00135     for(int i=0; i<n_learners; i++)
00136         learners[i]->train();
00137 }
00138 
00139 
00140 void CompareLearner::computeOutput(const Vec& input, Vec& output) const
00141 {
00142     output.resize(outputsize());
00143     Vec output_i;
00144     for(int i=0; i<n_learners; i++)
00145     {
00146         output_i = output.subVec(i*learners_outputsize,learners_outputsize);
00147         learners[i]->computeOutput(input,output_i);
00148     }
00149 }    
00150 
00151 void CompareLearner::computeCostsFromOutputs(const Vec& input, const Vec& output, 
00152                                              const Vec& target, Vec& costs) const
00153 {
00154     Vec one_learner_costs;   
00155     costs.resize(0);
00156     Vec output_i;
00157     for(int i=0; i<n_learners; i++)
00158     {
00159         one_learner_costs.resize(learners[i]->getTestCostNames().length());
00160         output_i = output.subVec(i*learners_outputsize,learners_outputsize);
00161         learners[i]->computeCostsFromOutputs(input, output_i,target,one_learner_costs);
00162         for(int c=0; c<common_costs.length(); c++)
00163         {
00164             if(costs_indexes(i,c) == -1)
00165                 costs.append(MISSING_VALUE);
00166             else
00167                 costs.append(one_learner_costs[costs_indexes(i,c)]);
00168       
00169         }
00170     }
00171 
00172     for ( int m1=0; m1 < n_learners; m1++ )
00173         for ( int m2=(m1+1); m2 < n_learners; m2++ )
00174             for ( int cc=0; cc < common_costs.length(); cc++ )
00175             {
00176                 real diff = costs[m1*common_costs.length()+cc]-costs[m2*common_costs.length()+cc];
00177                 costs.append(diff);
00178                 costs.append(fabs(diff));
00179             }
00180 }                                
00181 
00182 TVec<string> CompareLearner::getTestCostNames() const
00183 {
00184     TVec<string> cost_names(0);
00185 
00186     for(int i=0; i<n_learners; i++)
00187     {
00188         for(int c=0; c<common_costs.length(); c++)
00189         {
00190             cost_names.append(learner_names[i] + "::" + common_costs[c]);
00191         }
00192     }
00193 
00194     for ( int m1=0; m1 < n_learners; m1++ )
00195         for ( int m2=(m1+1); m2 < n_learners; m2++ )
00196             for ( int cc=0; cc < common_costs.length(); cc++ )
00197             {
00198                 string postfix = common_costs[cc] + "_" + learner_names[m1] + "_VS_" + learner_names[m2];        
00199                 cost_names.append( "difference_" + postfix );
00200                 cost_names.append( "abs_difference_" + postfix );
00201             }
00202 
00203     return cost_names;
00204 }
00205 
00206 TVec<string> CompareLearner::getTrainCostNames() const
00207 {
00208     TVec<string> cost_names(0);
00209     TVec<string> cost_names_i;
00210     for(int i=0; i<n_learners; i++)
00211     {
00212         cost_names_i = learners[i]->getTrainCostNames();
00213         for(int c=0; c<cost_names_i.length(); c++)
00214             cost_names.append(learner_names[i] + "::" + cost_names_i[c]);
00215     }
00216 
00217     return cost_names;
00218 }
00219 
00220 void CompareLearner::setTrainStatsCollector(PP<VecStatsCollector> statscol)
00221 { 
00222     PP<VecStatsCollector> stat_i;
00223     for(int i=0; i<n_learners; i++)
00224     {
00225         stat_i = new VecStatsCollector();
00226         learners[i]->setTrainStatsCollector(stat_i); 
00227     }
00228 }
00229 
00230 void CompareLearner::setTrainingSet(VMat training_set, bool call_forget)
00231 { 
00232     for(int i=0; i<n_learners; i++)
00233     {
00234         learners[i]->setTrainingSet(training_set,call_forget);
00235     }
00236     if (call_forget)
00237         forget();
00238 }
00239 
00240 void CompareLearner::setValidationSet(VMat validset)
00241 { 
00242     for(int i=0; i<n_learners; i++)
00243     {
00244         learners[i]->setValidationSet(validset);
00245     }
00246 }
00247 
00248 void CompareLearner::setExperimentDirectory(const PPath& the_expdir) 
00249 { 
00250     if(the_expdir=="")
00251     {
00252         expdir = "";
00253         for(int i=0; i<n_learners; i++)
00254         {
00255             learners[i]->setExperimentDirectory(the_expdir);
00256         }
00257     }
00258     else
00259     {
00260         if(!force_mkdir(the_expdir))
00261             PLERROR("In PLearner::setExperimentDirectory Could not create experiment directory %s",the_expdir.c_str());
00262         expdir = the_expdir.absolute();
00263         string learner_expdir;
00264         for(int i=0; i<n_learners; i++)
00265         {
00266             learner_expdir = the_expdir.absolute() + "_" + learner_names[i];
00267             learners[i]->setExperimentDirectory(learner_expdir); 
00268         }
00269     }
00270 }
00271 
00272 } // end of namespace PLearn
00273 
00274 
00275 /*
00276   Local Variables:
00277   mode:c++
00278   c-basic-offset:4
00279   c-file-style:"stroustrup"
00280   c-file-offsets:((innamespace . 0)(inline-open . 0))
00281   indent-tabs-mode:nil
00282   fill-column:79
00283   End:
00284 */
00285 // 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