PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // EmbeddedLearner.cc 00004 // 00005 // Copyright (C) 2002 Frederic Morin 00006 // Copyright (C) 2003 Pascal Vincent 00007 // 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions are met: 00010 // 00011 // 1. Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // 00014 // 2. Redistributions in binary form must reproduce the above copyright 00015 // notice, this list of conditions and the following disclaimer in the 00016 // documentation and/or other materials provided with the distribution. 00017 // 00018 // 3. The name of the authors may not be used to endorse or promote 00019 // products derived from this software without specific prior written 00020 // permission. 00021 // 00022 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00023 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00024 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00025 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00027 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00028 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00029 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00030 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00031 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00033 // This file is part of the PLearn library. For more information on the PLearn 00034 // library, go to the PLearn Web site at www.plearn.org 00035 00036 /* ******************************************************* 00037 * $Id: EmbeddedLearner.cc 9108 2008-06-06 20:46:44Z louradou $ 00038 ******************************************************* */ 00039 00041 #include "EmbeddedLearner.h" 00042 #include <assert.h> 00043 00044 #include <plearn/base/stringutils.h> 00045 00046 namespace PLearn { 00047 using namespace std; 00048 00049 // ###### EmbeddedLearner ###################################################### 00050 00051 PLEARN_IMPLEMENT_OBJECT( 00052 EmbeddedLearner, 00053 "Wraps an underlying learner", 00054 "EmbeddedLearner implements nothing but forwarding \n" 00055 "calls to an underlying learner. It is typically used as\n" 00056 "baseclass for learners that are built on top of another learner.\n" 00057 "Note that only the NECESSARY member functions are forwarded to\n" 00058 "the embedded learner; for others, we rely on the base class\n" 00059 "implementation (which themselves call forwarded functions).\n" 00060 "This makes it easier to override only a few select functions."); 00061 00062 EmbeddedLearner::EmbeddedLearner(string expdir_append_) 00063 : learner_(0), 00064 expdir_append(expdir_append_), 00065 forward_test(false), 00066 provide_learner_expdir(true), 00067 forward_nstages(false) 00068 { } 00069 00070 void EmbeddedLearner::declareOptions(OptionList& ol) 00071 { 00072 declareOption(ol, "learner", &EmbeddedLearner::learner_, 00073 OptionBase::buildoption, 00074 "The embedded learner"); 00075 00076 declareOption(ol, "provide_learner_expdir", &EmbeddedLearner::provide_learner_expdir, 00077 OptionBase::buildoption, 00078 "Whether or not to provide the underlying learner with an experiment " 00079 "directory one is given for this learner."); 00080 00081 declareOption(ol, "expdir_append", &EmbeddedLearner::expdir_append, 00082 OptionBase::buildoption, 00083 "A string which should be appended to the expdir for the inner learner;" 00084 "default = \"\"."); 00085 declareOption(ol, "forward_nstages",&EmbeddedLearner::forward_nstages, 00086 OptionBase::buildoption, 00087 "Did we forward our value of nstages to the sublearner before calling " 00088 "the sublearner train()"); 00089 00090 // 'forward_test' is set as a 'nosave' option: each subclass should set it 00091 // to either 'true' or 'false' depending on its specific needs. 00092 declareOption(ol, "forward_test", &EmbeddedLearner::forward_test, 00093 OptionBase::nosave, 00094 "If set to 1, will forward calls to test(..) method to the inner learner."); 00095 00096 inherited::declareOptions(ol); 00097 } 00098 00100 // declareMethods // 00102 void EmbeddedLearner::declareMethods(RemoteMethodMap& rmm) 00103 { 00104 // Insert a backpointer to remote methods; note that this is different from 00105 // declareOptions(). 00106 rmm.inherited(inherited::_getRemoteMethodMap_()); 00107 declareMethod( 00108 rmm, "getLearner", &EmbeddedLearner::getLearner, 00109 (BodyDoc("Returns the learnt embedded learner.\n"), 00110 RetDoc ("the learner"))); 00111 } 00112 00113 void EmbeddedLearner::build_() 00114 { 00115 if (!learner_) 00116 PLERROR("EmbeddedLearner::_build() - learner_ attribute is NULL"); 00117 } 00118 00120 // build // 00122 void EmbeddedLearner::build() 00123 { 00124 inherited::build(); 00125 build_(); 00126 } 00127 00128 00130 // setInnerLearnerTrainingSet // 00132 void EmbeddedLearner::setInnerLearnerTrainingSet(VMat training_set, 00133 bool call_forget) 00134 { 00135 PLASSERT( learner_ ); 00136 VMat ts = learner_->getTrainingSet(); 00137 bool training_set_has_changed = !ts || !(ts->looksTheSameAs(training_set)); 00138 // If 'call_forget' is true, learner_->forget() will be called 00139 // in this->forget() (called by PLearner::setTrainingSet a few lines below), 00140 // so we don't need to call it here. 00141 learner_->setTrainingSet(training_set, false); 00142 if (call_forget && !training_set_has_changed) 00143 // In this case, learner_->build() will not have been called, which may 00144 // cause trouble if it updates data from the training set. 00145 learner_->build(); 00146 } 00147 00149 // setTrainingSet // 00151 void EmbeddedLearner::setTrainingSet(VMat training_set, bool call_forget) 00152 { 00153 setInnerLearnerTrainingSet(training_set, call_forget); 00154 inherited::setTrainingSet(training_set, call_forget); 00155 } 00156 00158 // setValidationSet // 00160 void EmbeddedLearner::setValidationSet(VMat validset) 00161 { 00162 PLASSERT( learner_ ); 00163 inherited::setValidationSet(validset); 00164 learner_->setValidationSet(validset); 00165 } 00166 00167 void EmbeddedLearner::setTrainStatsCollector(PP<VecStatsCollector> statscol) 00168 { 00169 PLASSERT( learner_ ); 00170 inherited::setTrainStatsCollector(statscol); 00171 learner_->setTrainStatsCollector(statscol); 00172 } 00173 00174 void EmbeddedLearner::setExperimentDirectory(const PPath& the_expdir) 00175 { 00176 PLASSERT( learner_ ); 00177 inherited::setExperimentDirectory(the_expdir); 00178 if (provide_learner_expdir) { 00179 if (!the_expdir.isEmpty()) 00180 learner_->setExperimentDirectory(the_expdir / expdir_append); 00181 else 00182 learner_->setExperimentDirectory(""); 00183 } 00184 } 00185 00186 int EmbeddedLearner::inputsize() const 00187 { 00188 PLASSERT( learner_ ); 00189 return learner_->inputsize(); 00190 } 00191 00192 int EmbeddedLearner::targetsize() const 00193 { 00194 PLASSERT( learner_ ); 00195 return learner_->targetsize(); 00196 } 00197 00198 int EmbeddedLearner::outputsize() const 00199 { 00200 PLASSERT( learner_ ); 00201 return learner_->outputsize(); 00202 } 00203 00204 void EmbeddedLearner::forget() 00205 { 00206 PLASSERT( learner_ ); 00207 learner_->forget(); 00208 stage = 0; 00209 } 00210 00211 void EmbeddedLearner::train() 00212 { 00213 PLASSERT( learner_ ); 00214 if(forward_nstages) 00215 learner_->nstages = nstages; 00216 learner_->train(); 00217 stage = learner_->stage; 00218 } 00219 00220 void EmbeddedLearner::test(VMat testset, PP<VecStatsCollector> test_stats, 00221 VMat testoutputs, VMat testcosts) const 00222 { 00223 if (forward_test) { 00224 PLASSERT( learner_ ); 00225 learner_->test(testset, test_stats, testoutputs, testcosts); 00226 } else 00227 inherited::test(testset, test_stats, testoutputs, testcosts); 00228 } 00229 00230 void EmbeddedLearner::computeOutput(const Vec& input, Vec& output) const 00231 { 00232 PLASSERT( learner_ ); 00233 learner_->computeOutput(input, output); 00234 } 00235 00236 void EmbeddedLearner::computeCostsFromOutputs(const Vec& input, const Vec& output, 00237 const Vec& target, Vec& costs) const 00238 { 00239 PLASSERT( learner_ ); 00240 learner_->computeCostsFromOutputs(input, output, target, costs); 00241 } 00242 00243 void EmbeddedLearner::computeOutputAndCosts(const Vec& input, const Vec& target, 00244 Vec& output, Vec& costs) const 00245 { 00246 PLASSERT( learner_ ); 00247 learner_->computeOutputAndCosts(input, target, output, costs); 00248 } 00249 00250 void EmbeddedLearner::computeOutputsAndCosts(const Mat& input, const Mat& target, 00251 Mat& output, Mat& costs) const 00252 { 00253 PLASSERT( learner_ ); 00254 learner_->computeOutputsAndCosts(input, target, output, costs); 00255 } 00256 00257 bool EmbeddedLearner::computeConfidenceFromOutput( 00258 const Vec& input, const Vec& output, 00259 real probability, TVec< pair<real,real> >& intervals) const 00260 { 00261 PLASSERT( learner_ ); 00262 return learner_->computeConfidenceFromOutput(input,output,probability, 00263 intervals); 00264 } 00265 00266 TVec<string> EmbeddedLearner::getTestCostNames() const 00267 { 00268 PLASSERT( learner_ ); 00269 return learner_->getTestCostNames(); 00270 } 00271 00272 TVec<string> EmbeddedLearner::getTrainCostNames() const 00273 { 00274 PLASSERT( learner_ ); 00275 return learner_->getTrainCostNames(); 00276 } 00277 00278 TVec<string> EmbeddedLearner::getOutputNames() const 00279 { 00280 PLASSERT( learner_ ); 00281 return learner_->getOutputNames(); 00282 } 00283 00284 void EmbeddedLearner::resetInternalState() 00285 { 00286 PLASSERT( learner_ ); 00287 learner_->resetInternalState(); 00288 } 00289 00290 bool EmbeddedLearner::isStatefulLearner() const 00291 { 00292 PLASSERT( learner_ ); 00293 return learner_->isStatefulLearner(); 00294 } 00295 00296 void EmbeddedLearner::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00297 { 00298 inherited::makeDeepCopyFromShallowCopy(copies); 00299 00300 // ### Call deepCopyField on all "pointer-like" fields 00301 // ### that you wish to be deepCopied rather than 00302 // ### shallow-copied. 00303 deepCopyField(learner_, copies); 00304 } 00305 00306 } // end of namespace PLearn 00307 00308 00309 /* 00310 Local Variables: 00311 mode:c++ 00312 c-basic-offset:4 00313 c-file-style:"stroustrup" 00314 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00315 indent-tabs-mode:nil 00316 fill-column:79 00317 End: 00318 */ 00319 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :