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 	PCATrainer *pca_trainer = NULL;
 95 	pca_trainer = new(allocator) PCATrainer(pca_machine);
 96 	pca_trainer->setIOption("verbose_level", verbose_level);
 97 	pca_trainer->setBOption("saveCovar", saveCovar);
 98 	
 99 
100 	//
101 	// Load all the data in the same dataset
102 	DataSet *bindata = NULL;
103 	
104 	if(use_disk)
105 	{
106   		DiskBinDataSet *bindata_ = new(allocator) DiskBinDataSet(filelist.file_names, filelist.n_files, n_inputs, -1);
107 	  	bindata_->info(false);
108 
109 		bindata = bindata_;
110 	}
111 	else
112 	{
113     		//FileBinDataSet *bindata = new(allocator) FileBinDataSet(filelist.file_names, filelist.n_files, 0.0, n_inputs);
114 	    	//FileBinDataSet *bindata = new(allocator) FileBinDataSet(filelist.file_names, filelist.n_files, n_inputs, offset_window, n_inputs_window);
115 	    	FileBinDataSet *bindata_ = new(allocator) FileBinDataSet(filelist.file_names, filelist.n_files, n_inputs, offset_window, n_inputs_window);
116 		bindata_->info(false);	
117 
118 		bindata = bindata_;
119 	}
120 	
121 	//
122 	if(image_normalize)
123 	{
124 		print("Pre-processing image %dx%d ...\n", width, height);
125 		PreProcessing *preprocess = new(allocator) HistoEqualSmoothImagePreProcessing(width, height);
126 
127 		bindata->preProcess(preprocess);
128 	}
129 	
130 	//
131 	MeanVarNorm *mv_norm = NULL;
132 	if(normalize)
133 	{
134 	   	print("Normalization ...\n");
135 
136 		mv_norm = new(allocator) MeanVarNorm(bindata);
137 		bindata->preProcess(mv_norm);
138 	}
139 
140 
141 	//
142 	// Computes PCA
143 	pca_trainer->train(bindata);
144 
145 
146 	//
147 	// Project data into PCA sub-space
148 	real *realinput = NULL;
149         Sequence *seq = NULL;
150 
151 	if(forward)
152 	{
153         	realinput = new real [n_inputs_window];
154         	seq = new Sequence(&realinput, 1, n_inputs_window);
155 	
156 		//
157 		pca_machine->setROption("variance", 0.95);
158 		pca_machine->init();
159 	
160 		for(int i=0; i< bindata->n_examples; i++)
161 		{
162 			if(verbose) 
163 	   			print("[%d]:\n", i);
164 
165 			//
166 			bindata->setExample(i);
167 		
168 			if(verbose) 
169 				print(" Input =   [%2.3f %2.3f %2.3f ...]\n", bindata->inputs->frames[0][0], bindata->inputs->frames[0][1], bindata->inputs->frames[0][2]);
170 
171 			//
172 			bindata->inputs->copyTo(realinput);
173 
174 			if(verbose) 
175 				print(" Seq =     [%2.3f %2.3f %2.3f ...]\n", realinput[0], realinput[1], realinput[2]);
176 
177 			//
178 			pca_machine->forward(seq);
179 			
180 			if(verbose) 
181 				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]);
182 		}
183 	}
184 
185 
186 	//
187 	// Save the model
188 	if(strcmp(model_file, "") != 0)
189 	{
190 	   	if(normalize) 
191 		{
192 	   		print("Saving PCA model and its normalisation...\n");
193 
194 		   	pca_machine->save(model_file, mv_norm);
195 		}
196 		else
197 		{
198 	   		print("Saving PCA model ...\n");
199 
200 			DiskXFile *file = NULL;
201 
202 			file = new DiskXFile(model_file, "w");
203 	
204 			pca_machine->saveXFile(file);
205 	
206 			delete file;
207 		}
208 	}
209 
210 
211 
212 	//
213 	// Free memory
214 	if(forward)
215 	{
216 		delete [] realinput;
217 		delete seq;
218 	}
219   	delete allocator;
220 
221   	return(0);
222 }