PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // TransformationLearner.h 00004 // 00005 // Copyright (C) 2007 Lysiane Bouchard 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: Lysiane Bouchard, Pascal Vincent 00036 00040 #ifndef TransformationLearner_INC 00041 #define TransformationLearner_INC 00042 00043 //PLEARN 00044 #include <plearn_learners/distributions/PDistribution.h> 00045 #include <plearn/math/plapack.h> 00046 #include <plearn/math/pl_math.h> 00047 #include <plearn_learners/distributions/PDistribution.h> 00048 #include <plearn/math/TMat_maths.h> 00049 #include <plearn/math/PRandom.h> 00050 #include <plearn/base/tuple.h> 00051 00052 //C++ 00053 #include <utility> 00054 #include <queue> 00055 #include <math.h> 00056 00057 #define TRANSFORM_FAMILY_LINEAR 0 00058 #define TRANSFORM_FAMILY_LINEAR_INCREMENT 1 00059 #define UNDEFINED -1 00060 #define INIT_MODE_DEFAULT 0 00061 #define INIT_MODE_RANDOM 1 00062 #define NOISE_ALPHA_NO_REG 1 00063 #define NOISE_BETA_NO_REG 0 00064 #define TRANSFORM_DISTRIBUTION_ALPHA_NO_REG 1 00065 #define BEHAVIOR_LEARNER 0 00066 #define BEHAVIOR_GENERATOR 1 00067 00068 namespace PLearn { 00069 00070 00071 00105 /**************************************************************************** 00106 *AUXILIARY CLASS RECONSTRUCTION CANDIDATE : 00107 * 00108 * 00109 * 00110 *Reconstruction Candidate objects are basically 4-tuples with the following format: 00111 * nKm x4 matrix 00112 * ------C1----------|---- C2------------|-- C3-----------|-- C4-----------| 00113 * index i in the | index j in the | index t of a | positive weight 00114 * training set of a | training set of a | transformation | 00115 * target point | a neighbour | | 00116 * | candidate | | 00117 * 00118 ***************************************************************************/ 00119 class ReconstructionCandidate 00120 { 00121 public: 00122 int targetIdx, neighborIdx, transformIdx; 00123 real weight; 00124 00125 ReconstructionCandidate(int targetIdx_=-1, int neighborIdx_=-1, int transformIdx_=-1, real weight_=0){ 00126 targetIdx = targetIdx_; 00127 neighborIdx = neighborIdx_; 00128 transformIdx = transformIdx_ ; 00129 weight = weight_; 00130 } 00131 }; 00132 00133 //Comparisons between ReconstructionCandidate objects 00134 inline bool operator<(const ReconstructionCandidate& o1 , 00135 const ReconstructionCandidate& o2) 00136 { 00137 // Will be used in storage process, in a priority queue. 00138 // With the following definitions, priority measure increases when weight 00139 // field decreases. 00140 // That is, we want to keep ReconstructionCandidate objects with lower 00141 // weights on top of the priority queue 00142 return o2.weight<o1.weight; 00143 } 00144 inline bool operator==(const ReconstructionCandidate& o1, 00145 const ReconstructionCandidate& o2) 00146 { 00147 return o1.weight==o2.weight; 00148 } 00149 00150 00151 //print/read ReconstructionCandidate objects 00152 inline PStream& operator<<(PStream& out, 00153 const ReconstructionCandidate& x) 00154 { 00155 out << tuple<int, int, int, real>(x.targetIdx, x.neighborIdx, x.transformIdx, x.weight); 00156 return out; 00157 } 00158 inline PStream& operator>>(PStream& in, ReconstructionCandidate& x) 00159 { 00160 tuple<int, int, int, real> t; 00161 in >> t; 00162 tie(x.targetIdx, x.neighborIdx, x.transformIdx, x.weight) = t; 00163 return in; 00164 } 00165 00166 00167 00168 /*************************************************************************** 00169 * main class: TRANSFORMATION LEARNER 00170 * 00171 * 00172 * 00173 * Learns a finite set of linear transformations. That is, learns how to move from 00174 * one point to another. 00175 */ 00176 class TransformationLearner : public PDistribution 00177 { 00178 typedef PDistribution inherited; 00179 00180 public: 00181 //##### Public Build Options ############################################ 00182 00184 int behavior; 00185 00186 00190 real minimumProba; 00191 00192 00193 //WHICH KIND OF TRANSFORMATION FUNCTIONS ... 00194 00196 int transformFamily; 00198 bool withBias; 00199 00200 //LEARNING MODE ... 00201 00204 bool learnNoiseVariance; 00205 00207 bool regOnNoiseVariance; 00208 00210 bool learnTransformDistribution; 00211 00213 bool regOnTransformDistribution; 00214 00220 bool emphasisOnDiversity; 00221 real diversityFactor; 00222 00223 00225 int initializationMode; 00226 00234 int largeEStepAPeriod; 00235 int largeEStepAOffset; 00236 int largeEStepBPeriod; 00237 int largeEStepBOffset; 00238 00242 int noiseVariancePeriod; 00243 int noiseVarianceOffset; 00244 00252 real noiseAlpha; 00253 real noiseBeta; 00254 00258 int transformDistributionPeriod; 00259 int transformDistributionOffset; 00260 00263 //(u1,u2,...,uK) with dirichlet prior probability : 00264 // p(u1,...,uK) = NormalisationCoeff(alpha)*u1^(alpha -1)*u2^(alpha -1)...*uK^(alpha - 1) 00265 //Note: if alpha = 1, it means all possibilities are equiprobable 00266 // (no regularization effect) 00267 real transformDistributionAlpha; 00268 00269 00271 int transformsPeriod; 00272 int transformsOffset; 00273 int biasPeriod; 00274 int biasOffset; 00275 00276 00277 00278 00279 //PARAMETERS OF THE DISTRIBUTION 00280 00287 real noiseVariance; 00288 00290 real transformsVariance; 00291 00293 int nbTransforms; 00294 00296 int nbNeighbors; 00297 00305 Vec transformDistribution; 00306 00307 00308 00309 public: 00310 //##### Public Member Functions ######################################### 00311 00313 // ### Make sure the implementation in the .cc 00314 // ### initializes all fields to reasonable default values. 00315 TransformationLearner(); 00316 00317 00318 //##### PDistribution Member Functions ################################## 00319 00320 00321 // virtual TVec<string> getTrainCostNames() const; 00322 00323 00325 virtual real log_density(const Vec& y) const; 00326 00329 virtual void generate(Vec& y) const ; 00330 00331 //### Override this method if you need it (and if your distribution can 00332 //### handle it. Default version calls PLERROR. 00337 // virtual void generatePredictorGivenPredicted(Vec& x, const Vec& y); 00338 00339 //### Override this method if you need it. Default version calls 00340 //### random_gen->manual_seed(g_seed) if g_seed !=0 00343 // virtual void resetGenerator(long g_seed) const; 00344 00345 // ### These methods may be overridden for efficiency purpose: 00346 /* 00347 //### Default version calls exp(log_density(y)) 00349 virtual real density(const Vec& y) const; 00350 00351 //### Default version calls setPredictorPredictedSises(0,-1) and generate 00356 virtual void generateJoint(Vec& xy); 00357 00358 //### Default version calls generateJoint and discards y 00363 virtual void generatePredictor(Vec& x); 00364 00365 //### Default version calls generateJoint and discards x 00370 virtual void generatePredicted(Vec& y); 00371 */ 00372 00373 00374 //##### PLearner Member Functions ####################################### 00375 00376 // ### Default version of inputsize returns learner->inputsize() 00377 // ### If this is not appropriate, you should uncomment this and define 00378 // ### it properly in the .cc 00379 virtual int inputsize() const; 00380 00388 virtual void forget(); 00389 00393 // ### You may remove this method if your distribution does not 00394 // ### implement it. 00395 virtual void train(); 00396 00397 00398 //##### PLearn::Object Protocol ######################################### 00399 00400 // Declares other standard object methods. 00401 // ### If your class is not instantiatable (it has pure virtual methods) 00402 // ### you should replace this by PLEARN_DECLARE_ABSTRACT_OBJECT_METHODS 00403 PLEARN_DECLARE_OBJECT(TransformationLearner); 00404 00405 00407 00410 void initTransformsParameters(); 00411 00414 void setTransformsParameters(TVec<Mat> transforms, Mat bias=Mat()); 00415 00416 00417 00418 00421 void initNoiseVariance(); 00422 00424 void setNoiseVariance(real nv); 00425 00428 void initTransformDistribution(); 00429 00431 void setTransformDistribution(Vec td); 00432 00433 00435 00437 void generatePredictedFrom(const Vec & source, Vec & sample)const; 00438 00440 void generatePredictedFrom(const Vec & source, Vec & sample, int transformIdx)const; 00441 00444 Vec returnPredictedFrom(Vec source, int transformIdx=-1)const ; 00445 00446 00448 void batchGeneratePredictedFrom(const Vec & center, 00449 Mat & samples)const; 00450 00453 void batchGeneratePredictedFrom(const Vec & center, 00454 Mat & samples, 00455 int transformIdx)const ; 00456 00457 //Generates n samples from center and returns them stored in a matrix 00458 // (generation process = 1) choose a transformation (*), 00459 // 2) apply it on center 00460 // 3) add noise) 00461 // - (*) if transformIdx>=0, we always use the corresponding transformation 00462 Mat returnGeneratedSamplesFrom(Vec center, int n, int transformIdx=-1)const; 00463 00464 00466 int pickTransformIdx() const; 00467 00471 int pickNeighborIdx() const; 00472 00498 void treeDataSet(const Vec &root, 00499 int deepness, 00500 int branchingFactor, 00501 Mat & dataPoints, 00502 int transformIdx = -1)const; 00503 Mat returnTreeDataSet(Vec root, 00504 int deepness, 00505 int branchingFactor, 00506 int transformIdx =-1)const; 00507 00508 00512 void sequenceDataSet(const Vec & start, 00513 int n, 00514 Mat & dataPoints, 00515 int transformIdx=-1)const; 00516 00517 Mat returnSequenceDataSet(Vec start,int n, int transformIdx=-1)const; 00518 00519 00520 00521 00522 00523 00524 00526 00528 Vec returnTrainingPoint(int idx)const; 00529 00531 TVec<ReconstructionCandidate> returnReconstructionCandidates(int targetIdx)const; 00532 00535 Mat returnReconstructions(int targetIdx)const; 00536 00539 Mat returnNeighbors(int targetIdx)const; 00540 00542 Mat returnTransform(int transformIdx)const; 00543 00547 Mat returnAllTransforms()const; 00548 00549 00550 //OTHER BUILDING/INITIALIZATION METHODS 00551 00552 // Simply calls inherited::build() then build_() 00553 virtual void build(); 00554 00556 void mainLearnerBuild(); 00557 00558 void buildLearnedParameters(); 00559 00560 00563 void generatorBuild(int inputSpaceDim_=2, 00564 TVec<Mat> transforms_ =TVec<Mat>(), 00565 Mat biasSet_ =Mat(), 00566 real noiseVariance_ =-1.0, 00567 Vec transformDistribution_ =Vec()); 00568 00569 00570 00571 00573 // (PLEASE IMPLEMENT IN .cc) 00574 virtual void makeDeepCopyFromShallowCopy(CopiesMap& copies); 00575 00576 protected: 00577 //##### Protected Options ############################################### 00578 00579 // ### Declare protected option fields (such as learned parameters) here 00580 00581 00582 //TRANSFORMATIONS 00583 00590 Mat transformsSet; 00591 TVec<Mat> transforms; 00592 00595 Mat biasSet; 00596 00597 //SELECTED HIDDEN VARIABLES COMBINATIONS 00598 00602 TVec< ReconstructionCandidate > reconstructionSet; 00603 00604 00605 //DIMENSION VARIABLES 00606 00608 int inputSpaceDim; 00609 00613 int nbTargetReconstructions; 00614 00616 int nbReconstructions; 00617 00619 int trainingSetLength; 00620 00621 //USEFUL CONSTANTS 00622 00623 00625 real transformsSD; 00626 00627 00628 //OTHERS 00629 00630 00633 TVec<ReconstructionCandidate> targetReconstructionSet; 00634 00638 Mat B_C; 00641 TVec<Mat> B,C; 00642 00643 // Temporary storage for internal methods 00644 mutable Vec newDistribution; 00645 mutable Vec ses_target; 00646 mutable Vec ses_neighbor; 00647 mutable Vec ses_predictedTarget; 00648 mutable Vec lg_neighbor; 00649 mutable Vec lg_predictedTarget; 00650 mutable Vec stp_v; 00651 mutable real stp_w; 00652 mutable Vec fnn_target; 00653 mutable Vec fnn_neighbor; 00654 mutable Vec fbtrc_target; 00655 mutable Vec fbtrc_neighbor; 00656 mutable Vec fbtrc_predictedTarget; 00657 mutable Vec fbwn_target; 00658 mutable Vec fbwn_neighbor; 00659 mutable Vec fbwn_predictedTarget; 00660 mutable Vec mst_v; 00661 mutable Vec mst_target; 00662 mutable Vec mst_neighbor; 00663 mutable TVec<int> mst_pivots; 00664 mutable Mat msb_newBiasSet; 00665 mutable Vec msb_norms; 00666 mutable Vec msb_target; 00667 mutable Vec msb_neighbor; 00668 mutable Vec msb_reconstruction; 00669 mutable Vec msnvMAP_total_k; 00670 mutable Vec msnvMAP_target; 00671 mutable Vec msnvMAP_neighbor; 00672 mutable Vec msnvMAP_reconstruction; 00673 mutable Mat mstd_B; 00674 mutable Mat mstd_C; 00675 mutable Mat mstd_D; 00676 mutable Vec mstd_v; 00677 mutable Vec mstd_target; 00678 mutable Vec mstd_neighbor; 00679 mutable TVec<int> mstd_pivots; 00680 00681 protected: 00682 //##### Protected Member Functions ###################################### 00683 00685 // (PLEASE IMPLEMENT IN .cc) 00686 static void declareOptions(OptionList& ol); 00688 static void declareMethods(RemoteMethodMap& rmm); 00689 00690 00691 private: 00692 //##### Private Member Functions ######################################## 00693 00695 // (PLEASE IMPLEMENT IN .cc) 00696 void build_(); 00697 00698 00700 00703 void seeTargetReconstructionSet(int targetIdx, 00704 TVec<ReconstructionCandidate> & targetReconstructionSet)const ; 00705 00706 00708 inline void seeTrainingPoint(const int idx, Vec & dst) const ; 00709 00710 00712 00714 00717 real gamma_sample(real alpha,real beta=1)const; 00718 00719 00722 00727 void dirichlet_sample(real alpha, Vec & sample)const; 00728 Vec return_dirichlet_sample(real alpha)const; 00729 00730 00731 00732 00733 00735 00737 inline void normalizeTargetWeights(int targetIdx, real totalWeight); 00738 00740 inline real randomWeight() const; 00741 00743 inline real INIT_weight(real initValue) const; 00744 inline real PROBA_weight(real weight) const; 00745 inline real DIV_weights(real numWeight, real denomWeight) const; 00746 inline real MULT_INVERSE_weight(real weight) const ; 00747 inline real MULT_weights(real weight1, real weight2) const ; 00748 inline real SUM_weights(real weight1, real weight2) const ; 00749 00752 inline real updateReconstructionWeight(int candidateIdx); 00753 inline real updateReconstructionWeight(int candidateIdx, 00754 const Vec & target, 00755 const Vec & neighbor, 00756 int transformIdx, 00757 Vec & predictedTarget); 00758 inline real computeReconstructionWeight(const ReconstructionCandidate & gc) const; 00759 inline real computeReconstructionWeight(int targetIdx, 00760 int neighborIdx, 00761 int transformIdx) const; 00762 inline real computeReconstructionWeight(const Vec & target, 00763 int neighborIdx, 00764 int transformIdx) const; 00765 inline real computeReconstructionWeight(const Vec & target, 00766 const Vec & neighbor, 00767 int transformIdx)const; 00768 inline real computeReconstructionWeight(const Vec & target, 00769 const Vec & neighbor, 00770 int transformIdx, 00771 Vec & predictedTarget)const; 00772 00774 inline void applyTransformationOn(int transformIdx, const Vec & src , Vec & dst) const ; 00775 00776 00782 bool isWellDefined(Vec & distribution)const; 00783 00785 00787 void initEStep(); 00788 00790 //for each target: 00791 // 1)find the neighbors (we use euclidean distance as an heuristic) 00792 // 2)for each neighbor, assign a random weight to each possible transformation 00793 void initEStepA(); 00794 00796 00797 void initEStepB(); 00798 00799 00800 00805 real expandTargetNeighborPairInReconstructionSet(int targetIdx, 00806 int neighborIdx, 00807 int candidateStartIdx); 00808 00812 void findNearestNeighbors(int targetIdx, 00813 priority_queue< pair< real, int > > & pq); 00814 00815 00817 00820 void EStep(); 00821 00823 00827 void largeEStepA(); 00828 00833 void findBestTargetReconstructionCandidates 00834 (int targetIdx, 00835 priority_queue< ReconstructionCandidate > & pq); 00836 00837 00839 00843 void largeEStepB(); 00844 00845 00849 void findBestWeightedNeighbors 00850 (int targetIdx, 00851 int transformIdx, 00852 priority_queue< ReconstructionCandidate > & pq); 00853 00855 00857 void smallEStep(); 00858 00860 00863 void MStep(); 00864 00867 void MStepTransformDistribution(); 00868 00869 00874 void MStepTransformDistributionMAP(real alpha); 00875 00878 void MStepTransformations(); 00879 00883 void MStepTransformationDiv(int transformIdx); 00884 00885 00888 void MStepBias(); 00889 00891 void MStepNoiseVariance(); 00892 00896 void MStepNoiseVarianceMAP(real alpha, real beta); 00897 00900 inline real reconstructionEuclideanDistance(int candidateIdx); 00901 inline real reconstructionEuclideanDistance(const Vec & target, 00902 const Vec & neighbor, 00903 int transformIdx, 00904 Vec & reconstruction)const; 00905 00906 //increment the variable 'stage' of 1 00907 void nextStage(); 00908 00909 private: 00910 //##### Private Data Members ############################################ 00911 00912 // The rest of the private stuff goes here 00913 00914 }; 00915 00916 // Declares a few other classes and functions related to this class 00917 DECLARE_OBJECT_PTR(TransformationLearner); 00918 00919 } // end of namespace PLearn 00920 00921 #endif 00922 00923 00924 /* 00925 Local Variables: 00926 mode:c++ 00927 c-basic-offset:4 00928 c-file-style:"stroustrup" 00929 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00930 indent-tabs-mode:nil 00931 fill-column:79 00932 End: 00933 */ 00934 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :