/// <summary> /// Invokes BeginSampleEvent /// </summary> /// <param name="currentIteration"> /// Current training iteration /// </param> /// <param name="currentSample"> /// Current sample which got trained successfully /// </param> protected virtual void OnEndSample(int currentIteration, TrainingSample currentSample) { if (EndSampleEvent != null) { EndSampleEvent(this, new TrainingSampleEventArgs(currentIteration, currentSample)); } }
/// <summary> /// Trains the neural network for the given training set (Batch Training) /// </summary> /// <param name="trainingSet"> /// The training set to use /// </param> /// <param name="trainingEpochs"> /// Number of training epochs. (All samples are trained in some random order, in every /// training epoch) /// </param> /// <exception cref="ArgumentNullException"> /// if <c>trainingSet</c> is <c>null</c> /// </exception> /// <exception cref="ArgumentException"> /// if <c>trainingEpochs</c> is zero or negative /// </exception> public virtual void Learn(TrainingSet trainingSet, int trainingEpochs) { // Validate Helper.ValidateNotNull(trainingSet, "trainingSet"); Helper.ValidatePositive(trainingEpochs, "trainingEpochs"); if ((trainingSet.InputVectorLength != inputLayer.NeuronCount) || (trainingMethod == TrainingMethod.Supervised && trainingSet.OutputVectorLength != outputLayer.NeuronCount) || (trainingMethod == TrainingMethod.Unsupervised && trainingSet.OutputVectorLength != 0)) { throw new ArgumentException("Invalid training set"); } // Reset isStopping isStopping = false; // Re-Initialize the network Initialize(); for (int currentIteration = 0; currentIteration < trainingEpochs; currentIteration++) { int[] randomOrder = Helper.GetRandomOrder(trainingSet.TrainingSampleCount); // Beginning a new training epoch OnBeginEpoch(currentIteration, trainingSet); // Check for Jitter Epoch if (jitterEpoch > 0 && currentIteration % jitterEpoch == 0) { for (int i = 0; i < connectors.Count; i++) { connectors[i].Jitter(jitterNoiseLimit); } } for (int index = 0; index < trainingSet.TrainingSampleCount; index++) { TrainingSample randomSample = trainingSet[randomOrder[index]]; // Learn a random training sample OnBeginSample(currentIteration, randomSample); LearnSample(trainingSet[randomOrder[index]], currentIteration, trainingEpochs); OnEndSample(currentIteration, randomSample); // Check if we need to stop if (isStopping) { isStopping = false; return; } } // Training Epoch successfully complete OnEndEpoch(currentIteration, trainingSet); // Check if we need to stop if (isStopping) { isStopping = false; return; } } }
/// <summary> /// Trains the network for the given training sample (Online training mode). Note that this /// method trains the sample only once, irrespective of what current epoch is. The arguments /// are just used to find out training progress and adjust parameters depending on it. /// </summary> /// <param name="trainingSample"> /// Training sample to use /// </param> /// <param name="currentIteration"> /// Current training iteration /// </param> /// <param name="trainingEpochs"> /// Number of training epochs /// </param> /// <exception cref="ArgumentNullException"> /// If <c>trainingSample</c> is <c>null</c> /// </exception> /// <exception cref="ArgumentException"> /// If <c>trainingEpochs</c> is not positive /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// If <c>currentIteration</c> is negative or, if it is not less than <c>trainingEpochs</c> /// </exception> public virtual void Learn(TrainingSample trainingSample, int currentIteration, int trainingEpochs) { Helper.ValidateNotNull(trainingSample, "trainingSample"); Helper.ValidatePositive(trainingEpochs, "trainingEpochs"); Helper.ValidateWithinRange(currentIteration, 0, trainingEpochs - 1, "currentIteration"); OnBeginSample(currentIteration, trainingSample); LearnSample(trainingSample, currentIteration, trainingEpochs); OnEndSample(currentIteration, trainingSample); }
/// <summary> /// Adds a new supervised training sample to the training set. If already exists, it will /// be replaced. /// </summary> /// <param name="sample"> /// The sample to add /// </param> /// <exception cref="ArgumentNullException"> /// If <c>sample</c> is <c>null</c> /// </exception> /// <exception cref="ArgumentException"> /// If sizes of input vector or output vector are different from their expected sizes /// </exception> public void Add(TrainingSample sample) { // Validation Helper.ValidateNotNull(sample, "sample"); if (sample.InputVector.Length != inputVectorLength) { throw new ArgumentException ("Input vector must be of size " + inputVectorLength, "sample"); } if (sample.OutputVector.Length != outputVectorLength) { throw new ArgumentException ("Output vector must be of size " + outputVectorLength, "sample"); } // Note that the reference is being added. (Sample is immutable) trainingSamples.Add(sample); }
/// <summary> /// Determine whether the given object is equal to this instance /// </summary> /// <param name="obj"> /// The object to compare with this instance /// </param> /// <returns> /// <c>true</c> if the given object is equal to this instance, <c>false</c> otherwise /// </returns> public override bool Equals(object obj) { if (obj is TrainingSample) { TrainingSample sample = (TrainingSample)obj; int size; if ((size = sample.inputVector.Length) == inputVector.Length) { for (int i = 0; i < size; i++) { if (inputVector[i] != sample.inputVector[i]) { return(false); } } return(true); } } return(false); }
/// <summary> /// Creates a new instance of this class /// </summary> /// <param name="trainingIteration"> /// Current training iteration /// </param> /// <param name="trainingSample"> /// The training sample associated with the event /// </param> public TrainingSampleEventArgs(int trainingIteration, TrainingSample trainingSample) { this.trainingIteration = trainingIteration; this.trainingSample = trainingSample; }
/// <summary> /// A protected helper function used to train single learning sample /// </summary> /// <param name="trainingSample"> /// Training sample to use /// </param> /// <param name="currentIteration"> /// Current training epoch (Assumed to be positive and less than <c>trainingEpochs</c>) /// </param> /// <param name="trainingEpochs"> /// Number of training epochs (Assumed to be positive) /// </param> protected abstract void LearnSample(TrainingSample trainingSample, int currentIteration, int trainingEpochs);
/// <summary> /// Determines whether the training sample is present in the set /// </summary> /// <param name="sample"> /// The sample to locate /// </param> /// <returns> /// <c>true</c> if present, <c>false</c> otherwise /// </returns> public bool Contains(TrainingSample sample) { return(trainingSamples.Contains(sample)); }
/// <summary> /// Removes the given training sample /// </summary> /// <param name="sample"> /// The sample to remove /// </param> /// <returns> /// <c>true</c> if successful, <c>false</c> otherwise /// </returns> public bool Remove(TrainingSample sample) { return(trainingSamples.Remove(sample)); }