/// <summary> /// Predicts the output of the provided data after training has occured. /// </summary> /// <param name="outputType">The type of output data.</param> /// <returns></returns> public void Predict(EPerceptronOutputType outputType) { if (!HasTrained) { WorqnetsUtils.PrintMessage("Please Train The Network Before Attempting To Predict", WorqnetsUtils.MessageType.Error); return; } _bias = TrainingData.CalculatedBias; switch (outputType) { case EPerceptronOutputType.Integer: PredictedValue = CalculateWeightedSum(ProblemData.Values, TrainingData.CalculatedWeights).ToString(); break; case EPerceptronOutputType.String: PredictedValue = CalculateWeightedSum(ProblemData.Values, TrainingData.CalculatedWeights) > 0 ? TrainingData.OutputClass2 : TrainingData.OutputClass1; break; default: throw new ArgumentOutOfRangeException(nameof(outputType), outputType, null); } //ProblemData.FloatOutput = PredictedValue > 0 ? 1 : 0; }
/// <summary> /// Co-routine to perform the training of the perceptron. This ensures that training is done on a separate thread so as to avoid freezing the program. /// </summary> /// <returns>Returns Wait For End Of Frame. Continues at the end of the current frame.</returns> private IEnumerator DoTrain() { InitializeWeights(); EpochsPerformed = 0; _repeatedAfterConverging = 0; LastTrainingCouldNotConverge = false; //Get out of training if train data is null. if (!TrainingData) { yield break; } CheckForTrainData(); //Train at least once. do { //Set total error euals zero. _totalError = 0; //Get out of training if max number of epochs has been reached (training could not converge). if (EpochsPerformed == MaxEpochs - 1) { WorqnetsUtils.PrintMessage("Could Not Converge", WorqnetsUtils.MessageType.Error); LastTrainingCouldNotConverge = true; HasTrained = false; yield break; } for (var i = 0; i < TrainingData.TrainingDataSize; i++) { UpdateWeights(i); if (EnableTrainDebugging) { //Debug.Log("========================================"); Debug.Log("W1: " + _weights[0] + " W2: " + _weights[1] + " Bias: " + _bias); } } if (EnableTrainDebugging) { Debug.Log("Total Error: " + _totalError); //Debug.Log("========================================"); } if (_totalError <= Epsilon) { _repeatedAfterConverging++; } EpochsPerformed += 1; } while (EpochsPerformed < MaxEpochs && _repeatedAfterConverging <= RepetitionsAfterConverging); TrainingData.CalculatedWeights = _weights; TrainingData.CalculatedBias = _bias; yield return(new WaitForEndOfFrame()); }
private float CalculateWeightedSum(IList <float> inputs, IList <float> weights) { if (inputs.Count != weights.Count) { WorqnetsUtils.PrintMessage("Can not train. Inputs and weights do not match", WorqnetsUtils.MessageType.Warning); return(float.MinValue); } var weightedSum = 0.0f; for (var i = 0; i < inputs.Count; i += 1) { weightedSum += inputs[i] * weights[i]; } weightedSum += _bias; return(weightedSum); }