PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // MultiTaskSeparationSplitter.cc 00004 // 00005 // Copyright (C) 2006 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 /* ******************************************************* 00036 * $Id: .pyskeleton_header 544 2003-09-01 00:05:31Z plearner $ 00037 ******************************************************* */ 00038 00039 // Authors: Hugo Larochelle 00040 00043 #include "SelectRowsVMatrix.h" 00044 #include "MultiTaskSeparationSplitter.h" 00045 #include "AddMissingVMatrix.h" 00046 #include "GetInputVMatrix.h" 00047 #include "MultiTargetOneHotVMatrix.h" 00048 00049 namespace PLearn { 00050 using namespace std; 00051 00052 PLEARN_IMPLEMENT_OBJECT( 00053 MultiTaskSeparationSplitter, 00054 "Splitter that one class (test) from the examples of other classes (train)", 00055 "This splitter is intended to measure inductive transfer performance from some tasks to another task" 00056 ); 00057 00058 MultiTaskSeparationSplitter::MultiTaskSeparationSplitter() 00059 :Splitter(), numsplits(-1), select_tasks_randomly(1), append_train(0), seed(-1) 00060 { 00061 random_gen = new PRandom(); 00062 } 00063 00064 void MultiTaskSeparationSplitter::declareOptions(OptionList& ol) 00065 { 00066 declareOption(ol, "tasks", &MultiTaskSeparationSplitter::tasks, OptionBase::buildoption, 00067 "Tasks to isolate from the others. Determines number of splits."); 00068 declareOption(ol, "numsplits", &MultiTaskSeparationSplitter::numsplits, OptionBase::buildoption, 00069 "Number of splits. Ignored if tasks is not empty."); 00070 declareOption(ol, "select_tasks_randomly", &MultiTaskSeparationSplitter::select_tasks_randomly, OptionBase::buildoption, 00071 "If tasks is not specified, indication that the tasks to isolate from the others should be chosen at random.\n" 00072 "Otherwise, the tasks are selected by order of their index."); 00073 declareOption(ol, "append_train", &MultiTaskSeparationSplitter::append_train, OptionBase::buildoption, 00074 "Indication that the training set should be appended to the split sets lists."); 00075 00076 declareOption(ol, "seed", &MultiTaskSeparationSplitter::seed, OptionBase::buildoption, 00077 "Seed of random generator"); 00078 00079 // Now call the parent class' declareOptions 00080 inherited::declareOptions(ol); 00081 } 00082 00083 void MultiTaskSeparationSplitter::build_() 00084 { 00085 if (seed != 0) 00086 random_gen->manual_seed(long(seed)); 00087 00088 if(tasks.length() == 0 && dataset) 00089 { 00090 if(numsplits <= 0) PLERROR("MultiTaskSeparationSplitter::build_(): numsplits must be > 0"); 00091 00092 tasks.resize(numsplits); 00093 int it = 0; 00094 for(int i=0; i<numsplits; i++) 00095 { 00096 if(select_tasks_randomly) 00097 random_gen->uniform_multinomial_sample(dataset->targetsize()); 00098 else 00099 { 00100 tasks[i] = it; 00101 it = (it+1)%dataset->targetsize(); 00102 } 00103 } 00104 } 00105 } 00106 00107 // ### Nothing to add here, simply calls build_ 00108 void MultiTaskSeparationSplitter::build() 00109 { 00110 inherited::build(); 00111 build_(); 00112 } 00113 00114 void MultiTaskSeparationSplitter::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00115 { 00116 inherited::makeDeepCopyFromShallowCopy(copies); 00117 00118 deepCopyField(tasks, copies); 00119 deepCopyField(random_gen, copies); 00120 00121 //PLERROR("MultiTaskSeparationSplitter::makeDeepCopyFromShallowCopy not fully (correctly) implemented yet!"); 00122 } 00123 00124 int MultiTaskSeparationSplitter::nsplits() const 00125 { 00126 return tasks.length(); 00127 } 00128 00129 int MultiTaskSeparationSplitter::nSetsPerSplit() const 00130 { 00131 return append_train ? 3 : 2; 00132 } 00133 00134 TVec<VMat> MultiTaskSeparationSplitter::getSplit(int k) 00135 { 00136 00137 if (k >= nsplits()) 00138 PLERROR("MultiTaskSeparationSplitter::getSplit() - k (%d) cannot be greater than " 00139 " the number of splits (%d)", k, nsplits()); 00140 00141 int task_k = tasks[k]; 00142 Vec row(dataset->width()); 00143 TVec<int> miss_cols_train(0); 00144 miss_cols_train.push_back(dataset->inputsize()+task_k); 00145 TVec<int> miss_cols_test(0); 00146 for(int i=0; i<dataset->targetsize(); i++) 00147 { 00148 if(task_k != i) 00149 miss_cols_test.push_back(dataset->inputsize()+i); 00150 } 00151 00152 TVec<VMat> split(2); 00153 split[0] = get_input(multi_target_one_hot(add_missing(dataset,miss_cols_train),MISSING_VALUE,MISSING_VALUE),dataset->inputsize(),dataset->targetsize()); 00154 split[1] = get_input(multi_target_one_hot(add_missing(dataset,miss_cols_test),MISSING_VALUE,MISSING_VALUE),dataset->inputsize(),dataset->targetsize()); 00155 if(append_train) 00156 { 00157 split.resize(3); 00158 split[2] = split[0]; 00159 } 00160 //split.append(split[0]); 00161 //if(append_train) split.append(get_input(multi_target_one_hot(add_missing(dataset,miss_cols_train),MISSING_VALUE,MISSING_VALUE),dataset->inputsize(),dataset->targetsize())); 00162 return split; 00163 } 00164 00165 00166 void MultiTaskSeparationSplitter::setDataSet(VMat the_dataset) 00167 { 00168 dataset = the_dataset; 00169 build(); 00170 } 00171 00172 } // end of namespace PLearn 00173 00174 00175 /* 00176 Local Variables: 00177 mode:c++ 00178 c-basic-offset:4 00179 c-file-style:"stroustrup" 00180 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00181 indent-tabs-mode:nil 00182 fill-column:79 00183 End: 00184 */ 00185 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :