PLearn 0.1
KPCATangentLearner.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // KPCATangentLearner.cc
00004 //
00005 // Copyright (C) 2004 Martin Monperrus 
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 /* *******************************************************      
00036  * $Id: KPCATangentLearner.cc 3994 2005-08-25 13:35:03Z chapados $ 
00037  ******************************************************* */
00038 
00039 // Authors: Martin Monperrus
00040 
00043 //
00044 #include "KernelPCA.h"
00045 #include "KPCATangentLearner.h"
00046 #include "plearn/ker/GeodesicDistanceKernel.h"
00047 #include "plearn/ker/AdditiveNormalizationKernel.h"
00048 #include "plearn/ker/GaussianKernel.h"
00049 
00050 
00051 namespace PLearn {
00052 using namespace std;
00053 
00054 KPCATangentLearner::KPCATangentLearner() : n_comp(2),sigma(1)
00055 /* ### Initialize all fields to their default value here */
00056 {
00057     // ...
00058 
00059     // ### You may or may not want to call build_() to finish building the object
00060     // build_();
00061 }
00062 
00063 PLEARN_IMPLEMENT_OBJECT(KPCATangentLearner, "Tangent learning based on KPCA Kernel", "MULTI-LINE \nHELP");
00064 
00065 void KPCATangentLearner::declareOptions(OptionList& ol)
00066 {
00067     // ### Declare all of this object's options here
00068     // ### For the "flags" of each option, you should typically specify  
00069     // ### one of OptionBase::buildoption, OptionBase::learntoption or 
00070     // ### OptionBase::tuningoption. Another possible flag to be combined with
00071     // ### is OptionBase::nosave
00072   
00073   
00074     declareOption(ol, "sigma", &KPCATangentLearner::sigma, OptionBase::buildoption,
00075                   "Sigma");
00076     declareOption(ol, "n_comp", &KPCATangentLearner::n_comp, OptionBase::buildoption,
00077                   "Number of Components");
00078     declareOption(ol, "KPCA", &KPCATangentLearner::KPCA, OptionBase::learntoption,
00079                   "");
00080   
00081     // Now call the parent class' declareOptions
00082     inherited::declareOptions(ol);
00083 }
00084 
00085 void KPCATangentLearner::build_()
00086 {
00087     // ### This method should do the real building of the object,
00088     // ### according to set 'options', in *any* situation. 
00089     // ### Typical situations include:
00090     // ###  - Initial building of an object from a few user-specified options
00091     // ###  - Building of a "reloaded" object: i.e. from the complete set of all serialised options.
00092     // ###  - Updating or "re-building" of an object after a few "tuning" options have been modified.
00093     // ### You should assume that the parent class' build_() has already been called.
00094 }
00095 
00096 // ### Nothing to add here, simply calls build_
00097 void KPCATangentLearner::build()
00098 {
00099     inherited::build();
00100     build_();
00101 }
00102 
00103 
00104 void KPCATangentLearner::makeDeepCopyFromShallowCopy(CopiesMap& copies)
00105 {
00106     inherited::makeDeepCopyFromShallowCopy(copies);
00107 
00108     // ### Call deepCopyField on all "pointer-like" fields 
00109     // ### that you wish to be deepCopied rather than 
00110     // ### shallow-copied.
00111     // ### ex:
00112     // deepCopyField(trainvec, copies);
00113 
00114     // ### Remove this line when you have fully implemented this method.
00115     PLERROR("KPCATangentLearner::makeDeepCopyFromShallowCopy not fully (correctly) implemented yet!");
00116 }
00117 
00118 
00119 int KPCATangentLearner::outputsize() const
00120 {
00121     // Compute and return the size of this learner's output (which typically
00122     // may depend on its inputsize(), targetsize() and set options).
00123     return inputsize()*n_comp;
00124 }
00125 
00126 void KPCATangentLearner::forget()
00127 {
00130 
00136 }
00137     
00138 void KPCATangentLearner::train()
00139 {
00140     // The role of the train method is to bring the learner up to stage==nstages,
00141     // updating train_stats with training costs measured on-line in the process.
00142     KPCA.n_comp = n_comp;
00143     KPCA.kpca_kernel = new GaussianKernel(sigma);
00144     if (train_set)
00145         KPCA.setTrainingSet(train_set);
00146     KPCA.build();
00147     KPCA.train();
00148 }
00149 
00150 
00151 void KPCATangentLearner::computeOutput(const Vec& input, Vec& output) const
00152 {
00153     PP<AdditiveNormalizationKernel> ank = dynamic_cast<AdditiveNormalizationKernel*>((Kernel*)KPCA.kernel);  
00154     PP<GaussianKernel> gk = dynamic_cast<GaussianKernel*>((Kernel*)ank->source_kernel);
00155   
00156     VMat trainset = ank->specify_dataset;
00157     int n_examples = trainset->length();
00158     Mat result(n_comp,inputsize());
00159   
00160     Vec dkdx(inputsize()); //dk/dx
00161     Vec temp(inputsize());
00162     Vec term2(inputsize());
00163     Vec sum(inputsize());
00164     Mat diK_dx(n_examples,inputsize());
00165   
00166     int i,j,nc;
00167   
00168     sum<<0;
00169     for(j=0;j<n_examples;++j) {
00170         trainset->getRow(j,temp);
00171         //real nt = norm(input-temp);
00172         // le noyau me renvoie ce que je veux mais les valeurs sont toutes petites: pb de sigma
00173         //cout<<gk->evaluate(temp,input)<<" "<<exp(-(nt*nt)/(sigma*sigma))<<endl;
00174         sum += gk->evaluate(temp,input)*(input-temp)/(sigma*sigma);
00175     }
00176 
00177   
00178     for(i=0;i<n_examples;++i)  {
00179         trainset->getRow(i,temp);
00180         term2 << gk->evaluate(temp,input)*(input-temp)/(sigma*sigma);      
00181         //cout<<term2<<endl;
00182         //cout<<sum;
00183         diK_dx(i) << (term2 - sum/n_examples); // on a le moins qui vient du moins de la dérivation de de exp(-)
00184         //diK_dx(i) << (sum/n_examples - term2); // exactement la formule de NIPS
00185         //cout<<diK_dx(i);
00186     }
00187   
00188     for(nc=0;nc<n_comp;++nc)
00189     {
00190         // compute the corresponding vector with the Nystrom formula
00191         // d ek / dx = 1/n sum_i dK/dX
00192     
00193         // initialisation
00194         temp<<(0);
00195         for(i=0;i<n_examples;++i)
00196         {
00197             temp += (KPCA.eigenvectors(nc,i) * diK_dx(i));
00198         }
00199         // on ne normalise pas car c'est la direction vecteur qui nous interesse et pas sa norme
00200         // en plus on normalise tout a 1 dans matlab pour eviter les erreurs numériques.
00201 //     result(nc)<<(temp/iso_learner.eigenvalues[nc]);
00202         result(nc)<<(temp);
00203     }    
00204     //cout<<result; 
00205     // toVec: a mettre dans l'aide
00206     output << result.toVec();
00207   
00208 }
00209 
00210 
00211 
00212 void KPCATangentLearner::computeCostsFromOutputs(const Vec& input, const Vec& output, 
00213                                                  const Vec& target, Vec& costs) const
00214 {
00215 // Compute the costs from *already* computed output. 
00216 // ...
00217 }                                
00218 
00219 TVec<string> KPCATangentLearner::getTestCostNames() const
00220 {
00221     // Return the names of the costs computed by computeCostsFromOutpus
00222     // (these may or may not be exactly the same as what's returned by getTrainCostNames).
00223     // ...
00224     return TVec<string>();
00225 }
00226  
00227 TVec<string> KPCATangentLearner::getTrainCostNames() const
00228 {
00229     // Return the names of the objective costs that the train method computes and 
00230     // for which it updates the VecStatsCollector train_stats
00231     // (these may or may not be exactly the same as what's returned by getTestCostNames).
00232     // ...
00233     return TVec<string>();
00234 }
00235 
00236 
00237 } // end of namespace PLearn
00238 
00239 
00240 /*
00241   Local Variables:
00242   mode:c++
00243   c-basic-offset:4
00244   c-file-style:"stroustrup"
00245   c-file-offsets:((innamespace . 0)(inline-open . 0))
00246   indent-tabs-mode:nil
00247   fill-column:79
00248   End:
00249 */
00250 // 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