static void Main(string[] args) { CultureInfo customCulture = (CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone(); customCulture.NumberFormat.NumberDecimalSeparator = "."; System.Threading.Thread.CurrentThread.CurrentCulture = customCulture; /* * Tinker(); * Console.ReadLine(); * Environment.Exit(0); */ NetworkModel model = null; bool teaching = false; int epochRuns = 1; int repeats = 1; string inputFile = null; CommandLine.Parser.Default.ParseArguments <Options>(args) .WithParsed <Options>(opts => { teaching = opts.Teaching; epochRuns = opts.EpochRuns; repeats = opts.Repeats; Debug = opts.Debug; #if !DEBUG try { #endif model = NetworkModel.Load(opts.Model); inputFile = model.Path(opts.Input); #if !DEBUG Console.Clear(); } catch (Exception e) { Console.WriteLine(e.Message); Environment.Exit(1); } #endif }); if (model is null) { Environment.Exit(0); } if (teaching) { Console.WriteLine("Launching model in teaching mode"); // Save newly generated model. if (!model.Loaded) { model.Save(); } var plotModel = new PlotModel { Title = String.Format("{0} model \"{1}\" learning graph", model.Config.Type, model.Name) }; var series = new OxyPlot.Series.LineSeries(); try { var graphMatrix = DelimitedReader.Read <double>(model.Path("graph")); for (int i = 0; i < graphMatrix.RowCount; i++) { series.Points.Add(new DataPoint(i + 1, graphMatrix.Row(i).At(0))); } } catch { } plotModel.Series.Add(series); plotModel.Axes.Add(new OxyPlot.Axes.LinearAxis { Minimum = 1, Position = OxyPlot.Axes.AxisPosition.Bottom, Title = "Epochs", }); plotModel.Axes.Add(new OxyPlot.Axes.LinearAxis { Position = OxyPlot.Axes.AxisPosition.Left, Title = "Cost", }); var epochOffset = series.Points.Count; var epoch = epochOffset; var epochRunStep = epochRuns; var stopwatch = new Stopwatch(); var epochStopwatch = new Stopwatch(); bool forceStop = false; stopwatch.Restart(); var repeat = 1; while (epochRuns == 0 || epoch < epochRuns + epochOffset) { Console.Write("\nepoch {0} / {1}...", ++epoch, epochOffset + epochRuns); var previous = model.GetInfo(); epochStopwatch.Restart(); stopwatch.Start(); var cost = model.RunEpoch(); stopwatch.Stop(); Console.Write(" {0:f2} + {1:f2}s,", stopwatch.Elapsed.TotalSeconds, epochStopwatch.Elapsed.TotalSeconds); Console.Write(" cost {0}", cost); series.Points.Add(new DataPoint(epoch, cost)); if (model.Config.Threshold != null && Math.Abs(cost) <= model.Config.Threshold) { Console.WriteLine("\nError threshold ({0}) reached. Finished learning.", model.Config.Threshold); forceStop = true; } if (epochRuns == 0 || epoch >= epochRuns + epochOffset || forceStop) { forceStop = false; epochRuns += epochRunStep; var pngExporter = new PngExporter(); pngExporter.ExportToFile(plotModel, model.Path("learning-graph.png")); if (repeat++ >= repeats) { DisplayActions(model, series); } else { SaveModel(model, series); } } } } else { if (model.DataTransformer is Model.Transformers.VectorDataTransformer) { Console.WriteLine("Running execution loop\n"); while (true) { Console.WriteLine("Model info:"); Console.WriteLine("==========="); Console.WriteLine(model.GetInfo()); DisplayActions(model); var inputs = Vector <double> .Build.Dense(model.Config.Inputs); for (int i = 0; i < model.Config.Inputs; i++) { inputs[i] = ReadDouble(String.Format("Input[{0}]", i)); } Console.Clear(); Console.WriteLine("Inputs:"); Console.WriteLine("======="); Console.WriteLine(inputs.ToVectorString()); Console.WriteLine("Result:"); Console.WriteLine("======="); foreach (var label in model.Run(inputs)) { Console.WriteLine(label); } Console.WriteLine(); } } else if (model.DataTransformer is Model.Transformers.MnistDataTransformer) { if (!File.Exists(inputFile)) { Console.WriteLine("Input file '{0}' doesn't exist", inputFile); Environment.Exit(1); } var inputs = model.InputTransformer.Transform(inputFile).Row(0); foreach (var label in model.Run(inputs)) { Console.WriteLine(label); } } else { Console.WriteLine("Unsupported model input transformer '{0}'.", model.DataTransformer); Environment.Exit(1); } } }