// train the neural network public void Train(double[] inputsList, double[] targetsList) { // Convert inputs and targets list (one-dimensional) to two-dimensional, one-column matrices. double[,] inputs = new double[inputsList.Length, 1]; inputs.SetColumn(0, inputsList); // calculate signals into hidden layer double[,] hiddenInputs = Wih.Dot(inputs); // calculate the signals emerging from hidden layer double[,] hiddenOutputs = hiddenInputs.Apply(x => ActivationFunction(x)); // calculate signals into final output layer double[,] finalInputs = Who.Dot(hiddenOutputs); // calculate the signals emerging from final output layer double[,] finalOutputs = finalInputs.Apply(x => ActivationFunction(x)); // output layer error is the (target - actual) double[] outputError = targetsList.Subtract(finalOutputs.GetColumn(0)); // hidden layer error is the output_errors, split by weights, recombined at hidden nodes double[] hiddenError = Who.TransposeAndDot(outputError); // update the weights for the links between the hidden and output layers UpdateWeigths(hiddenOutputs, finalOutputs, ref Who, outputError); // update the weights for the links between the input and hidden layers UpdateWeigths(inputs, hiddenOutputs, ref Wih, hiddenError); }
// ---------------------------------------------------------------------------------------- // Helper function for updating weight values during backpropagation. private void UpdateWeigths(double[,] layer1, double[,] layer2, ref double[,] weigths, double[] errorList) { // Convert errors list (one-dimensional) to two-dimensional, one-column matrix. double[,] errors = Matrix.Create <double>(errorList.Length, 1); errors.SetColumn(0, errorList); // Calculate delta matrix (differences for updating weight values). double[,] deltas = Elementwise.Multiply(errors, layer2.Apply(x => x * (1 - x))) .Dot(layer1.Transpose()) .Apply(x => x * .1); // Apply delta matrix. weigths = weigths.Add(deltas); }
// query the neural network public double[] Query(double[] inputsList) { // Convert inputs list (one-dimensional) to two-dimensional, one-column matrix. double[,] inputs = Matrix.Create <double>(inputsList.Length, 1); inputs.SetColumn(0, inputsList); // calculate signals into hidden layer double[,] hiddenInputs = Wih.Dot(inputs); // calculate the signals emerging from hidden layer double[,] hiddenOutputs = hiddenInputs.Apply(x => ActivationFunction(x)); // calculate signals into final output layer double[,] finalInputs = Who.Dot(hiddenOutputs); // calculate the signals emerging from final output layer double[,] finalOutputs = finalInputs.Apply(x => ActivationFunction(x)); // Convert output node matrix back to a 1-dimensional list of values. return(finalOutputs.GetColumn(0)); }