PLearn 0.1
InfiniteMNISTVMatrix.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // InfiniteMNISTVMatrix.cc
00004 //
00005 // Copyright (C) 2008 Hugo Larochelle
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: Hugo Larochelle
00036 
00040 #include "InfiniteMNISTVMatrix.h"
00041 
00042 namespace PLearn {
00043 using namespace std;
00044 
00045 
00046 // Initialize static variables
00047 mnistproblem_t* InfiniteMNISTVMatrix::dataset = 0;
00048 int InfiniteMNISTVMatrix::n_pointers_to_dataset = 0;
00049 
00050 PLEARN_IMPLEMENT_OBJECT(
00051     InfiniteMNISTVMatrix,
00052     "VMatrix containing an \"infinite\" stream of MNIST samples.",
00053     "VMatrix that uses the code from \"Training Invariant Support Vector Machines\n"
00054     "using Selective Sampling\" by Loosli, Canu and Bottou (JMLR 2007), to generate\n"
00055     "\"infinite\" stream (i.e. INT_MAX sized set) of samples from the MNIST dataset. The samples\n"
00056     "are obtained by applying some class-invariante transformations on the original MNIST\n"
00057     "dataset.\n"
00058     );
00059 
00060 InfiniteMNISTVMatrix::InfiniteMNISTVMatrix():
00061     include_test_examples(false),
00062     include_validation_examples(false),
00063     random_switch_to_original_training_set(false),
00064     proportion_of_switches(0.0),
00065     seed(1834),
00066     input_divisor(1.),
00067     test_images(TEST_IMAGES_PATH),
00068     test_labels(TEST_LABELS_PATH),
00069     train_images(TRAIN_IMAGES_PATH),
00070     train_labels(TRAIN_LABELS_PATH),
00071     fields(FIELDS_PATH),
00072     tangent_vectors(TANGVEC_PATH)
00073 /* ### Initialize all fields to their default value */
00074 {
00075     InfiniteMNISTVMatrix::n_pointers_to_dataset++;
00076     random_gen = new PRandom();
00077     image = (unsigned char*)malloc(EXSIZE);
00078 }
00079 
00080 InfiniteMNISTVMatrix::~InfiniteMNISTVMatrix()
00081 {
00082     InfiniteMNISTVMatrix::n_pointers_to_dataset--;
00083     if( InfiniteMNISTVMatrix::dataset && InfiniteMNISTVMatrix::n_pointers_to_dataset == 0 )
00084     {
00085             destroy_mnistproblem(dataset);
00086             InfiniteMNISTVMatrix::dataset = 0;
00087     }
00088     free( image );
00089 }
00090 
00091 void InfiniteMNISTVMatrix::getNewRow(int i, const Vec& v) const
00092 {
00093     int i_dataset;
00094     if( include_test_examples )
00095         if( include_validation_examples )
00096             i_dataset = i;
00097         else
00098             if( i < 10000)
00099                 i_dataset = i;
00100             else
00101                 i_dataset = i + ((i-10000)/50000)*10000;
00102     else
00103         if( include_validation_examples )
00104             i_dataset = i+10000;
00105         else
00106             i_dataset = i + (i/50000)*10000 + 10000;
00107 
00108     if( random_switch_to_original_training_set && 
00109         random_gen->uniform_sample() < proportion_of_switches )
00110         i_dataset = (i_dataset % 50000)+10000;
00111 
00112     image = compute_transformed_vector_in_place(InfiniteMNISTVMatrix::dataset, i_dataset, image);
00113 
00114     unsigned char* xj=image;
00115     real* vj=v.data();
00116     for( int j=0; j<inputsize_; j++, xj++, vj++ )
00117         *vj = *xj/input_divisor;
00118     
00119     v.last() = InfiniteMNISTVMatrix::dataset->y[ (i_dataset<10000) ? i_dataset : 10000 + ((i_dataset - 10000) % 60000) ];
00120 }
00121 
00122 void InfiniteMNISTVMatrix::declareOptions(OptionList& ol)
00123 {
00124      declareOption(ol, "include_test_examples", &InfiniteMNISTVMatrix::include_test_examples,
00125                    OptionBase::buildoption,
00126                    "Indication that the test examples from the MNIST dataset should be included.\n"
00127                    "This option is false by default. If true, these examples will be the first"
00128                    "10000\n"
00129                    "of this VMatrix.\n");
00130 
00131      declareOption(ol, "include_validation_examples", &InfiniteMNISTVMatrix::include_validation_examples,
00132                    OptionBase::buildoption,
00133                    "Indication that the validation set examples (the last 10000 examples from the\n"
00134                    "training set) should be included in this VMatrix.\n");     
00135 
00136      declareOption(ol, "random_switch_to_original_training_set", 
00137                    &InfiniteMNISTVMatrix::random_switch_to_original_training_set,
00138                    OptionBase::buildoption,
00139                    "Indication that the VMatrix should randomly (from time to time) provide\n"
00140                    "an example from the original training set instead of an example\n"
00141                    "from the global dataset.\n");     
00142 
00143      declareOption(ol, "proportion_of_switches", &InfiniteMNISTVMatrix::proportion_of_switches,
00144                    OptionBase::buildoption,
00145                    "Proportion of switches to the original training set.\n");     
00146 
00147      declareOption(ol, "seed", &InfiniteMNISTVMatrix::seed,
00148                    OptionBase::buildoption,
00149                    "Seed of random number generator.\n");
00150 
00151      declareOption(ol, "input_divisor", &InfiniteMNISTVMatrix::input_divisor,
00152                    OptionBase::buildoption,
00153                    "Value that the inputs should be divided by.\n");     
00154 
00155      declareOption(ol, "test_images", &InfiniteMNISTVMatrix::test_images,
00156                    OptionBase::buildoption,
00157                    "File path of MNIST test images.\n");     
00158 
00159      declareOption(ol, "test_labels", &InfiniteMNISTVMatrix::test_labels,
00160                    OptionBase::buildoption,
00161                    "File path of MNIST test labels.\n");     
00162 
00163      declareOption(ol, "train_images", &InfiniteMNISTVMatrix::train_images,
00164                    OptionBase::buildoption,
00165                    "File path of MNIST train images.\n");     
00166 
00167      declareOption(ol, "train_labels", &InfiniteMNISTVMatrix::train_labels,
00168                    OptionBase::buildoption,
00169                    "File path of MNIST train labels.\n");     
00170 
00171      declareOption(ol, "fields", &InfiniteMNISTVMatrix::fields,
00172                    OptionBase::buildoption,
00173                    "File path of MNIST fields information.\n");     
00174 
00175      declareOption(ol, "tangent_vectors", &InfiniteMNISTVMatrix::tangent_vectors,
00176                    OptionBase::buildoption,
00177                    "File paht of MNIST transformation tangent vectors.\n");
00178 
00179     // Now call the parent class' declareOptions
00180     inherited::declareOptions(ol);
00181 }
00182 
00183 void InfiniteMNISTVMatrix::build_()
00184 {
00185     random_gen->manual_seed(seed);
00186 
00187     if( !InfiniteMNISTVMatrix::dataset )
00188     {
00189         char* test_images_char = new char[test_images.size()+1];
00190         char* test_labels_char = new char[test_labels.size()+1];
00191         char* train_images_char = new char[train_images.size()+1];
00192         char* train_labels_char = new char[train_labels.size()+1];
00193         char* fields_char = new char[fields.size()+1];
00194         char* tangent_vectors_char = new char[tangent_vectors.size()+1];
00195         
00196         strcpy(test_images_char,test_images.c_str());
00197         strcpy(test_labels_char,test_labels.c_str());
00198         strcpy(train_images_char,train_images.c_str());
00199         strcpy(train_labels_char,train_labels.c_str());
00200         strcpy(fields_char,fields.c_str());
00201         strcpy(tangent_vectors_char,tangent_vectors.c_str());
00202         
00203         InfiniteMNISTVMatrix::dataset = create_mnistproblem(
00204             test_images_char,
00205             test_labels_char,
00206             train_images_char,
00207             train_labels_char,
00208             fields_char,
00209             tangent_vectors_char);
00210         if( !InfiniteMNISTVMatrix::dataset )
00211             PLERROR("In InfiniteMNISTVMatrix(): could not load MNIST dataset");
00212     }
00213 
00214 
00215     if( include_test_examples )
00216         if( include_validation_examples )
00217             length_ = INT_MAX;
00218         else
00219             // Might be removing more samples than need, but we have so many anyways...
00220             length_ = INT_MAX - ((INT_MAX-10000)/50000)*10000 + 1;
00221     
00222     else
00223         if( include_validation_examples )
00224             length_ = INT_MAX - 10000+1;
00225         else
00226             // Might be removing more samples than need, but we have so many anyways...
00227             length_ = INT_MAX - ((INT_MAX-10000)/50000)*10000 - 10000 + 1;
00228 
00229     inputsize_ = 784;
00230     targetsize_ = 1;
00231     weightsize_ = 0;
00232     extrasize_ = 0;
00233     width_ = 785;
00234 
00235     // ### You should keep the line 'updateMtime(0);' if you don't implement the 
00236     // ### update of the mtime. Otherwise you can have an mtime != 0 that is not valid.
00237     updateMtime(0);
00238     //updateMtime(filename);
00239     //updateMtime(VMat);
00240 }
00241 
00242 // ### Nothing to add here, simply calls build_
00243 void InfiniteMNISTVMatrix::build()
00244 {
00245     inherited::build();
00246     build_();
00247 }
00248 
00249 void InfiniteMNISTVMatrix::makeDeepCopyFromShallowCopy(CopiesMap& copies)
00250 {
00251     inherited::makeDeepCopyFromShallowCopy(copies);
00252 
00253     // ### Call deepCopyField on all "pointer-like" fields
00254     // ### that you wish to be deepCopied rather than
00255     // ### shallow-copied.
00256     // ### ex:
00257     // deepCopyField(trainvec, copies);
00258 
00259     PLWARNING("InfiniteMNISTVMatrix::makeDeepCopyFromShallowCopy is not totally implemented. Need "
00260               "to figure out how to deep copy the \"dataset\" variable (mnistproblem_t*).\n");
00261     InfiniteMNISTVMatrix::n_pointers_to_dataset++;
00262     image = (unsigned char*)malloc(EXSIZE);
00263 }
00264 
00265 } // end of namespace PLearn
00266 
00267 
00268 /*
00269   Local Variables:
00270   mode:c++
00271   c-basic-offset:4
00272   c-file-style:"stroustrup"
00273   c-file-offsets:((innamespace . 0)(inline-open . 0))
00274   indent-tabs-mode:nil
00275   fill-column:79
00276   End:
00277 */
00278 // 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