public void Given__BiasesHigh_WeightsHigh__Returns111__ForAnyInput(params double[] inputs) { const double h = Neuron.High; var net = new NeuralNet3LayerSigmoid(new[, ] { { h }, { h }, { h } }, new[, ] { { h, h, h } }, new[] { h }, new[] { h, h, h }); // Console.WriteLine(net.OutputFor(inputs)); net.OutputFor(inputs).ToArray().ShouldBe(new ZeroToOne[] { 1, 1, 1 }); }
public void Given_Biases0_Weights0__ReturnsHalfHalfHalf__ForAnyInput(params double[] inputs) { var net = new NeuralNet3LayerSigmoid(3, 1, 3) .SetBiases(new[] { 0d }, new [] { 0d, 0d, 0d }) .SetInputToHiddenWeights(new double[3, 1] { { 0 }, { 0 }, { 0 } }) .SetHiddenToOutputWeights(new double[1, 3] { { 0, 0, 0 } }); // Console.WriteLine(net.OutputFor(inputs).ToArray()); // net.OutputFor(inputs).ShouldEqualByValue(new ZeroToOne[] { 0.5, 0.5, 0.5 }); }
public void Given__BiasesLow_WeightsLow__Returns000__ForAnyInput(params double[] inputs) { const double low = Neuron.Low; var net = new NeuralNet3LayerSigmoid(3, 1, 3) .SetBiases(new[] { low }, new[] { low, low, low }) .SetInputToHiddenWeights(new double[3, 1] { { low }, { low }, { low } }) .SetHiddenToOutputWeights(new double[1, 3] { { low, low, low } }); // Console.WriteLine(net.OutputFor(inputs)); net.OutputFor(inputs).ToArray().ShouldBe(new ZeroToOne[] { 0, 0, 0 }); }
public static DeltasFor2LayersOfNet DeltasFor(NeuralNet3LayerSigmoid net, IEnumerable <double> inputs, IEnumerable <ZeroToOne> targets) { var outputs = net.OutputFor(inputs).ToArray(); var outputDeltas = outputs .Zip(targets, (o, target) => (target - o) * o * (1 - o)) /* see e.g. wikipedia https://en.wikipedia.org/wiki/Backpropagation#Derivation */ .ToArray(); var outputWeightDeltas = new MatrixD(net.HiddenToOutput.RowCount, net.HiddenToOutput.ColumnCount); var hiddenDeltaParts = new MatrixD(net.HiddenToOutput.RowCount, net.HiddenToOutput.ColumnCount); for (int i = 0; i < outputWeightDeltas.RowCount; i++) { for (int j = 0; j < outputWeightDeltas.ColumnCount; j++) { outputWeightDeltas[i, j] = net.HiddenLayer[i].FiringRate * outputDeltas[j]; hiddenDeltaParts[i, j] = outputDeltas[j] * (net.HiddenToOutput[i, j] + outputWeightDeltas[i, j]) * outputs[j] * (1 - outputs[j]); } } var hiddenDeltas = hiddenDeltaParts.ByRows().Select(row => row.Sum()).ToArray(); var hiddenWeightDeltas = new MatrixD(net.InputToHidden.RowCount, net.InputToHidden.ColumnCount); for (int i = 0; i < hiddenWeightDeltas.RowCount; i++) { for (int j = 0; j < hiddenWeightDeltas.ColumnCount; j++) { hiddenWeightDeltas[i, j] = net.InputLayer[i].FiringRate * hiddenDeltas[j]; } } return(new DeltasFor2LayersOfNet { OutputBiases = net.OutputLayer.Zip(outputDeltas, (neuron, delta) => neuron.Bias * delta).ToArray(), OutputWeights = outputWeightDeltas, HiddenBiases = net.HiddenLayer.Zip(hiddenDeltas, (neuron, delta) => neuron.Bias * delta).ToArray(), HiddenWeights = hiddenWeightDeltas }); }