PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // ForwardModule.cc 00004 // 00005 // Copyright (C) 2007 Jerome Louradour 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: Jerome Louradour 00036 00041 #include "ForwardModule.h" 00042 00043 namespace PLearn { 00044 using namespace std; 00045 00046 PLEARN_IMPLEMENT_OBJECT( 00047 ForwardModule, 00048 "Module that simply forwards all calls to an underlying module.", 00049 "The underlying module may be chosen among a list of different modules,\n" 00050 "through the option 'forward_to'.\n" 00051 ); 00052 00054 // ForwardModule // 00056 ForwardModule::ForwardModule(const string& the_name, bool call_build_): 00057 inherited(the_name.empty() && call_build_ ? classname() : the_name, 00058 call_build_), 00059 forget_all(true), 00060 current(-1) 00061 { 00062 if (call_build_) 00063 build_(); 00064 } 00065 00067 // declareOptions // 00069 void ForwardModule::declareOptions(OptionList& ol) 00070 { 00071 00072 // 'build' options. 00073 00074 declareOption(ol, "modules", &ForwardModule::modules, 00075 OptionBase::buildoption, 00076 "The list of modules that can be used to forward calls."); 00077 00078 declareOption(ol, "forward_to", &ForwardModule::forward_to, 00079 OptionBase::buildoption, 00080 "Name of the module currently being used. If empty, the first module\n" 00081 "in 'modules' will be used."); 00082 00083 declareOption(ol, "forget_all", &ForwardModule::forget_all, 00084 OptionBase::buildoption, 00085 "If set to 1, then the forget() method will call forget() on all\n" 00086 "modules. Otherwise, only the current module pointed by 'forward_to'\n" 00087 "will be forgotten."); 00088 00089 // 'nosave' options. 00090 00091 // 'current' is an option only so it can be modified in server mode for 00092 // instance, in order to bypass a call to build (yes, this is a hack!). 00093 declareOption(ol, "current", &ForwardModule::current, 00094 OptionBase::nosave, 00095 "Index in 'modules' of the module given by 'forward_to'."); 00096 00097 // Now call the parent class' declareOptions 00098 inherited::declareOptions(ol); 00099 00100 } 00101 00103 // build_ // 00105 void ForwardModule::build_() 00106 { 00107 current = -1; 00108 if (forward_to.empty()) 00109 current = 0; 00110 else { 00111 for (int i = 0; i < modules.length(); i++) { 00112 if (modules[i]->name == forward_to) { 00113 current = i; 00114 break; 00115 } 00116 } 00117 } 00118 PLCHECK( current >= 0 ); 00119 00120 // Forward random number generator to all underlying modules. Note that we 00121 // need to forward it to all modules because we call forget(). 00122 if (random_gen) { 00123 for (int i = 0; i < modules.length(); i++) { 00124 PP<OnlineLearningModule> mod = modules[i]; 00125 if (!mod->random_gen) { 00126 mod->random_gen = random_gen; 00127 mod->build(); 00128 mod->forget(); 00129 } 00130 } 00131 } 00132 } 00133 00135 // build // 00137 void ForwardModule::build() 00138 { 00139 inherited::build(); 00140 build_(); 00141 } 00142 00143 00145 // makeDeepCopyFromShallowCopy // 00147 void ForwardModule::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00148 { 00149 inherited::makeDeepCopyFromShallowCopy(copies); 00150 00151 deepCopyField(modules, copies); 00152 } 00153 00155 // fprop // 00157 void ForwardModule::fprop(const TVec<Mat*>& ports_value) 00158 { 00159 modules[current]->fprop(ports_value); 00160 } 00161 00163 // bpropAccUpdate // 00165 void ForwardModule::bpropAccUpdate(const TVec<Mat*>& ports_value, 00166 const TVec<Mat*>& ports_gradient) 00167 { 00168 modules[current]->bpropAccUpdate(ports_value, ports_gradient); 00169 } 00170 00172 // forget // 00174 void ForwardModule::forget() 00175 { 00176 if (forget_all) { 00177 for (int i = 0; i < modules.length(); i++) 00178 modules[i]->forget(); 00179 } else 00180 modules[current]->forget(); 00181 } 00182 00184 // finalize // 00186 void ForwardModule::finalize() 00187 { 00188 modules[current]->finalize(); 00189 } 00190 00192 // bpropDoesNothing // 00194 bool ForwardModule::bpropDoesNothing() 00195 { 00196 return modules[current]->bpropDoesNothing(); 00197 } 00198 00200 // setLearningRate // 00202 void ForwardModule::setLearningRate(real dynamic_learning_rate) 00203 { 00204 modules[current]->setLearningRate(dynamic_learning_rate); 00205 } 00206 00208 // getPorts // 00210 const TVec<string>& ForwardModule::getPorts() { 00211 return modules[current]->getPorts(); 00212 } 00213 00215 // getPortSizes // 00217 const TMat<int>& ForwardModule::getPortSizes() 00218 { 00219 return modules[current]->getPortSizes(); 00220 } 00221 00222 } 00223 // end of namespace PLearn 00224 00225 00226 /* 00227 Local Variables: 00228 mode:c++ 00229 c-basic-offset:4 00230 c-file-style:"stroustrup" 00231 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00232 indent-tabs-mode:nil 00233 fill-column:79 00234 End: 00235 */ 00236 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :