PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // PLearn (A C++ Machine Learning Library) 00004 // Copyright (C) 1998 Pascal Vincent 00005 // Copyright (C) 1999-2002 Pascal Vincent, Yoshua Bengio and University of Montreal 00006 // 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 00038 00039 /* ******************************************************* 00040 * $Id: Variable.h 9177 2008-06-26 17:50:25Z tihocan $ 00041 * This file is part of the PLearn library. 00042 ******************************************************* */ 00043 00044 #ifndef Variable_INC 00045 #define Variable_INC 00046 00047 #include <plearn/base/Object.h> 00048 #include <plearn/math/TMat.h> 00049 00050 namespace PLearn { 00051 using namespace std; 00052 00053 class Variable; 00054 class VarArray; 00055 class RandomVariable; 00056 class RandomVar; 00057 00058 class Var: public PP<Variable> 00059 { 00060 friend class RandomVariable; 00061 friend class RandomVar; 00062 00063 public: 00064 Var(); 00065 Var(Variable* v); 00066 Var(Variable* v, const char* name); 00067 Var(const Var& other); 00068 Var(const Var& other, const char* name); 00069 Var(const Var &other, const string &name); 00070 explicit Var(int the_length, int width_=1); 00071 Var(int the_length, int the_width, const char* name); 00072 Var(int the_length, int the_width, const string &name); 00073 Var(int the_length, const char* name); 00074 Var(int the_length, const string &name); 00075 explicit Var(const Vec& vec, bool vertical=true); 00076 explicit Var(const Mat& mat); 00077 00078 int length() const; 00079 int width() const; 00080 00081 Var subVec(int start, int len, bool transpose=false) const; 00082 Var subMat(int i, int j, int sublength, int subwidth, bool transpose=false) const; 00083 Var row(int i, bool transpose=false) const; 00084 Var column(int j, bool transpose=false) const; 00085 Var operator()(int i) const; 00086 Var operator()(int i, int j) const; 00087 00089 Var operator[](int i) const; 00090 Var operator[](Var i) const; 00091 00093 Var operator()(Var index) const; 00094 00096 Var operator()(Var i, Var j) const; 00097 00098 void operator=(real f); 00099 void operator=(const Vec& v); 00100 void operator=(const Mat& m); 00101 }; 00102 00103 class Variable: public Object 00104 { 00105 00106 private: 00107 00108 typedef Object inherited; 00109 00110 public: 00111 00113 Variable() : varnum(++nvars), marked(false), varname(), allows_partial_update(false), 00114 gradient_status(0), valuedata(0), gradientdata(0), min_value(-FLT_MAX), 00115 max_value(FLT_MAX), dont_bprop_here(false) {} 00116 00117 protected: 00118 static void declareOptions(OptionList & ol); 00119 00121 static void declareMethods(RemoteMethodMap& rmm); 00122 00123 friend class Var; 00124 friend class RandomVariable; 00125 friend class ProductRandomVariable; 00126 friend class Function; 00127 00128 friend class UnaryVariable; 00129 friend class BinaryVariable; 00130 friend class NaryVariable; 00131 00132 public: 00133 static int nvars; 00134 int varnum; 00135 00136 protected: 00137 bool marked; 00138 string varname; 00139 00140 bool allows_partial_update; 00141 int gradient_status; 00142 TVec<int> rows_to_update; 00143 00144 public: 00145 Vec value; 00146 Vec gradient; 00147 Mat matValue; 00148 Mat matGradient; 00149 Vec rValue; 00150 Mat matRValue; 00151 Mat matDiagHessian; 00152 00153 real* valuedata; 00154 real* gradientdata; 00155 real min_value, max_value; 00156 Var g; 00157 Vec diaghessian; 00158 real* diaghessiandata; 00159 real* rvaluedata; 00160 bool dont_bprop_here; 00161 00162 public: 00163 Variable(int thelength, int thewidth, bool call_build_ = true); 00164 Variable(const Mat& m, bool call_build_ = true); 00165 00166 int length() const { return matValue.length(); } 00167 int width() const { return matValue.width(); } 00168 int size() const { return matValue.size(); } // length*width 00169 int nelems() const { return size(); } 00170 00177 virtual void recomputeSize(int& l, int& w) const; 00178 00182 void resize(int l, int w); 00183 00188 void sizeprop(); 00189 00191 virtual void setParents(const VarArray& parents); 00192 00194 Variable(const Variable& v); 00195 00196 private: 00197 void build_(); 00198 public: 00199 virtual void build(); 00200 00201 bool isScalar() const { return length()==1 && width()==1; } 00202 bool isVec() const { return length()==1 || width()==1; } 00203 bool isColumnVec() const { return width()==1; } 00204 bool isRowVec() const { return length()==1; } 00205 00206 PLEARN_DECLARE_ABSTRACT_OBJECT(Variable); 00207 00208 virtual void makeDeepCopyFromShallowCopy(CopiesMap& copies); 00209 00211 virtual void fprop() =0; 00213 00215 inline void sizefprop() 00216 { sizeprop(); fprop(); } 00217 00218 virtual void bprop() =0; 00224 virtual void bbprop(); 00226 virtual void fbprop(); 00228 virtual void fbbprop(); 00230 virtual void symbolicBprop(); 00231 00232 virtual void rfprop(); 00233 00234 virtual void copyValueInto(Vec v) { v << value; } 00235 virtual void copyGradientInto(Vec g) { g << gradient; } 00236 00237 // virtual void newwrite(PStream& out) const; 00238 00241 string getName() const; 00243 void setName(const string& the_name); 00244 bool nameIsSet() { return varname.size()>0; } 00245 00251 Mat defineValueLocation(const Mat& m); 00252 00258 Mat defineGradientLocation(const Mat& m); 00259 00260 virtual void printInfo(bool print_gradient=false) = 0; 00261 virtual void printInfos(bool print_gradient=false); 00262 00263 Var subVec(int start, int len, bool transpose=false); 00264 Var subMat(int i, int j, int sublength, int subwidth, bool transpose=false); 00265 Var row(int i, bool transpose=false) { return subMat(i,0,1,width(),transpose); } 00266 Var column(int j, bool transpose=false) { return subMat(0,j,length(),1,transpose); } 00267 00268 void setDontBpropHere(bool val) { dont_bprop_here = val; } 00269 void setKeepPositive() { min_value = 0; } 00270 void setMinValue(real minv=-FLT_MAX) { min_value = minv; } 00271 void setMaxValue(real maxv=FLT_MAX) { max_value = maxv; } 00272 void setBoxConstraint(real minv, real maxv) { min_value = minv; max_value = maxv; } 00273 00274 void setMark() { marked = true; } 00275 void clearMark() { marked = false; } 00276 bool isMarked() { return marked; } 00277 00278 void fillGradient(real value) { gradient.fill(value); } 00279 void fillValue(real val) { value.fill(val); } 00280 00283 void setValueSubMat(const Mat& submat, int istart, int jstart); 00284 00285 void clearRowsToUpdate() 00286 { 00287 rows_to_update.resize(0); 00288 gradient_status=0; 00289 } 00290 void clearGradient() 00291 { 00292 if(!allows_partial_update) 00293 gradient.clear(); 00294 else 00295 { 00296 for (int r=0;r<rows_to_update.length();r++) 00297 { 00298 int row = rows_to_update[r]; 00299 matGradient.row(row).clear(); 00300 } 00301 rows_to_update.resize(0); 00302 gradient_status=0; 00303 } 00304 } 00305 void clearDiagHessian(); 00306 void clearSymbolicGradient() { g = Var(); } 00307 00315 virtual bool update(real step_size, Vec direction_vec, 00316 real coeff = 1.0, real b = 0.0); 00317 00324 virtual bool update(Vec step_sizes, Vec direction_vec, 00325 real coeff = 1.0, real b = 0.0); 00326 00333 virtual bool update(real step_size, bool clear=false); 00334 00342 virtual bool update(Vec new_value); 00343 00346 virtual void updateAndClear(); 00347 00356 virtual void updateWithWeightDecay(real step_size, real weight_decay, 00357 bool L1, bool clear=true); 00358 00360 void allowPartialUpdates() 00361 { 00362 allows_partial_update=true; 00363 rows_to_update.resize(length()); // make sure that there are always enough elements 00364 rows_to_update.resize(0); 00365 gradient_status=0; 00366 } 00367 00369 void disallowPartialUpdates() 00370 { 00371 allows_partial_update = false; 00372 gradient_status=2; 00373 } 00374 00376 void updateRow(int row) 00377 { 00378 if (gradient_status!=2 && allows_partial_update && !rows_to_update.contains(row)) 00379 { 00380 rows_to_update.append(row); 00381 if (gradient_status==0) gradient_status=1; 00382 } 00383 } 00384 00391 real maxUpdate(Vec direction); 00392 00398 virtual bool markPath() =0; 00399 00402 virtual void buildPath(VarArray& proppath) =0; 00403 00404 virtual void oldread(istream& in); 00405 virtual void write(ostream& out) const; 00406 00407 00408 00409 00410 void copyFrom(const Vec& v) { value << v; } 00411 void copyTo(Vec& v) { v << value; } 00412 void copyGradientFrom(const Vec& v) { gradient << v; } 00413 void copyGradientTo(Vec& v) { v << gradient; } 00414 void makeSharedValue(real* x, int n); 00415 void makeSharedGradient(real* x, int n); 00416 00417 void makeSharedValue(PP<Storage<real> > storage, int offset_=0); 00418 void makeSharedGradient(PP<Storage<real> > storage, int offset_=0); 00419 void makeSharedValue(Vec& v, int offset_=0); 00420 void makeSharedGradient(Vec& v, int offset_=0); 00421 00422 void copyRValueFrom(const Vec& v) { resizeRValue(); rValue << v; } 00423 void copyRValueTo(Vec& v) { resizeRValue(); v << rValue; } 00424 void makeSharedRValue(real* x, int n); 00425 void makeSharedRValue(PP<Storage<real> > storage, int offset_=0); 00426 void makeSharedRValue(Vec& v, int offset_=0); 00427 00428 // make this var point to the same things as v, using default operator= 00429 void makePointTo(Variable* v) { 00430 value = v->value; 00431 valuedata = v->valuedata; 00432 matValue = v->matValue; 00433 gradient = v->gradient; 00434 matGradient = v->matGradient; 00435 gradientdata = v->gradientdata; 00436 rows_to_update = v->rows_to_update; 00437 rValue = v->rValue; 00438 matRValue = v->matRValue; 00439 matDiagHessian = v->matDiagHessian; 00440 diaghessian = v->diaghessian; 00441 diaghessiandata = v->diaghessiandata; 00442 rvaluedata = v->rvaluedata; 00443 } 00444 00445 virtual bool isConstant() { return false; } 00446 00453 virtual void fprop_from_all_sources(); 00454 00457 virtual VarArray sources() = 0; 00458 00461 virtual VarArray random_sources() = 0; 00462 00464 virtual VarArray ancestors() = 0; 00466 virtual void unmarkAncestors() = 0; 00467 00470 virtual VarArray parents() = 0; 00471 00473 virtual void accg(Var v); 00474 00477 virtual void verifyGradient(real step=0.001); 00478 00480 virtual void resizeDiagHessian(); 00481 00482 virtual void resizeRValue(); 00483 }; 00484 00485 DECLARE_OBJECT_PTR(Variable); 00486 DECLARE_OBJECT_PP(Var, Variable); 00487 00488 00489 void varDeepCopyField(Var& field, CopiesMap& copies); 00490 00491 00492 inline Var Var::row(int i, bool transpose) const 00493 { 00494 return subMat(i, 0, 1, width(), transpose); 00495 } 00496 00497 inline Var Var::column(int j, bool transpose) const 00498 { 00499 return subMat(0, j, length(), 1, transpose); 00500 } 00501 00502 inline Var Var::operator()(int i) const 00503 { 00504 return row(i, false); 00505 } 00506 00507 inline Var Var::operator()(int i, int j) const 00508 { 00509 return subMat(i, j, 1, 1); 00510 } 00511 00512 } // end of namespace PLearn 00513 00514 #endif 00515 00516 00517 /* 00518 Local Variables: 00519 mode:c++ 00520 c-basic-offset:4 00521 c-file-style:"stroustrup" 00522 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00523 indent-tabs-mode:nil 00524 fill-column:79 00525 End: 00526 */ 00527 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :