public ComputationGraphNetwork([NotNull] ComputationGraph graph) : base(NetworkType.ComputationGraph)
 {
     Graph                 = graph;
     OutputLayer           = Graph.OutputNode.To <IComputationGraphNode, ProcessingNode>().Layer.To <INetworkLayer, OutputLayerBase>();
     Layers                = Graph.ProcessingNodes.Select(node => node.Layer).ToArray();
     WeightedLayersIndexes = Layers.Select((l, i) => (Layer: l as WeightedLayerBase, Index: i)).Where(t => t.Layer != null).Select(t => t.Index).ToArray();
 }
        private static unsafe void TestBackward(OutputLayerBase cpu, OutputLayerBase gpu, float[,] y)
        {
            SetBackpropagationProperty(true);
            int n = y.GetLength(0);

            fixed(float *p = y)
            {
                Tensor.Reshape(p, n, y.GetLength(1), out Tensor yTensor);
                Tensor
                    x  = CreateRandomTensor(n, cpu.InputInfo.Size),
                    dy = CreateRandomTensor(n, cpu.OutputInfo.Size);

                Tensor.Like(x, out Tensor dx1);
                Tensor.Like(x, out Tensor dx2);
                cpu.Forward(x, out Tensor z_cpu, out Tensor a_cpu);
                gpu.Forward(x, out Tensor z_gpu, out Tensor a_gpu);
                cpu.Backpropagate(x, a_cpu, yTensor, z_cpu, dx1, out Tensor dJdw_cpu, out Tensor dJdb_cpu);
                gpu.Backpropagate(x, a_cpu, yTensor, z_cpu, dx2, out Tensor dJdw_gpu, out Tensor dJdb_gpu);
                Assert.IsTrue(dx1.ContentEquals(dx2));
                Assert.IsTrue(dJdw_cpu.ContentEquals(dJdw_gpu));
                Assert.IsTrue(dJdb_cpu.ContentEquals(dJdb_gpu, 1e-4f, 1e-5f));
                Tensor.Free(x, dy, dx1, dx2, z_cpu, a_cpu, z_gpu, a_gpu, dJdw_cpu, dJdw_gpu, dJdb_cpu, dJdb_gpu);
            }

            SetBackpropagationProperty(false);
        }