public void ComputeTwiceGradientShouldYieldTheSameResult() { const int inputWidth = 10; const int inputHeight = 10; const int inputDepth = 2; const int filterWidth = 3; const int filterHeight = 3; const int filterCount = 2; // Create layer var layer = new ConvLayer <double>(filterWidth, filterHeight, filterCount) { Stride = 2, BiasPref = 0.1 }; layer.Init(inputWidth, inputHeight, inputDepth); // Forward pass var input = BuilderInstance <double> .Volume.Random(new Shape(inputWidth, inputHeight, inputDepth)); var output = layer.DoForward(input, true); // Set output gradients to 1 var outputGradient = BuilderInstance <double> .Volume.From(new double[output.Shape.TotalLength].Populate(1.0), output.Shape); // Backward pass to retrieve gradients layer.Backward(outputGradient); var step1 = ((Volume <double>)layer.InputActivationGradients.Clone()).ToArray(); layer.Backward(outputGradient); var step2 = ((Volume <double>)layer.InputActivationGradients.Clone()).ToArray(); Assert.IsTrue(step1.SequenceEqual(step2)); }
public void ForwardBackwardTest() { var input = new TensorOld(new double[] { 4, 6, 1, 4, 8, 4, 5, 1, 5, 3, 5, 7, 1, 7, 2, 8, }, 1, 1, 4, 4); var conv = new ConvLayer(4, 2, 1, 1); conv.SetFilters(new TensorOld(new double[] { 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, }, 4, 1, 2, 2)); var expected = new TensorOld(new double[] { 0, 0, 0, 0, 0, 4, 10, 7, 5, 4, 8, 12, 9, 6, 1, 5, 8, 8, 12, 7, 1, 8, 9, 10, 8, 4, 10, 7, 5, 4, 8, 12, 9, 6, 1, 5, 8, 8, 12, 7, 1, 8, 9, 10, 8, 0, 0, 0, 0, 0, 0, 4, 6, 1, 4, 0, 12, 10, 6, 5, 0, 13, 7, 10, 8, 0, 6, 10, 7, 15, 0, 1, 7, 2, 8, 4, 6, 1, 4, 0, 12, 10, 6, 5, 0, 13, 7, 10, 8, 0, 6, 10, 7, 15, 0, 1, 7, 2, 8, 0, }, 1, 4, 5, 5); conv.PrepareTrain(input); var acutal = conv.Forward(input); Assert.Equal(acutal, expected); var error = expected / 10; var back = conv.Backward(error); }