PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // SemiSupervisedDBN.cc 00004 // 00005 // Copyright (C) 2008 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 00040 #include "SemiSupervisedDBN.h" 00041 00042 namespace PLearn { 00043 using namespace std; 00044 00045 PLEARN_IMPLEMENT_OBJECT( 00046 SemiSupervisedDBN, 00047 "Deep Belief Net, possibly supervised, trained only with CD", 00048 ""); 00049 00050 SemiSupervisedDBN::SemiSupervisedDBN(): 00051 learning_rate(0), 00052 n_classes(0), 00053 share_layers(false), 00054 n_layers(0) 00055 { 00056 random_gen = new PRandom(); 00057 } 00058 00059 void SemiSupervisedDBN::declareOptions(OptionList& ol) 00060 { 00061 // declareOption(ol, "myoption", &SemiSupervisedDBN::myoption, 00062 // OptionBase::buildoption, 00063 // "Help text describing this option"); 00064 00065 declareOption(ol, "", &SemiSupervisedDBN::, 00066 OptionBase::buildoption, 00067 ""); 00068 00069 // Now call the parent class' declareOptions 00070 inherited::declareOptions(ol); 00071 } 00072 00073 void SemiSupervisedDBN::build_() 00074 { 00075 bool rbms_need_build = false; 00076 if (layer_sizes.length() != rbms.size()+1) 00077 rbms_need_build = true; 00078 else 00079 { 00080 n_rbms = rbms.size(); 00081 for (int i=0; i<n_rbms; i++) 00082 { 00083 if (layer_sizes[i] != rbms[i]->input_size) 00084 { 00085 rbms_need_build = true; 00086 break; 00087 } 00088 if (layer_is_supervised[i] && (rbms[i]->target_size != n_target)) 00089 { 00090 rbms_need_build = true; 00091 break; 00092 } 00093 if (!layer_is_supervised[i] && (rbms[i]->target_size != 0)) 00094 { 00095 rbms_need_build = true; 00096 break; 00097 } 00098 if (layer_sizes[i+1] != rbms[i]->hidden_size) 00099 { 00100 rbms_need_build = true; 00101 break; 00102 } 00103 } 00104 } 00105 00106 if (rbms_need_build) 00107 build_rbms(); 00108 } 00109 00110 void SemiSupervisedDBN::build_rbms() 00111 { 00112 n_layers = layer_sizes.length(); 00113 n_rbms = n_layers - 1; 00114 rbms.resize(n_rbms); 00115 for (int i=0; i<n_rbms; i++) 00116 { 00117 if (rbms[i].isNull()) 00118 rbms[i] = new InferenceRBM; 00119 00120 if (i==0 && first_layer_type == "gaussian") 00121 rbms[i]->input_layer = new RBMGaussianLayer(layer_sizes[0]); 00122 else if (i>0 && share_layers) 00123 rbms[i]->input_layer = rbms[i-1]->hidden_layer; 00124 else 00125 rbms[i]->input_layer = new RBMGaussianLayer(layer_sizes[i]); 00126 00127 00128 if (layer_is_supervised[i]) 00129 rbms[i]->target = new RBMMultinomialLayer(n_classes); 00130 00131 rbms[i]->hidden = new RBMBinomialLayer(layer_sizes[i+1]); 00132 00133 rbms[i]->random_gen = random_gen; 00134 rbms[i]->build(); 00135 rbms[i]->setLearningRate(learning_rate); 00136 } 00137 } 00138 00139 00140 void SemiSupervisedDBN::build() 00141 { 00142 inherited::build(); 00143 build_(); 00144 } 00145 00146 00147 void SemiSupervisedDBN::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00148 { 00149 inherited::makeDeepCopyFromShallowCopy(copies); 00150 00151 // ### Call deepCopyField on all "pointer-like" fields 00152 // ### that you wish to be deepCopied rather than 00153 // ### shallow-copied. 00154 // ### ex: 00155 // deepCopyField(trainvec, copies); 00156 00157 // ### Remove this line when you have fully implemented this method. 00158 PLERROR("SemiSupervisedDBN::makeDeepCopyFromShallowCopy not fully (correctly) implemented yet!"); 00159 } 00160 00161 00162 int SemiSupervisedDBN::outputsize() const 00163 { 00164 // Compute and return the size of this learner's output (which typically 00165 // may depend on its inputsize(), targetsize() and set options). 00166 } 00167 00168 void SemiSupervisedDBN::forget() 00169 { 00173 00180 inherited::forget(); 00181 } 00182 00183 void SemiSupervisedDBN::train() 00184 { 00185 // The role of the train method is to bring the learner up to 00186 // stage==nstages, updating train_stats with training costs measured 00187 // on-line in the process. 00188 00189 /* TYPICAL CODE: 00190 00191 static Vec input; // static so we don't reallocate memory each time... 00192 static Vec target; // (but be careful that static means shared!) 00193 input.resize(inputsize()); // the train_set's inputsize() 00194 target.resize(targetsize()); // the train_set's targetsize() 00195 real weight; 00196 00197 // This generic PLearner method does a number of standard stuff useful for 00198 // (almost) any learner, and return 'false' if no training should take 00199 // place. See PLearner.h for more details. 00200 if (!initTrain()) 00201 return; 00202 00203 while(stage<nstages) 00204 { 00205 // clear statistics of previous epoch 00206 train_stats->forget(); 00207 00208 //... train for 1 stage, and update train_stats, 00209 // using train_set->getExample(input, target, weight) 00210 // and train_stats->update(train_costs) 00211 00212 ++stage; 00213 train_stats->finalize(); // finalize statistics for this epoch 00214 } 00215 */ 00216 } 00217 00218 00219 void SemiSupervisedDBN::computeOutput(const Vec& input, Vec& output) const 00220 { 00221 // Compute the output from the input. 00222 // int nout = outputsize(); 00223 // output.resize(nout); 00224 // ... 00225 } 00226 00227 void SemiSupervisedDBN::computeCostsFromOutputs(const Vec& input, const Vec& output, 00228 const Vec& target, Vec& costs) const 00229 { 00230 // Compute the costs from *already* computed output. 00231 // ... 00232 } 00233 00234 TVec<string> SemiSupervisedDBN::getTestCostNames() const 00235 { 00236 // Return the names of the costs computed by computeCostsFromOutputs 00237 // (these may or may not be exactly the same as what's returned by 00238 // getTrainCostNames). 00239 // ... 00240 } 00241 00242 TVec<string> SemiSupervisedDBN::getTrainCostNames() const 00243 { 00244 // Return the names of the objective costs that the train method computes 00245 // and for which it updates the VecStatsCollector train_stats 00246 // (these may or may not be exactly the same as what's returned by 00247 // getTestCostNames). 00248 // ... 00249 } 00250 00251 00252 } // end of namespace PLearn 00253 00254 00255 /* 00256 Local Variables: 00257 mode:c++ 00258 c-basic-offset:4 00259 c-file-style:"stroustrup" 00260 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00261 indent-tabs-mode:nil 00262 fill-column:79 00263 End: 00264 */ 00265 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :