trainPCA.cc

  1 const char *help = "\
  2 progname: trainPCA.cc\n\
  3 code2html: This program computes PCA projection sub-space.\n\
  4 version: Torch3 vision2.0, 2003-2005\n\
  5 (c) Sebastien Marcel (marcel@idiap.ch)\n";
  6 
  7 #include "FileBinDataSet.h"
  8 #include "DiskBinDataSet.h"
  9 #include "PCATrainer.h"
 10 #include "MeanVarNorm.h"
 11 #include "HistoEqualSmoothImagePreProcessing.h"
 12 #include "FileListCmdOption.h"
 13 #include "CmdLine.h"
 14 
 15 using namespace Torch;
 16 			
 17 int main(int argc, char **argv)
 18 {
 19   	int n_inputs;
 20   	int offset_window;
 21   	int n_inputs_window;
 22   	char *model_file;
 23 	bool verbose;
 24 	int verbose_level;
 25 	bool normalize;
 26 	bool forward;
 27 	bool saveCovar;
 28 	bool use_disk;
 29 	bool image_normalize;
 30 	int width, height;
 31 
 32   	Allocator *allocator = new Allocator;
 33   	DiskXFile::setLittleEndianMode();
 34 
 35 
 36 	
 37   	//=================== The command-line ==========================
 38 	FileListCmdOption filelist("file name", "the list files or one data file");
 39         filelist.isArgument(true);
 40 
 41   	// Construct the command line
 42   	CmdLine cmd;
 43 	cmd.setBOption("write log", false);
 44 	
 45   	// Put the help line at the beginning
 46   	cmd.info(help);
 47 
 48   	cmd.addText("\nArguments:");
 49   	cmd.addCmdOption(&filelist);
 50   	cmd.addICmdArg("n_inputs", &n_inputs, "input dimension of the data", true);
 51   	cmd.addText("\nOptions:");
 52   	cmd.addICmdOption("-offset_window", &offset_window, 0, "offset window", true);
 53   	cmd.addICmdOption("-n_inputs_window", &n_inputs_window, -1, "input dimension of the window", true);
 54   	cmd.addBCmdOption("-saveCovar", &saveCovar, false, "save the covariance matrix", true);
 55   	cmd.addBCmdOption("-normalize", &normalize, false, "normalization", true);
 56   	cmd.addBCmdOption("-verbose", &verbose, false, "verbose", true);
 57   	cmd.addICmdOption("-verbose_level", &verbose_level, 0, "verbose level", true);
 58   	cmd.addBCmdOption("-forward", &forward, false, "project data into PCA sub-space", true);
 59   	cmd.addSCmdOption("-save", &model_file, "", "model file", true);
 60 	cmd.addBCmdOption("-use_disk", &use_disk, false, "use disk");
 61 	cmd.addBCmdOption("-imagenorm", &image_normalize, false, "considers the input pattern as an image and performs a photometric normalization");
 62 	cmd.addICmdOption("-width", &width, -1, "width");
 63 	cmd.addICmdOption("-height", &height, -1, "height");
 64 
 65   	// Read the command line
 66   	cmd.read(argc, argv);
 67 
 68 	if(n_inputs_window == -1) n_inputs_window = n_inputs;
 69 
 70 	if(image_normalize)
 71 	{
 72 		print("Perform photometric normalization ...\n");
 73 
 74 		print("The input pattern is an %dx%d image.\n", width, height);
 75 	}
 76 
 77 	//
 78 	if(verbose)
 79 	{
 80 		print(" + n_filenames = %d\n", filelist.n_files);
 81 		for(int i = 0 ; i < filelist.n_files ; i++)
 82 			print("   filename[%d] = %s\n", i, filelist.file_names[i]);
 83 	}
 84 
 85 
 86 	//
 87   	// The PCA Machine
 88 	PCAMachine *pca_machine = NULL;
 89 	pca_machine = new(allocator) PCAMachine(n_inputs_window);
 90 	pca_machine->setIOption("verbose_level", verbose_level);
 91 
 92 	//
 93 	// The PCA Trainer
 94 	Trainer *pca_trainer = NULL;
 95 
 96 	pca_trainer = new(allocator) PCATrainer(pca_machine);
 97 	pca_trainer->setBOption("saveCovar", saveCovar);
 98 	pca_trainer->setIOption("verbose_level", verbose_level);
 99 	
100 
101 	//
102 	// Load all the data in the same dataset
103 	DataSet *bindata = NULL;
104 	
105 	if(use_disk)
106 	{
107   		DiskBinDataSet *bindata_ = new(allocator) DiskBinDataSet(filelist.file_names, filelist.n_files, n_inputs, -1);
108 	  	bindata_->info(false);
109 
110 		bindata = bindata_;
111 	}
112 	else
113 	{
114     		//FileBinDataSet *bindata = new(allocator) FileBinDataSet(filelist.file_names, filelist.n_files, 0.0, n_inputs);
115 	    	//FileBinDataSet *bindata = new(allocator) FileBinDataSet(filelist.file_names, filelist.n_files, n_inputs, offset_window, n_inputs_window);
116 	    	FileBinDataSet *bindata_ = new(allocator) FileBinDataSet(filelist.file_names, filelist.n_files, n_inputs, offset_window, n_inputs_window);
117 		bindata_->info(false);	
118 
119 		bindata = bindata_;
120 	}
121 	
122 	//
123 	if(image_normalize)
124 	{
125 		print("Pre-processing image %dx%d ...\n", width, height);
126 		PreProcessing *preprocess = new(allocator) HistoEqualSmoothImagePreProcessing(width, height);
127 
128 		bindata->preProcess(preprocess);
129 	}
130 	
131 	//
132 	MeanVarNorm *mv_norm = NULL;
133 	if(normalize)
134 	{
135 	   	print("Normalization ...\n");
136 
137 		mv_norm = new(allocator) MeanVarNorm(bindata);
138 		bindata->preProcess(mv_norm);
139 	}
140 
141 
142 	//
143 	// Computes PCA
144 	pca_trainer->train(bindata, NULL);
145 
146 
147 	//
148 	// Project data into PCA sub-space
149 	real *realinput = NULL;
150         Sequence *seq = NULL;
151 
152 	if(forward)
153 	{
154         	realinput = new real [n_inputs_window];
155         	seq = new Sequence(&realinput, 1, n_inputs_window);
156 	
157 		//
158 		pca_machine->setROption("variance", 0.95);
159 		pca_machine->init();
160 	
161 		for(int i=0; i< bindata->n_examples; i++)
162 		{
163 			if(verbose) 
164 	   			print("[%d]:\n", i);
165 
166 			//
167 			bindata->setExample(i);
168 		
169 			if(verbose) 
170 				print(" Input =   [%2.3f %2.3f %2.3f ...]\n", bindata->inputs->frames[0][0], bindata->inputs->frames[0][1], bindata->inputs->frames[0][2]);
171 
172 			//
173 			bindata->inputs->copyTo(realinput);
174 
175 			if(verbose) 
176 				print(" Seq =     [%2.3f %2.3f %2.3f ...]\n", realinput[0], realinput[1], realinput[2]);
177 
178 			//
179 			pca_machine->forward(seq);
180 			
181 			if(verbose) 
182 				print(" Output =   [%2.3f %2.3f %2.3f ...]\n", pca_machine->outputs->frames[0][0], pca_machine->outputs->frames[0][1], pca_machine->outputs->frames[0][2]);
183 		}
184 	}
185 
186 
187 	//
188 	// Save the model
189 	if(strcmp(model_file, "") != 0)
190 	{
191 	   	if(normalize) 
192 		{
193 	   		print("Saving PCA model and its normalisation...\n");
194 
195 		   	pca_machine->save(model_file, mv_norm);
196 		}
197 		else
198 		{
199 	   		print("Saving PCA model ...\n");
200 
201 			DiskXFile *file = NULL;
202 
203 			file = new DiskXFile(model_file, "w");
204 	
205 			pca_machine->saveXFile(file);
206 	
207 			delete file;
208 		}
209 	}
210 
211 
212 
213 	//
214 	// Free memory
215 	if(forward)
216 	{
217 		delete [] realinput;
218 		delete seq;
219 	}
220   	delete allocator;
221 
222   	return(0);
223 }