View Javadoc

1   package yawn.ui.cli;
2   
3   import java.io.FileNotFoundException;
4   import java.io.FileReader;
5   
6   import org.apache.commons.cli.CommandLine;
7   import org.apache.commons.cli.GnuParser;
8   import org.apache.commons.cli.HelpFormatter;
9   import org.apache.commons.cli.MissingArgumentException;
10  import org.apache.commons.cli.MissingOptionException;
11  import org.apache.commons.cli.Option;
12  import org.apache.commons.cli.Options;
13  import org.apache.commons.cli.ParseException;
14  import org.apache.commons.cli.UnrecognizedOptionException;
15  import org.apache.commons.lang.StringUtils;
16  import org.apache.commons.logging.Log;
17  import org.apache.commons.logging.LogFactory;
18  import org.apache.log4j.Level;
19  import org.apache.log4j.Logger;
20  
21  import yawn.config.ValidationException;
22  import yawn.envs.EnvironmentException;
23  import yawn.io.DuplicateKeyException;
24  import yawn.io.Experiment;
25  import yawn.io.IStorage;
26  import yawn.io.StorageException;
27  import yawn.io.serialization.SerializationException;
28  import yawn.io.serialization.xml.CastorXmlSerializer;
29  import yawn.io.xml.XmlStorage;
30  import yawn.nn.NeuralNetwork;
31  import yawn.util.InputOutputPattern;
32  import yawn.util.Pattern;
33  
34  /***
35   * Trains and tests a neural network using a given test environment. It reads
36   * its configuration from an XML file.
37   * 
38   * <p>$Id: RunExperiment.java,v 1.9 2005/05/09 11:04:54 supermarti Exp $</p>
39   * 
40   * @author Luis Mart&iacute; (luis dot marti at uc3m dot es)
41   * @version $Revision: 1.9 $
42   */
43  
44  public class RunExperiment implements Runnable {
45  
46      private static final Log log = LogFactory.getLog(RunExperiment.class);
47  
48      protected static void printHelpMessage(String usageMessage, Options options) {
49          HelpFormatter hf = new HelpFormatter();
50          // hf.setWidth( 79 );
51          hf.printHelp(usageMessage, options, true);
52      }
53  
54      protected static void printErrorMessage(String error) {
55          log.fatal("Application error message: " + error);
56      }
57  
58      private static Option EXPERIMENT_OPTION = new Option("x", "experiment", true,
59              "Experiment config file to use");
60  
61      private static Option HELP_OPTION = new Option("h", "help", false, "View this help message");
62  
63      private static Option QUIET_OPTION = new Option("q", "quiet", false,
64              "Do not show welcome message");
65  
66      private static String USAGE_MESG = "java yawn.ui.cli.RunExperiment";
67  
68      private static Option VERB_OPTION = new Option("v", "verbose", false, "Show execution messages");
69  
70      private static Option DEBUG_OPTION = new Option("d", "debug", false, "Show debug messages");
71  
72      private static String WELCOME_MESG = "\nWelcome to RunExperiment: A simple interface to the Yawn library.\n"
73              + "Distributed under the GNU license (see http://www.gnu.org/licenses/gpl.html).\n"
74              + "Check http://yawn2.sourceforge.net for updates.\n";
75  
76  	/***
77  	 * 
78  	 */
79  	protected String experimentFileName = null;
80  
81  	/***
82  	 * 
83  	 */
84  	protected boolean verbose = false;
85  
86  	/***
87  	 * 
88  	 */
89  	protected boolean debug = false;
90  
91  	/***
92  	 * @return Returns the debug.
93  	 */
94  	public boolean isDebug() {
95  		return debug;
96  	}
97  
98  	/***
99  	 * @param debug
100 	 *            The debug to set.
101 	 */
102 	public void setDebug(boolean debug) {
103 		this.debug = debug;
104 	}
105 
106 	/***
107 	 * 
108 	 * @uml.property name="welcomeMsgEnabled" 
109 	 */
110 	protected boolean welcomeMsgEnabled = false;
111 
112 
113     public static void main(String args[]) {
114         CommandLine cl = null;
115         try {
116             cl = parseCommandLine(args);
117         } catch (CommandLineHaltRequestedException e) {
118             System.exit(1);
119         }
120 
121         RunExperiment re = new RunExperiment();
122         re.setPropertiesFromCommandLine(cl);
123         re.run();
124     }
125 
126     private static CommandLine parseCommandLine(String[] args)
127             throws CommandLineHaltRequestedException {
128         EXPERIMENT_OPTION.setRequired(true);
129         EXPERIMENT_OPTION.setArgs(1);
130         EXPERIMENT_OPTION.setArgName("conf-file");
131 
132         Options options = new Options();
133         options.addOption(EXPERIMENT_OPTION);
134         options.addOption(QUIET_OPTION);
135         options.addOption(VERB_OPTION);
136         options.addOption(DEBUG_OPTION);
137 
138         // is `help' option requested?
139         for (int i = 0; i < args.length; i++) {
140             if (args[i].equals("-" + HELP_OPTION.getOpt())
141                     || args[i].equals("--" + HELP_OPTION.getLongOpt())) {
142                 printHelpMessage(USAGE_MESG, options);
143                 throw new CommandLineHaltRequestedException();
144             }
145         }
146 
147         CommandLine cl = null;
148 
149         try {
150             return (new GnuParser()).parse(options, args);
151         } catch (ParseException e) {
152             if (e instanceof MissingOptionException) {
153                 printErrorMessage("Missing required option `" + e.getMessage() + "'.");
154             } else if (e instanceof MissingArgumentException) {
155                 printErrorMessage("Missing required argument.");
156             } else if (e instanceof UnrecognizedOptionException) {
157                 printErrorMessage("Unrecognized option `" + e.getMessage() + "'.");
158             } else {
159                 printErrorMessage(e.getMessage());
160             }
161             printHelpMessage(USAGE_MESG, options);
162             throw new CommandLineHaltRequestedException();
163         }
164     }
165 
166     /***
167      * 
168      */
169     public RunExperiment() {
170         super();
171     }
172 
173 	/***
174 	 * @return Returns the experimentFileName.
175 	 * 
176 	 * @uml.property name="experimentFileName"
177 	 */
178 	public String getExperimentFileName() {
179 		return experimentFileName;
180 	}
181 
182 	/***
183 	 * @return Returns the verbose.
184 	 * 
185 	 * @uml.property name="verbose"
186 	 */
187 	public boolean isVerbose() {
188 		return verbose;
189 	}
190 
191 	/***
192 	 * @return Returns the welcomeMsgEnabled.
193 	 * 
194 	 * @uml.property name="welcomeMsgEnabled"
195 	 */
196 	public boolean isWelcomeMsgEnabled() {
197 		return welcomeMsgEnabled;
198 	}
199 
200 
201     /***
202      * 
203      * @see java.lang.Runnable#run()
204      */
205     public void run() {
206 
207         if (isWelcomeMsgEnabled()) {
208             System.out.println(WELCOME_MESG);
209         }
210 
211         if (isVerbose()) {
212             Logger.getRootLogger().setLevel(Level.INFO);
213         }
214 
215         if (isDebug()) {
216             Logger.getRootLogger().setLevel(Level.DEBUG);
217         }
218 
219         Experiment experiment = null;
220         FileReader reader;
221 
222         try {
223             reader = new FileReader(getExperimentFileName());
224             experiment = (Experiment) (new CastorXmlSerializer()).deSerialize(Experiment.class,
225                     reader);
226         } catch (SerializationException e2) {
227             log.debug(e2);
228             printErrorMessage("Unable to parse the experiment file.");
229             return;
230         } catch (FileNotFoundException e1) {
231             log.debug(e1);
232             printErrorMessage("The experiment file supplied does not exists.");
233             return;
234         }
235 
236         try {
237             experiment.getEnvironment().validate();
238         } catch (ValidationException e4) {
239             printErrorMessage("The test environment is not set up correctly, check your configuration file.");
240             return;
241         }
242 
243         experiment.getNeuralNetwork().setEnvironment(experiment.getEnvironment());
244 
245         log.info("Configuration loaded, everything seems to be ok...");
246         log.debug("Using " + experiment.getNeuralNetwork().getBindedNetworkClass()
247                 + " as learning method.");
248         log.debug("Using " + experiment.getEnvironment() + " as test environment.");
249 
250         int numberOfRuns = experiment.getEnvironment().getNumberOfSystemRuns();
251 
252         if (numberOfRuns == 0) {
253             printErrorMessage("According to your configuration the number of system run is zero, therefore I wont run ;).");
254         }
255 
256         int padding = numberOfRuns / 10;
257 
258         for (int run = 0; run < numberOfRuns; run++) {
259             log.info("Starting system run number: " + String.valueOf(run + 1) + " of "
260                     + numberOfRuns + ".");
261 
262             log.debug("Loading datasets...");
263 
264             InputOutputPattern[] trainPatterns = null;
265             Pattern[] testPatterns = null;
266 
267             try {
268                 trainPatterns = experiment.getEnvironment().getTrainingDataset(run);
269                 testPatterns = experiment.getEnvironment().getTestDatasetInputs(run);
270             } catch (EnvironmentException e) {
271                 log.debug(e);
272                 printErrorMessage("The specified problem dataset location is invalid.");
273                 return;
274             }
275 
276             log.debug("Training set size: " + trainPatterns.length + ", test set size: "
277                     + testPatterns.length + ".");
278 
279             NeuralNetwork nn = experiment.getNeuralNetwork().configuredNetworkFactory();
280 
281             log.debug("Training (this may take a while)...");
282 
283             nn.train(trainPatterns);
284 
285             log.debug("Testing... ");
286 
287             Pattern[] predictions = new Pattern[testPatterns.length];
288             for (int i = 0; i < testPatterns.length; i++) {
289                 predictions[i] = nn.predict(testPatterns[i]);
290             }
291 
292             log.debug("Writing results...");
293 
294             try {
295                 experiment.getEnvironment().writeResults(predictions, run);
296             } catch (EnvironmentException e) {
297                 log.debug(e);
298                 printErrorMessage("Imposible to write prediction results.");
299                 return;
300             }
301 
302             if (experiment.getStorage() != null) {
303                 log.info("Saving network...");
304                 IStorage storage = experiment.getStorage();
305 
306                 if (storage instanceof XmlStorage) {
307                 	XmlStorage xmlStorage = (XmlStorage) storage;
308                     String origSuffix = xmlStorage.getFileNameSuffix();
309                     xmlStorage.setFileNameSuffix(StringUtils.leftPad(String.valueOf(run), padding,
310                             "0")
311                             + origSuffix);
312                     String key = storage.generateKey(nn);
313                     try {
314                         storage.insert(nn, key);
315                     } catch (DuplicateKeyException e3) {
316                         // TODO Auto-generated catch block
317                         e3.printStackTrace();
318                     } catch (StorageException e3) {
319                         log.debug(e3);
320                         printErrorMessage("Unable to store network. Probable cause: "
321                                 + e3.getMessage() + ".");
322                     }
323                 }
324             }
325         }
326         if (isWelcomeMsgEnabled()) {
327             System.out.println("I have finished without errors, bye, bye...");
328         }
329     }
330 
331 	/***
332 	 * @param experimentFileName
333 	 *            The experimentFileName to set.
334 	 */
335 	public void setExperimentFileName(String experimentFileName) {
336 		this.experimentFileName = experimentFileName;
337 	}
338 
339 
340     private void setPropertiesFromCommandLine(CommandLine cl) {
341         setExperimentFileName(cl.getOptionValue(EXPERIMENT_OPTION.getOpt()));
342         setVerbose(cl.hasOption(VERB_OPTION.getOpt()));
343         setDebug(cl.hasOption(DEBUG_OPTION.getOpt()));
344         setWelcomeMsgEnabled(!cl.hasOption(QUIET_OPTION.getOpt()));
345     }
346 
347 	/***
348 	 * @param verbose
349 	 *            The verbose to set.
350 	 */
351 	public void setVerbose(boolean verbose) {
352 		this.verbose = verbose;
353 	}
354 
355 	/***
356 	 * @param welcomeMsgEnabled
357 	 *            The welcomeMsgEnabled to set.
358 	 */
359 	public void setWelcomeMsgEnabled(boolean welcomeMsgEnabled) {
360 		this.welcomeMsgEnabled = welcomeMsgEnabled;
361 	}
362 
363 }