/// <summary> /// Run a vector of inputs through this neural network and get the output vector /// </summary> /// <param name="inputs">The vector of inputs to push through</param> public DoubleVector FeedForward(DoubleVector inputs) { double sum; for (int h = 0; h < hiddenCount; h++) { sum = 0.0; // Find the sum of all inputs multiplied by their respective weights for (int i = 0; i < inputsCount; i++) { sum += inputs[i] * weights_IH[i, h]; } // Put the sum through an activation function to find the activation of this neuron neurons_H[h] = ActivationFunctions.Sigmoid(sum); } // Calculate the activations of the output neurons for (int o = 0; o < outputCount; o++) { sum = 0.0; // Find the sum of all inputs multiplied by their respective weights for (int h = 0; h < hiddenCount; h++) { sum += neurons_H[h] * weights_HO[h, o]; } // Put the sum through an activation function to find the activation of this neuron neurons_O[o] = ActivationFunctions.Sigmoid(sum); } return(neurons_O.Clone()); }
/// <summary> /// Train the network on a single input vector. Returns the mean square error of the set. /// </summary> /// <param name="inputs">The input vector to train on</param> /// <param name="targets">The target output vector</param> /// <param name="iterations">The number of iterations to train on these inputs</param> public double Train(DoubleVector inputs, DoubleVector targets, int iterations) { // Make sure the vectors are the correct sizes if (inputs.Size != inputsCount) { throw new Exception("An invalid number of inputs were fed into this neural network."); } if (targets.Size != outputCount) { throw new Exception("An invalid number of outputs are being expected from this neural network."); } for (int loop = 0; loop < iterations; loop++) { // The feed-formard pass DoubleVector actuals = FeedForward(inputs); // Calculate the error for the output layer for (int o = 0; o < outputCount; o++) { error_O[o] = (targets[o] - actuals[o]) * ActivationFunctions.SigmoidDerivative(actuals[o]); } // Calculate the error for the hidden layer for (int h = 0; h < hiddenCount; h++) { error_H[h] = 0.0; for (int o = 0; o < outputCount; o++) { error_H[h] += error_O[o] * weights_HO[h, o]; } error_H[h] *= ActivationFunctions.SigmoidDerivative(neurons_H[h]); } // Update the weights for the output layer for (int o = 0; o < outputCount; o++) { for (int h = 0; h < hiddenCount; h++) { weights_HO[h, o] += learningRate * error_O[o] * neurons_H[h]; } } // Updat the weights for the hidden layer for (int h = 0; h < hiddenCount; h++) { for (int i = 0; i < inputsCount; i++) { weights_IH[i, h] += learningRate * error_H[h] * inputs[i]; } } } // Return the mean square error return(GetMeanSquareError(targets, FeedForward(inputs))); }