/// <summary> /// Creates the instance and initializes it from given xml element. /// </summary> /// <param name="readoutUnitElem"> /// Xml data containing the settings. /// </param> public ReadoutUnitSettings(XElement readoutUnitElem) { Name = readoutUnitElem.Attribute("name").Value; TaskType = CommonEnums.ParseTaskType(readoutUnitElem.Attribute("task").Value); //Net settings List <XElement> netSettingsElems = new List <XElement>(); netSettingsElems.AddRange(readoutUnitElem.Descendants("ff")); netSettingsElems.AddRange(readoutUnitElem.Descendants("pp")); if (netSettingsElems.Count != 1) { throw new Exception("Only one network configuration can be specified in readout unit settings."); } if (netSettingsElems.Count == 0) { throw new Exception("Network configuration is not specified in readout unit settings."); } XElement netSettingsElem = netSettingsElems[0]; //FF? if (netSettingsElem.Name.LocalName == "ff") { NetType = ReadoutUnitNetworkType.FF; NetSettings = new FeedForwardNetworkSettings(netSettingsElem); OutputRange = ((FeedForwardNetworkSettings)NetSettings).OutputRange.DeepClone(); } else { //PP NetType = ReadoutUnitNetworkType.PP; NetSettings = new ParallelPerceptronSettings(netSettingsElem); OutputRange = ((ParallelPerceptronSettings)NetSettings).OutputRange.DeepClone(); } return; }
/// <summary> /// The default implementation of a judgement if the current readout unit is better than for now the best readout unit /// </summary> /// <param name="taskType">Type of the task</param> /// <param name="current">Current readout unit</param> /// <param name="best">For now the best readout unit</param> public static bool IsBetter(CommonEnums.TaskType taskType, ReadoutUnit current, ReadoutUnit best) { switch (taskType) { case CommonEnums.TaskType.Classification: if (current.CombinedBinaryError < best.CombinedBinaryError) { return(true); } else if (current.CombinedBinaryError == best.CombinedBinaryError) { if (current.TestingBinErrorStat.TotalErrStat.Sum < best.TestingBinErrorStat.TotalErrStat.Sum) { return(true); } else if (current.TrainingBinErrorStat.TotalErrStat.Sum < best.TrainingBinErrorStat.TotalErrStat.Sum) { return(true); } else if (current.CombinedPrecisionError < best.CombinedPrecisionError) { return(true); } } return(false); default: //Forecast task type return(current.CombinedPrecisionError < best.CombinedPrecisionError); } }
//Constructors /// <summary> /// Creates an unitialized instance /// </summary> public ReadoutUnitSettings() { Name = ""; TaskType = CommonEnums.TaskType.Forecast; NetType = ReadoutUnitNetworkType.FF; NetSettings = null; OutputRange = null; return; }
//Constructors /// <summary> /// Creates an unitialized instance /// </summary> public ReadoutUnitSettings() { Name = ""; TaskType = CommonEnums.TaskType.Forecast; NetType = ReadoutUnitNetworkType.FF; NetSettings = null; OutputRange = null; RegressionAttempts = 0; RegressionAttemptEpochs = 0; return; }
/// <summary> /// Constructs an instance prepared for initialization (updates) /// </summary> /// <param name="taskType"></param> /// <param name="numOfReadoutUnits"></param> /// <param name="refBinDistr"></param> public ClusterErrStatistics(CommonEnums.TaskType taskType, int numOfReadoutUnits, BinDistribution refBinDistr) { TaskType = taskType; NumOfReadoutUnits = numOfReadoutUnits; PrecissionErrStat = new BasicStat(); BinaryErrStat = null; if (TaskType == CommonEnums.TaskType.Classification) { BinaryErrStat = new BinErrStat(refBinDistr); } return; }
//Constructor /// <summary> /// Creates an uninitialized instance /// </summary> /// <param name="taskType">Type of the task</param> /// <param name="settings">Readout layer configuration</param> /// <param name="rand">Random object to be used</param> public ReadoutLayer(CommonEnums.TaskType taskType, ReadoutLayerSettings settings, System.Random rand ) { _taskType = taskType; _settings = settings.DeepClone(); _rand = rand; _clusterCollection = new ReadoutUnit[_settings.OutputFieldNameCollection.Count][]; _clusterErrStatisticsCollection = new List <ClusterErrStatistics>(); return; }
/// <summary> /// Copy constructor /// </summary> /// <param name="source">Source instance</param> public ReadoutUnitSettings(ReadoutUnitSettings source) { Name = source.Name; TaskType = source.TaskType; NetType = source.NetType; NetSettings = null; OutputRange = null; if (source.NetSettings != null) { if (source.NetSettings.GetType() == typeof(FeedForwardNetworkSettings)) { NetSettings = ((FeedForwardNetworkSettings)(source.NetSettings)).DeepClone(); } else { NetSettings = ((ParallelPerceptronSettings)(source.NetSettings)).DeepClone(); } OutputRange = source.OutputRange.DeepClone(); } return; }
/// <summary> /// Prepares trained readout unit for specified output field and task. /// </summary> /// <param name="taskType">Type of the task</param> /// <param name="readoutUnitIdx">Index of the readout unit (informative only)</param> /// <param name="foldNum">Current fold number</param> /// <param name="numOfFolds">Total number of the folds</param> /// <param name="refBinDistr">Reference bin distribution (if task type is Classification)</param> /// <param name="trainingPredictorsCollection">Collection of the predictors for training</param> /// <param name="trainingIdealOutputsCollection">Collection of ideal outputs for training. Note that the double array always has only one member.</param> /// <param name="testingPredictorsCollection">Collection of the predictors for testing</param> /// <param name="testingIdealOutputsCollection">Collection of ideal outputs for testing. Note that the double array always has only one member.</param> /// <param name="rand">Random object to be used</param> /// <param name="readoutUnitSettings">Readout unit configuration parameters</param> /// <param name="controller">Regression controller</param> /// <param name="controllerUserObject">An user object to be passed to controller</param> /// <returns>Prepared readout unit</returns> public static ReadoutUnit CreateTrained(CommonEnums.TaskType taskType, int readoutUnitIdx, int foldNum, int numOfFolds, BinDistribution refBinDistr, List <double[]> trainingPredictorsCollection, List <double[]> trainingIdealOutputsCollection, List <double[]> testingPredictorsCollection, List <double[]> testingIdealOutputsCollection, Random rand, ReadoutLayerSettings.ReadoutUnitSettings readoutUnitSettings, RegressionCallbackDelegate controller = null, Object controllerUserObject = null ) { ReadoutUnit bestReadoutUnit = null; //Regression attempts bool stopRegression = false; for (int regrAttemptNumber = 1; regrAttemptNumber <= readoutUnitSettings.RegressionAttempts; regrAttemptNumber++) { //Create network and trainer CreateNetAndTreainer(readoutUnitSettings, trainingPredictorsCollection, trainingIdealOutputsCollection, rand, out INonRecurrentNetwork net, out INonRecurrentNetworkTrainer trainer ); //Reference binary distribution //Iterate training cycles for (int epoch = 1; epoch <= readoutUnitSettings.RegressionAttemptEpochs; epoch++) { trainer.Iteration(); List <double[]> testingComputedOutputsCollection = null; //Compute current error statistics after training iteration ReadoutUnit currReadoutUnit = new ReadoutUnit(); currReadoutUnit.Network = net; currReadoutUnit.TrainingErrorStat = net.ComputeBatchErrorStat(trainingPredictorsCollection, trainingIdealOutputsCollection, out List <double[]> trainingComputedOutputsCollection); if (taskType == CommonEnums.TaskType.Classification) { currReadoutUnit.TrainingBinErrorStat = new BinErrStat(refBinDistr, trainingComputedOutputsCollection, trainingIdealOutputsCollection); currReadoutUnit.CombinedBinaryError = currReadoutUnit.TrainingBinErrorStat.TotalErrStat.Sum; //currReadoutUnit.CombinedBinaryError = currReadoutUnit.TrainingBinErrorStat.ProportionalErr; } currReadoutUnit.CombinedPrecisionError = currReadoutUnit.TrainingErrorStat.ArithAvg; if (testingPredictorsCollection != null && testingPredictorsCollection.Count > 0) { currReadoutUnit.TestingErrorStat = net.ComputeBatchErrorStat(testingPredictorsCollection, testingIdealOutputsCollection, out testingComputedOutputsCollection); currReadoutUnit.CombinedPrecisionError = Math.Max(currReadoutUnit.CombinedPrecisionError, currReadoutUnit.TestingErrorStat.ArithAvg); if (taskType == CommonEnums.TaskType.Classification) { currReadoutUnit.TestingBinErrorStat = new BinErrStat(refBinDistr, testingComputedOutputsCollection, testingIdealOutputsCollection); currReadoutUnit.CombinedBinaryError = Math.Max(currReadoutUnit.CombinedBinaryError, currReadoutUnit.TestingBinErrorStat.TotalErrStat.Sum); //currReadoutUnit.CombinedBinaryError = Math.Max(currReadoutUnit.CombinedBinaryError, currReadoutUnit.TestingBinErrorStat.ProportionalErr); } } //Current results processing bool better = false, stopTrainingCycle = false; //Result first initialization if (bestReadoutUnit == null) { //Adopt current regression results bestReadoutUnit = currReadoutUnit.DeepClone(); } //Perform call back if it is defined if (controller != null) { //Evaluation of the improvement is driven externally RegressionControlInArgs cbIn = new RegressionControlInArgs { TaskType = taskType, ReadoutUnitIdx = readoutUnitIdx, OutputFieldName = readoutUnitSettings.Name, FoldNum = foldNum, NumOfFolds = numOfFolds, RegrAttemptNumber = regrAttemptNumber, RegrMaxAttempts = readoutUnitSettings.RegressionAttempts, Epoch = epoch, MaxEpochs = readoutUnitSettings.RegressionAttemptEpochs, TrainingPredictorsCollection = trainingPredictorsCollection, TrainingIdealOutputsCollection = trainingIdealOutputsCollection, TrainingComputedOutputsCollection = trainingComputedOutputsCollection, TestingPredictorsCollection = testingPredictorsCollection, TestingIdealOutputsCollection = testingIdealOutputsCollection, TestingComputedOutputsCollection = testingComputedOutputsCollection, CurrReadoutUnit = currReadoutUnit, BestReadoutUnit = bestReadoutUnit, UserObject = controllerUserObject }; //Call external controller RegressionControlOutArgs cbOut = controller(cbIn); //Pick up results better = cbOut.CurrentIsBetter; stopTrainingCycle = cbOut.StopCurrentAttempt; stopRegression = cbOut.StopRegression; } else { //Default implementation better = IsBetter(taskType, currReadoutUnit, bestReadoutUnit); } //Best? if (better) { //Adopt current regression results bestReadoutUnit = currReadoutUnit.DeepClone(); } //Training stop conditions if (stopTrainingCycle || stopRegression) { break; } }//epoch //Regression stop conditions if (stopRegression) { break; } }//regrAttemptNumber //Create statistics of the best network weights bestReadoutUnit.OutputWeightsStat = bestReadoutUnit.Network.ComputeWeightsStat(); return(bestReadoutUnit); }