public void JacobianByChainRuleTest_MultipleOutput()
{
// Network with no hidden layers: 3-4
int numberOfInputs = 3;
int numberOfClasses = 4;
double[][] input =
{
new double[] { -1, -1, -1 }, // 0
new double[] { -1, 1, -1 }, // 1
new double[] { 1, -1, -1 }, // 1
new double[] { 1, 1, -1 }, // 0
new double[] { -1, -1, 1 }, // 2
new double[] { -1, 1, 1 }, // 3
new double[] { 1, -1, 1 }, // 3
new double[] { 1, 1, 1 } // 2
};
int[] labels =
{
0,
1,
1,
0,
2,
3,
3,
2,
};
double[][] output = Accord.Statistics.Tools
.Expand(labels, numberOfClasses, -1, 1);
// Neuron.RandGenerator = new ThreadSafeRandom(0);
Accord.Math.Random.Generator.Seed = 0;
ActivationNetwork network = new ActivationNetwork(
new BipolarSigmoidFunction(2), numberOfInputs, numberOfClasses);
var teacher1 = new LevenbergMarquardtLearning(network,
false, JacobianMethod.ByFiniteDifferences);
var teacher2 = new LevenbergMarquardtLearning(network,
false, JacobianMethod.ByBackpropagation);
// Set lambda to lambda max so no iterations are performed
teacher1.LearningRate = 1e30f;
teacher2.LearningRate = 1e30f;
teacher1.RunEpoch(input, output);
teacher2.RunEpoch(input, output);
var jacobian1 = teacher1.Jacobian;
var jacobian2 = teacher2.Jacobian;
for (int i = 0; i < jacobian1.Length; i++)
{
for (int j = 0; j < jacobian1[i].Length; j++)
{
double j1 = jacobian1[i][j];
double j2 = jacobian2[i][j];
Assert.AreEqual(j1, j2, 1e-3);
Assert.IsFalse(Double.IsNaN(j1));
Assert.IsFalse(Double.IsNaN(j2));
}
}
}