public TrainAndTestPage(NeuralNetRunType runtype, NeuralNet neuralnet, MNISTDataManager mnistdata) { // Define GUI // Page properties Title = string.Format("{0} Net", runtype.ToString().ToUpperFirstOnly()); BackgroundColor = Color.SteelBlue; Padding = new Thickness(Application.Current.MainPage.Width * 0.05, Application.Current.MainPage.Height * 0.05); // Label for description Label description = new Label { Text = string.Format("Please define the number of data sets from the MNIST {0} data base to be used for {0}ing. Each data set represents one digit. The {0} data base holds about {1:N0} data sets in total.", runtype.ToString(), mnistdata.CountData), Margin = new Thickness(0, 0, 0, Application.Current.MainPage.Height * 0.075) }; // Label for number of training / testing sets used Label label_useddatasets = new Label { Text = String.Format("{0:N0} data set{1} selected", mnistdata.UsedDataSets, mnistdata.UsedDataSets == 0 ? "" : "s"), Margin = new Thickness(0, 0, 0, Application.Current.MainPage.Height * 0.075) }; // Slider for number of data sets used for training / testing Slider slider_useddatasets = new Slider(1, mnistdata.CountData, mnistdata.UsedDataSets); slider_useddatasets.ValueChanged += (s, e) => { mnistdata.UsedDataSets = (int)e.NewValue; label_useddatasets.Text = String.Format("{0:N0} data set{1} selected", mnistdata.UsedDataSets, mnistdata.UsedDataSets == 0 ? "" : "s"); }; // Progress bar ProgressBar progressbar = new ProgressBar { Progress = 0 }; // Label for showing progress Label label_progress = new Label { Text = "Currently no calculation running", }; // Button to start training / testing Button button = new Button { Text = string.Format("Start {0}ing", runtype.ToString().ToUpperFirstOnly()), WidthRequest = Application.Current.MainPage.Width * 0.5, HeightRequest = Application.Current.MainPage.Height * 0.10 }; // Define page Content = new ScrollView { Content = new StackLayout { Children = { description, label_useddatasets, slider_useddatasets, button, progressbar, label_progress } } }; // Button event // Here training and test sessions are executed button.Clicked += async(s, e) => { // Check if another calculation is currently running if (activerun == true) { var answer = await DisplayAlert("Warning", "Do you want to stop current calculation?", "Yes", "No"); if (answer) { endrun = true; } return; } // Check if selected data set is big if (mnistdata.UsedDataSets > mnistdata.UsedDataSetsWarning) { bool answer = await DisplayAlert("Warning", "Please be aware that big data sets effect run time. Continue?", "Yes", "No"); if (!answer) { return; } } // Set activerun and endrun flags activerun = true; endrun = false; // Disable Back button NavigationPage.SetHasBackButton(this, false); // Rename Button to Stop button.Text = string.Format("Stop {0}ing", runtype.ToString().ToUpperFirstOnly()); // Define parameters for progress bar calculation (increase bar 100 times or each 20 runs) int progresssteps = Math.Max(100, mnistdata.UsedDataSets / 20); int progressspan = (int)Math.Ceiling((double)mnistdata.UsedDataSets / progresssteps); // Counter for training / testing runs int i = 0; // Initialize progress bar label_progress.Text = i.ToString() + " / " + mnistdata.UsedDataSets.ToString(); await progressbar.ProgressTo((double)i / mnistdata.UsedDataSets, 1, Easing.Linear); // Train neural net if (runtype == NeuralNetRunType.train) { while (i < mnistdata.UsedDataSets && endrun == false) { // Counter for runs in progress step int j = 0; // Training loop for one progress step done as task await Task.Run(() => { while (j < progressspan && i < mnistdata.UsedDataSets) { // Train net with data set i neuralnet.Train(mnistdata.Input(i), mnistdata.Output(i)); j++; i++; } // Remember number of training data sets neuralnet.TrainingDataCounter += j; }); // Update progress bar label_progress.Text = i.ToString() + " / " + mnistdata.UsedDataSets.ToString(); await progressbar.ProgressTo((double)i / mnistdata.UsedDataSets, 1, Easing.Linear); } // Show mesage await DisplayAlert("Result", string.Format("Neural net trained with {0:N0} data sets", i), "OK"); } if (runtype == NeuralNetRunType.test) { // Setup scorecard for capturing test results // digittotal counts all trained figures, digitcorrect the ones that are identified correctly Vector <double> digittotal = Vector <double> .Build.Dense(10); Vector <double> digitcorrect = Vector <double> .Build.Dense(10); // Testing loop while (i < mnistdata.UsedDataSets && endrun == false) { // Counter for runs in progress step int j = 0; // Testing loop for one progress step done as task await Task.Run(() => { while (j < progressspan && i < mnistdata.UsedDataSets) { // Increase counter for testet digit (0..9) int number = mnistdata.Number(i); digittotal[number]++; // Ask net Vector <double> answer = neuralnet.Query(mnistdata.Input(i)); // Check if it's correct if (answer.AbsoluteMaximumIndex() == number) { digitcorrect[number]++; } j++; i++; } // Remember number of training data sets neuralnet.TrainingDataCounter += j; }); // Update progress bar label_progress.Text = i.ToString() + " / " + mnistdata.UsedDataSets.ToString(); await progressbar.ProgressTo((double)i / mnistdata.UsedDataSets, 1, Easing.Linear); } // Remeber performance result neuralnet.Performance.Add(digitcorrect.Sum() / digittotal.Sum()); // Show test results await Navigation.PushAsync(new ResultsMNISTPage(neuralnet, mnistdata, digittotal, digitcorrect)); } // Reset progress bar label_progress.Text = "Currently no calculation running"; await progressbar.ProgressTo(0.0, 250, Easing.Linear); // Rename Button to Start button.Text = string.Format("Start {0}ing", runtype.ToString().ToUpperFirstOnly()); // Enable Back button NavigationPage.SetHasBackButton(this, true); // Cancel activerun flag activerun = false; }; }
public ResultsDetailsPage(NeuralNet neuralnet, MNISTDataManager mnistdata) { // Save parameters this.neuralnet = neuralnet; this.mnistdata = mnistdata; // Define GUI // Page properties Title = "Details"; BackgroundColor = Color.SteelBlue; Padding = new Thickness(Application.Current.MainPage.Width * 0.05, Application.Current.MainPage.Height * 0.05); // Step 1: Generate initial collection of pictures from MNIST database (buffersize elements) pictures = new ObservableCollection <CarouselItem>(); AddPictures(0); // Step 2: Generate data template (just a Image with data binding to CarouselItem class) DataTemplate template = new DataTemplate(() => { Image image = new Image(); image.SetBinding(Image.SourceProperty, "Picture"); return(image); }); // Step 3: Generate carousel view var myCarousel = new CarouselViewControl(); myCarousel.Position = 0; //default myCarousel.ItemsSource = pictures; myCarousel.ItemTemplate = template; myCarousel.InterPageSpacing = 2; myCarousel.Orientation = CarouselViewOrientation.Horizontal; myCarousel.ShowIndicators = false; myCarousel.HorizontalOptions = LayoutOptions.FillAndExpand; myCarousel.VerticalOptions = LayoutOptions.FillAndExpand; // Define labels labelheadline = new Label(); labeldigitcorrect = new Label(); labeldigitanswernet = new Label { HorizontalOptions = LayoutOptions.FillAndExpand, HeightRequest = Application.Current.MainPage.Height * 0.1, VerticalTextAlignment = TextAlignment.Center }; SetLabels(0); // Step 4: Build page Content = new ScrollView { Content = new StackLayout { Children = { labelheadline, labeldigitcorrect, myCarousel, labeldigitanswernet }, Spacing = Application.Current.MainPage.Height * 0.05 } }; // Update page when image is swiped myCarousel.PositionSelected += (s, e) => { // Add new pictures if user has reached end of carousel // KNOWN ERROR: When end is reached the wrong picture is displayed (first picture of uploaded data) // Warning: stepping through all MINST data may yield to memory problems if (myCarousel.Position == pictures.Count - 1) { AddPictures(myCarousel.Position + 1); } // Update label SetLabels(myCarousel.Position); }; }
public ResultsMNISTPage(NeuralNet neuralnet, MNISTDataManager mnistdata, Vector <double> digittotal, Vector <double> digitcorrect) { // Define GUI // Page properties Title = "Results"; BackgroundColor = Color.SteelBlue; Padding = new Thickness(Application.Current.MainPage.Width * 0.05, Application.Current.MainPage.Height * 0.05); // Define styles for labels in grid var labelgridStyle = new Style(typeof(Label)) { Setters = { new Setter { Property = Label.TextColorProperty, Value = Color.GhostWhite }, new Setter { Property = Label.BackgroundColorProperty, Value = Color.SteelBlue }, new Setter { Property = Label.HorizontalOptionsProperty, Value = LayoutOptions.FillAndExpand }, new Setter { Property = Label.HorizontalTextAlignmentProperty, Value = TextAlignment.Center }, new Setter { Property = Label.VerticalOptionsProperty, Value = LayoutOptions.FillAndExpand }, new Setter { Property = Label.VerticalTextAlignmentProperty, Value = TextAlignment.Center } } }; var labelgridhighlightStyle = new Style(typeof(Label)) { BasedOn = labelgridStyle, Setters = { new Setter { Property = Label.TextColorProperty, Value = Color.GhostWhite }, new Setter { Property = Label.BackgroundColorProperty, Value = Color.DarkOrange }, new Setter { Property = Label.FontAttributesProperty, Value = FontAttributes.Bold } } }; var labelgridheadlineStyle = new Style(typeof(Label)) { BasedOn = labelgridStyle, Setters = { new Setter { Property = Label.TextColorProperty, Value = Color.SteelBlue }, new Setter { Property = Label.BackgroundColorProperty, Value = Color.GhostWhite }, new Setter { Property = Label.FontAttributesProperty, Value = FontAttributes.Bold } } }; // Define 11x3 grid for representing results Grid grid = new Grid(); grid.BackgroundColor = Color.GhostWhite; grid.ColumnSpacing = 1; grid.RowSpacing = 1; grid.Padding = new Thickness(1); grid.HorizontalOptions = LayoutOptions.FillAndExpand; grid.VerticalOptions = LayoutOptions.FillAndExpand; for (int i = 0; i < 4; i++) { grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); } for (int i = 0; i < 12; i++) { grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }); } // Add headlines to grid grid.Children.Add(new Label { Text = "Digit", Style = labelgridheadlineStyle }, 0, 0); grid.Children.Add(new Label { Text = "Total", Style = labelgridheadlineStyle }, 1, 0); grid.Children.Add(new Label { Text = "Correct", Style = labelgridheadlineStyle }, 2, 0); grid.Children.Add(new Label { Text = "in %", Style = labelgridheadlineStyle }, 3, 0); // Add results for each digit to grid for (int i = 0; i < 10; i++) { grid.Children.Add(new Label { Text = i.ToString(), Style = labelgridStyle }, 0, i + 1); grid.Children.Add(new Label { Text = String.Format("{0:N0}", digittotal[i]), Style = labelgridStyle }, 1, i + 1); grid.Children.Add(new Label { Text = String.Format("{0:N0}", digitcorrect[i]), Style = labelgridStyle }, 2, i + 1); grid.Children.Add(new Label { Text = String.Format("{0:P0}", digittotal[i] > 0 ? digitcorrect[i] / digittotal[i] : 0), Style = labelgridStyle }, 3, i + 1); } // Add sum to grid grid.Children.Add(new Label { Text = "Sum", Style = labelgridhighlightStyle }, 0, 11); grid.Children.Add(new Label { Text = String.Format("{0:N0}", digittotal.Sum()), Style = labelgridhighlightStyle }, 1, 11); grid.Children.Add(new Label { Text = String.Format("{0:N0}", digitcorrect.Sum()), Style = labelgridhighlightStyle }, 2, 11); grid.Children.Add(new Label { Text = String.Format("{0:P0}", digitcorrect.Sum() / digittotal.Sum()), Style = labelgridhighlightStyle }, 3, 11); // Define button for details Button button = new Button { Text = "Details", WidthRequest = Application.Current.MainPage.Width * 0.8, HeightRequest = Application.Current.MainPage.Height * 0.10, VerticalOptions = LayoutOptions.Center, }; // Show page with detailed results for each digit button.Clicked += (s, e) => { if (messageflag == false) { DisplayAlert("Information", "Look at the details by swiping left and right.", "OK"); messageflag = true; } Navigation.PushAsync(new ResultsDetailsPage(neuralnet, mnistdata)); }; // Define page Content = new ScrollView { Content = new StackLayout { Children = { grid, button }, Spacing = Application.Current.MainPage.Height * 0.05 } }; }