/// <summary> /// This is the callback control function of the regression process and is called by State Machine /// after the completion of each regression training epoch. /// /// The goal of the regression process is for each output field to train a readout network(s) /// that will give good results both on the training data and the test data. An instance of the /// Regression.RegressionControlInArgs class passed to this function contains the best error statistics so far /// and the latest statistics. The primary purpose of this function is to decide whether the latest statistics /// are better than the best statistics so far. Here is used simply the default implementation of the decision, but /// the logic can be much more complicated in real-world situations. /// The function can also tell the regression process that it does not make any sense to continue the regression. /// It can terminate the current regression attempt or whole readout unit regression process. /// /// The secondary purpose of this function is to inform about the regression process progress. /// </summary> /// <param name="inArgs">Contains all the necessary information to control the regression.</param> /// <returns>Instructions for the regression process.</returns> public static ReadoutUnit.RegressionControlOutArgs RegressionControl(ReadoutUnit.RegressionControlInArgs inArgs) { //Instantiate output object. ReadoutUnit.RegressionControlOutArgs outArgs = new ReadoutUnit.RegressionControlOutArgs { //Call the default implementation of the judgement. CurrentIsBetter = ReadoutUnit.IsBetter(inArgs.TaskType, inArgs.CurrReadoutUnit, inArgs.BestReadoutUnit) }; //Report the progress if (outArgs.CurrentIsBetter || (inArgs.Epoch % 10) == 0 || inArgs.Epoch == inArgs.MaxEpochs || (inArgs.Epoch == 1 && inArgs.RegrAttemptNumber == 1)) { //Mark the currently best readout unit ReadoutUnit bestReadoutUnit = outArgs.CurrentIsBetter ? inArgs.CurrReadoutUnit : inArgs.BestReadoutUnit; //Build progress text message StringBuilder progressText = new StringBuilder(); progressText.Append(" OutputField: "); progressText.Append(inArgs.OutputFieldName); progressText.Append(", Fold/Attempt/Epoch: "); progressText.Append(inArgs.FoldNum.ToString().PadLeft(inArgs.NumOfFolds.ToString().Length, '0') + "/"); progressText.Append(inArgs.RegrAttemptNumber.ToString().PadLeft(inArgs.RegrMaxAttempts.ToString().Length, '0') + "/"); progressText.Append(inArgs.Epoch.ToString().PadLeft(inArgs.MaxEpochs.ToString().Length, '0')); progressText.Append(", DSet-Sizes: ("); progressText.Append(inArgs.CurrReadoutUnit.TrainingErrorStat.NumOfSamples.ToString() + ", "); progressText.Append(inArgs.CurrReadoutUnit.TestingErrorStat.NumOfSamples.ToString() + ")"); progressText.Append(", Best-Train: "); progressText.Append(bestReadoutUnit.TrainingErrorStat.ArithAvg.ToString("E3", CultureInfo.InvariantCulture)); if (inArgs.TaskType == CommonEnums.TaskType.Classification) { //Append binary errors progressText.Append("/" + bestReadoutUnit.TrainingBinErrorStat.TotalErrStat.Sum.ToString(CultureInfo.InvariantCulture)); progressText.Append("/" + bestReadoutUnit.TrainingBinErrorStat.BinValErrStat[1].Sum.ToString(CultureInfo.InvariantCulture)); } progressText.Append(", Best-Test: "); progressText.Append(bestReadoutUnit.TestingErrorStat.ArithAvg.ToString("E3", CultureInfo.InvariantCulture)); if (inArgs.TaskType == CommonEnums.TaskType.Classification) { //Append binary errors progressText.Append("/" + bestReadoutUnit.TestingBinErrorStat.TotalErrStat.Sum.ToString(CultureInfo.InvariantCulture)); progressText.Append("/" + bestReadoutUnit.TestingBinErrorStat.BinValErrStat[1].Sum.ToString(CultureInfo.InvariantCulture)); } progressText.Append(", Curr-Train: "); progressText.Append(inArgs.CurrReadoutUnit.TrainingErrorStat.ArithAvg.ToString("E3", CultureInfo.InvariantCulture)); if (inArgs.TaskType == CommonEnums.TaskType.Classification) { //Append binary errors progressText.Append("/" + inArgs.CurrReadoutUnit.TrainingBinErrorStat.TotalErrStat.Sum.ToString(CultureInfo.InvariantCulture)); progressText.Append("/" + inArgs.CurrReadoutUnit.TrainingBinErrorStat.BinValErrStat[1].Sum.ToString(CultureInfo.InvariantCulture)); } progressText.Append(", Curr-Test: "); progressText.Append(inArgs.CurrReadoutUnit.TestingErrorStat.ArithAvg.ToString("E3", CultureInfo.InvariantCulture)); if (inArgs.TaskType == CommonEnums.TaskType.Classification) { //Append binary errors progressText.Append("/" + inArgs.CurrReadoutUnit.TestingBinErrorStat.TotalErrStat.Sum.ToString(CultureInfo.InvariantCulture)); progressText.Append("/" + inArgs.CurrReadoutUnit.TestingBinErrorStat.BinValErrStat[1].Sum.ToString(CultureInfo.InvariantCulture)); } ((IOutputLog)inArgs.UserObject).Write(progressText.ToString(), !(inArgs.Epoch == 1 && inArgs.RegrAttemptNumber == 1)); } return(outArgs); }
/// <summary> /// This is the callback control function of the regression process and is called by State Machine /// after the completion of each training epoch. /// /// The goal of the regression process is to train for each output field the readout network(s) /// that will give good results both on the training data and the test data. An instance of the /// Regression.RegressionControlInArgs class passed to this function contains the best error statistics so far /// and the latest statistics. The primary purpose of this function is to decide whether the latest statistics /// are better than the best statistics so far. Here is used simply the default implementation of the decision, but /// the logic can be much more complicated in real-world situations. /// The function can also tell the regression process that it does not make any sense to continue the regression. /// It can terminate the current regression attempt or whole readout unit regression process. /// /// The secondary purpose of this function is to inform about the regression process progress. /// </summary> /// <param name="inArgs">Contains all the necessary information to control the regression.</param> /// <returns>Instructions for the regression process.</returns> public static ReadoutUnit.RegressionControlOutArgs RegressionControl(ReadoutUnit.RegressionControlInArgs inArgs) { const int reportEpochsInterval = 10; //Instantiate output object to set instructions for the regression process. ReadoutUnit.RegressionControlOutArgs outArgs = new ReadoutUnit.RegressionControlOutArgs { //Call the default implementation of the judgement. CurrentIsBetter = ReadoutUnit.IsBetter(inArgs.TaskType, inArgs.CurrReadoutUnit, inArgs.BestReadoutUnit), StopRegression = (inArgs.TaskType == ReadoutUnit.TaskType.Classification && inArgs.CurrReadoutUnit.TrainingBinErrorStat.TotalErrStat.Sum == 0 && inArgs.CurrReadoutUnit.TestingBinErrorStat.TotalErrStat.Sum == 0 ) }; //Progress info if (outArgs.CurrentIsBetter || (inArgs.Epoch % reportEpochsInterval) == 0 || inArgs.Epoch == inArgs.MaxEpochs || (inArgs.Epoch == 1 && inArgs.RegrAttemptNumber == 1) ) { //Build progress report message string progressText = ReadoutLayer.GetProgressReport(inArgs, outArgs.CurrentIsBetter ? inArgs.CurrReadoutUnit : inArgs.BestReadoutUnit, 6); //Report the progress ((IOutputLog)inArgs.UserObject).Write(progressText, !(inArgs.Epoch == 1 && inArgs.RegrAttemptNumber == 1)); } return(outArgs); }
/// <summary> /// This is the control function of the regression process and is called /// after the completion of each regression training epoch. /// The goal of the regression process is for each output field to train a readout network /// that will give good results both on the training data and the test data. /// Regression.RegressionControlInArgs object passed to the function contains the best error statistics so far /// and the latest statistics. The primary purpose of the function is to decide whether the latest statistics /// are better than the best statistics so far. /// Here is used simply the default implementation of the decision, but /// the the implemented logic can be much more complicated in real-world situations. /// The function can also tell the regression process that it does not make any sense to continue the regression. /// It can terminate the current regression attempt or whole readout unit regression process. /// </summary> /// <param name="inArgs">Contains all the necessary information to control the progress of the regression.</param> /// <returns>Instructions for the regression process.</returns> public static ReadoutUnit.RegressionControlOutArgs RegressionControl(ReadoutUnit.RegressionControlInArgs inArgs) { //Instantiate output object. ReadoutUnit.RegressionControlOutArgs outArgs = new ReadoutUnit.RegressionControlOutArgs(); //Call the default implementation of the judgement. outArgs.CurrentIsBetter = ReadoutUnit.IsBetter(inArgs.TaskType, inArgs.CurrReadoutUnit, inArgs.BestReadoutUnit); //Report the progress int reportInterval = Math.Max(inArgs.MaxEpochs / 100, 1); ReadoutUnit bestReadoutUnit = outArgs.CurrentIsBetter ? inArgs.CurrReadoutUnit : inArgs.BestReadoutUnit; if (outArgs.CurrentIsBetter || (inArgs.Epoch % reportInterval) == 0 || inArgs.Epoch == inArgs.MaxEpochs || (inArgs.Epoch == 1 && inArgs.RegrAttemptNumber == 1)) { ((IOutputLog)inArgs.UserObject).Write( " OutputField: " + inArgs.OutputFieldName + ", Fold/Attempt/Epoch: " + inArgs.FoldNum.ToString().PadLeft(inArgs.NumOfFolds.ToString().Length, '0') + "/" + inArgs.RegrAttemptNumber.ToString().PadLeft(inArgs.RegrMaxAttempts.ToString().Length, '0') + "/" + inArgs.Epoch.ToString().PadLeft(inArgs.MaxEpochs.ToString().Length, '0') + ", DSet-Sizes: (" + inArgs.CurrReadoutUnit.TrainingErrorStat.NumOfSamples.ToString() + ", " + inArgs.CurrReadoutUnit.TestingErrorStat.NumOfSamples.ToString() + ")" + ", Best-Train: " + bestReadoutUnit.TrainingErrorStat.ArithAvg.ToString("E3", CultureInfo.InvariantCulture) + (inArgs.TaskType == CommonEnums.TaskType.Classification ? "/" : string.Empty) + (inArgs.TaskType == CommonEnums.TaskType.Classification ? bestReadoutUnit.TrainingBinErrorStat.TotalErrStat.Sum.ToString(CultureInfo.InvariantCulture) : string.Empty) + (inArgs.TaskType == CommonEnums.TaskType.Classification ? "/" : string.Empty) + (inArgs.TaskType == CommonEnums.TaskType.Classification ? bestReadoutUnit.TrainingBinErrorStat.BinValErrStat[1].Sum.ToString(CultureInfo.InvariantCulture) : string.Empty) + ", Best-Test: " + bestReadoutUnit.TestingErrorStat.ArithAvg.ToString("E3", CultureInfo.InvariantCulture) + (inArgs.TaskType == CommonEnums.TaskType.Classification ? "/" : string.Empty) + (inArgs.TaskType == CommonEnums.TaskType.Classification ? bestReadoutUnit.TestingBinErrorStat.TotalErrStat.Sum.ToString(CultureInfo.InvariantCulture) : string.Empty) + (inArgs.TaskType == CommonEnums.TaskType.Classification ? "/" : string.Empty) + (inArgs.TaskType == CommonEnums.TaskType.Classification ? bestReadoutUnit.TestingBinErrorStat.BinValErrStat[1].Sum.ToString(CultureInfo.InvariantCulture) : string.Empty) + ", Curr-Train: " + inArgs.CurrReadoutUnit.TrainingErrorStat.ArithAvg.ToString("E3", CultureInfo.InvariantCulture) + (inArgs.TaskType == CommonEnums.TaskType.Classification ? "/" : string.Empty) + (inArgs.TaskType == CommonEnums.TaskType.Classification ? inArgs.CurrReadoutUnit.TrainingBinErrorStat.TotalErrStat.Sum.ToString(CultureInfo.InvariantCulture) : string.Empty) + (inArgs.TaskType == CommonEnums.TaskType.Classification ? "/" : string.Empty) + (inArgs.TaskType == CommonEnums.TaskType.Classification ? inArgs.CurrReadoutUnit.TrainingBinErrorStat.BinValErrStat[1].Sum.ToString(CultureInfo.InvariantCulture) : string.Empty) + ", Curr-Test: " + inArgs.CurrReadoutUnit.TestingErrorStat.ArithAvg.ToString("E3", CultureInfo.InvariantCulture) + (inArgs.TaskType == CommonEnums.TaskType.Classification ? "/" : string.Empty) + (inArgs.TaskType == CommonEnums.TaskType.Classification ? inArgs.CurrReadoutUnit.TestingBinErrorStat.TotalErrStat.Sum.ToString(CultureInfo.InvariantCulture) : string.Empty) + (inArgs.TaskType == CommonEnums.TaskType.Classification ? "/" : string.Empty) + (inArgs.TaskType == CommonEnums.TaskType.Classification ? inArgs.CurrReadoutUnit.TestingBinErrorStat.BinValErrStat[1].Sum.ToString(CultureInfo.InvariantCulture) : string.Empty) , !(inArgs.Epoch == 1 && inArgs.RegrAttemptNumber == 1)); } return(outArgs); }