private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { TrainingThreadParameters parameters = (TrainingThreadParameters)e.Argument; TrainingOptions options = parameters.Options; double[][] inputs = parameters.Inputs; double[][] outputs = parameters.Outputs; //Create Teacher BackPropagationLearning networkTeacher = new BackPropagationLearning(activationNetwork); networkTeacher.LearningRate = options.LearningRate1; networkTeacher.Momentum = options.Momentum; //Start Training bool stop = false; bool complete = false; int lastStatusEpoch = 0; int lastSaveEpoch = 0; int lastValidateEpoch = 0; backgroundWorker.ReportProgress(0, BackgroundWorkerUpdate.Starting); #region Main Training Loop while (!stop) { // Run training epoch status.TrainingError = networkTeacher.RunEpoch(inputs, outputs); if (options.Validate && status.Epoch >= lastValidateEpoch + options.ValidateEpochs) { status.ValidationError = networkTeacher.MeasureEpochError(inputs, outputs); } // Adjust Training Rate if (options.ChangeLearningRate) { networkTeacher.LearningRate = options.LearningRate2; } // Register Savepoint if (options.MarkSavepoints && status.Epoch >= lastSaveEpoch + options.MarkSavepointsEpochs) { backgroundWorker.ReportProgress(0, BackgroundWorkerUpdate.NetworkSave); lastSaveEpoch = status.Epoch; } // Progress Indicator if (options.ReportProgress && status.Epoch >= lastStatusEpoch + options.ReportProgressEpochs) { if (options.Limit == TrainingOptions.TrainingLimit.ByError) { if (status.TrainingError != 0) // Check to avoid division by zero { status.Progress = Math.Max(Math.Min((int)((options.LimitByError * 100) / status.TrainingError), 100), 0); } } else if (options.Limit == TrainingOptions.TrainingLimit.ByEpoch) { if (status.Epoch != 0) // Check to avoid division by zero { status.Progress = Math.Max(Math.Min((int)((status.Epoch * 100) / options.LimitByEpochs), 100), 0); } } backgroundWorker.ReportProgress(0, BackgroundWorkerUpdate.Progress); lastStatusEpoch = status.Epoch; } // Increment epoch counter ++status.Epoch; if (options.Delay) { // Sleep thread according to specified delay System.Threading.Thread.Sleep(options.DelayMilliseconds); } // Check stop conditions if ((options.Limit == TrainingOptions.TrainingLimit.ByError && status.TrainingError <= options.LimitByError) || (options.Limit == TrainingOptions.TrainingLimit.ByEpoch && status.Epoch >= options.LimitByEpochs)) { complete = true; stop = true; } // Check for cancellation requests if (backgroundWorker.CancellationPending) { e.Cancel = true; stop = true; } while (state == SessionState.Paused) { System.Threading.Thread.Sleep(1000); } } // End main training loop #endregion // Do a last update before exiting the thread if (complete) { backgroundWorker.ReportProgress(0, BackgroundWorkerUpdate.Completed); } else { backgroundWorker.ReportProgress(0, BackgroundWorkerUpdate.Progress); } }
//--------------------------------------------- #region Worker Thread private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { if (!(e.Argument is TrainingOptions)) { backgroundWorker.ReportProgress(0, "Bad thread argument!"); e.Cancel = true; return; } TrainingOptions options = (TrainingOptions)e.Argument; //Create Teacher BackPropagationLearning networkTeacher = new BackPropagationLearning(m_networkContainer.ActivationNetwork); networkTeacher.LearningRate = options.firstLearningRate; networkTeacher.Momentum = options.momentum; //Start Training bool stop = false; int lastStatusEpoch = 0; int lastGraphEpoch = 0; int lastSaveEpoch = 0; backgroundWorker.ReportProgress(0, "Training..."); while (!stop) { #region Training Epoch this.m_networkState.ErrorTraining = networkTeacher.RunEpoch(options.TrainingVectors.Input, options.TrainingVectors.Output) /* / options.TrainingVectors.Input.Length */; this.m_networkState.ErrorValidation = networkTeacher.MeasureEpochError(options.ValidationVectors.Input, options.ValidationVectors.Output) /* / options.ValidationVectors.Input.Length */; // Adjust Training Rate if (options.secondLearningRate.HasValue) { networkTeacher.LearningRate = options.secondLearningRate.Value; } #endregion #region Mark Network Savepoint if (Properties.Settings.Default.training_Autosave == true && m_networkState.Epoch >= lastSaveEpoch + Properties.Settings.Default.training_AutosaveEpochs) { backgroundWorker.ReportProgress(0, UpdateType.NetworkSave); lastSaveEpoch = m_networkState.Epoch; } #endregion #region Graph Update if (Properties.Settings.Default.graph_Disable == false && m_networkState.Epoch >= lastGraphEpoch + Properties.Settings.Default.graph_UpdateRate) { backgroundWorker.ReportProgress(0, UpdateType.Graph); lastGraphEpoch = m_networkState.Epoch; } #endregion #region Statusbar Update if (Properties.Settings.Default.display_UpdateByTime == false && m_networkState.Epoch >= lastStatusEpoch + Properties.Settings.Default.display_UpdateRate) { if (options.TrainingType == TrainingType.ByError) { if (m_networkState.ErrorTraining != 0) { m_networkState.Progress = Math.Max(Math.Min((int)((options.limError * 100) / m_networkState.ErrorTraining), 100), 0); } } else { if (m_networkState.Epoch != 0) { m_networkState.Progress = Math.Max(Math.Min((int)((m_networkState.Epoch * 100) / options.limEpoch), 100), 0); } } backgroundWorker.ReportProgress(0, UpdateType.Statusbar); lastStatusEpoch = m_networkState.Epoch; } #endregion ++m_networkState.Epoch; // Sleep thread according to specified delay System.Threading.Thread.Sleep(Properties.Settings.Default.training_delay); #region Stop Conditions if (options.TrainingType == TrainingType.ByError) { if (m_networkState.ErrorTraining <= options.limError) { stop = true; } } else if (options.TrainingType == TrainingType.ByEpoch) { if (m_networkState.Epoch >= options.limEpoch) { stop = true; } } if (backgroundWorker.CancellationPending) { e.Cancel = true; stop = true; } #endregion } backgroundWorker.ReportProgress(0); }