PLearn 0.1
TransformationLearner.h
Go to the documentation of this file.
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 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines