示例#1
0
        private void TestGradientsSuccess(bool grad_inputs_provided)
        {
            var inputs                = new TF_Output[2];
            var outputs               = new TF_Output[1];
            var grad_outputs          = new TF_Output[2];
            var expected_grad_outputs = new TF_Output[2];

            BuildSuccessGraph(inputs, outputs);
            BuildExpectedGraph(grad_inputs_provided, expected_grad_outputs);

            AddGradients(grad_inputs_provided, "gradients", inputs, 2, outputs, 1,
                         grad_outputs);
            EXPECT_EQ(TF_OK, TF_GetCode(s_));

            // Compare that the graphs match.
            GraphDef expected_gdef;
            GraphDef gdef;

            EXPECT_TRUE(GetGraphDef(expected_graph_, out expected_gdef));
            EXPECT_TRUE(GetGraphDef(graph_, out gdef));
            // Assert.IsTrue(expected_gdef.ToString().Equals(gdef.ToString()));

            // Compare that the output of the gradients of both graphs match.
            RunGraphsAndCompareOutputs(grad_outputs, expected_grad_outputs);
        }
示例#2
0
        private void BuildSuccessGraph(TF_Output[] inputs, TF_Output[] outputs)
        {
            // Construct the following graph:
            //            |
            //           z|
            //            |
            //          MatMul
            //         /       \
            //        ^         ^
            //        |         |
            //       x|        y|
            //        |         |
            //        |         |
            //      Const_0    Const_1
            //
            var const0_val = new float[] { 1.0f, 2.0f, 3.0f, 4.0f };
            var const1_val = new float[] { 1.0f, 0.0f, 0.0f, 1.0f };
            var const0     = FloatConst2x2(graph_, s_, const0_val, "Const_0");
            var const1     = FloatConst2x2(graph_, s_, const1_val, "Const_1");
            var matmul     = MatMul(graph_, s_, const0, const1, "MatMul");

            inputs[0]  = new TF_Output(const0, 0);
            inputs[1]  = new TF_Output(const1, 0);
            outputs[0] = new TF_Output(matmul, 0);
            EXPECT_EQ(TF_OK, TF_GetCode(s_));
        }
示例#3
0
        private void TestGradientsSuccess(bool grad_inputs_provided)
        {
            var inputs                = new TF_Output[2];
            var outputs               = new TF_Output[1];
            var grad_outputs          = new TF_Output[2];
            var expected_grad_outputs = new TF_Output[2];

            BuildSuccessGraph(inputs, outputs);
            BuildExpectedGraph(grad_inputs_provided, expected_grad_outputs);

            AddGradients(grad_inputs_provided, string.Empty, inputs, 2, outputs, 1,
                         grad_outputs);
            // EXPECT_EQ(TF_OK, TF_GetCode(s_));

            // Compare that the graphs match.
            GraphDef expected_gdef;
            GraphDef gdef;

            EXPECT_TRUE(GetGraphDef(expected_graph_, out expected_gdef));
            EXPECT_TRUE(GetGraphDef(graph_, out gdef));
            //TF_EXPECT_GRAPH_EQ(expected_gdef, gdef);

            // Compare that the output of the gradients of both graphs match.
            RunGraphsAndCompareOutputs(grad_outputs, expected_grad_outputs);
        }
        private void TestGradientsSuccess(bool grad_inputs_provided)
        {
            var inputs                = new TF_Output[2];
            var outputs               = new TF_Output[1];
            var grad_outputs          = new TF_Output[2];
            var expected_grad_outputs = new TF_Output[2];

            BuildSuccessGraph(inputs, outputs);
        }
示例#5
0
        private void BuildExpectedGraph(bool grad_inputs_provided, TF_Output[] expected_grad_outputs)
        {
            // The expected graph looks like this if grad_inputs_provided.
            // If grad_inputs_provided is false, Const_0 will be a OnesLike op.
            //      ^             ^
            //    dy|           dx|        // MatMul Gradient Graph
            //      |             |
            //   MatMul_2      MatMul_1
            //   ^   ^          ^    ^
            //   |   |----------|    |
            //   |        ^          |
            //   |      dz|          |
            //   |        |          |
            //   |     Const_3       |
            //   |                   |
            //   |        ^          |
            //   |       z|          |     // MatMul Forward Graph
            //   |        |          |
            //   |      MatMul       |
            //   |     /       \     |
            //   |    ^         ^    |
            //   |    |         |    |
            //   |---x|        y|----|
            //        |         |
            //        |         |
            //      Const_0   Const_1
            //
            float[] const0_val = { 1.0f, 2.0f, 3.0f, 4.0f };
            float[] const1_val = { 1.0f, 0.0f, 0.0f, 1.0f };
            var     const0     = FloatConst2x2(expected_graph_, s_, const0_val, "Const_0");
            var     const1     = FloatConst2x2(expected_graph_, s_, const1_val, "Const_1");
            var     matmul     = MatMul(expected_graph_, s_, const0, const1, "MatMul");

            Operation const3;

            if (grad_inputs_provided)
            {
                float[] const3_val = { 1.0f, 1.0f, 1.0f, 1.0f };
                const3 = FloatConst2x2(expected_graph_, s_, const3_val, "GradInputs");
            }
            else
            {
                const3 = OnesLike(expected_graph_, s_, matmul, "gradients/OnesLike");
            }

            var matmul1 = MatMul(expected_graph_, s_, const3, const1,
                                 "gradients/MatMul", false, true);
            var matmul2 = MatMul(expected_graph_, s_, const0, const3,
                                 "gradients/MatMul_1", true, false);

            expected_grad_outputs[0] = new TF_Output(matmul1, 0);
            expected_grad_outputs[1] = new TF_Output(matmul2, 0);
        }
示例#6
0
        public static Operation Neg(Operation n, Graph graph, Status s, string name = "neg")
        {
            OperationDescription desc = c_api.TF_NewOperation(graph, "Neg", name);
            var neg_input             = new TF_Output(n, 0);

            c_api.TF_AddInput(desc, neg_input);
            var op = c_api.TF_FinishOperation(desc, s);

            s.Check();

            return(op);
        }
示例#7
0
        /*void TestGradientsError(bool grad_inputs_provided)
         * {
         *  var inputs = new TF_Output[1];
         *  var outputs = new TF_Output[1];
         *  var grad_outputs = new TF_Output[1];
         *
         *  BuildErrorGraph(inputs, outputs);
         *
         *  AddGradients(grad_inputs_provided, nullptr, inputs, 1, outputs, 1,
         *               grad_outputs);
         *
         *  string expected_msg =
         *      "No gradient defined for op: TestOpWithNoGradient. Please see "
         * "https://www.tensorflow.org/code/"
         * "tensorflow/cc/gradients/README.md"
         * " for instructions on how to add C++ gradients.";
         *  EXPECT_EQ(expected_msg, TF_Message(s_));
         * }*/

        private void AddGradients(bool grad_inputs_provided, string prefix, TF_Output[] inputs, int ninputs,
                                  TF_Output[] outputs, int noutputs, TF_Output[] grad_outputs)
        {
            if (grad_inputs_provided)
            {
                var     grad_inputs     = new TF_Output[1];
                float[] grad_inputs_val = { 1.0f, 1.0f, 1.0f, 1.0f };
                var     grad_inputs_op  = FloatConst2x2(graph_, s_, grad_inputs_val, "GradInputs");
                grad_inputs[0] = new TF_Output(grad_inputs_op, 0);
                c_api.TF_AddGradientsWithPrefix(graph_, prefix, outputs, noutputs, inputs,
                                                ninputs, grad_inputs, s_, grad_outputs);
            }
            else
            {
                c_api.TF_AddGradientsWithPrefix(graph_, prefix, outputs, noutputs, inputs,
                                                ninputs, null, s_, grad_outputs);
            }
        }
示例#8
0
        public static Operation Add(Operation l, Operation r, Graph graph, Status s, string name = "add")
        {
            var desc = c_api.TF_NewOperation(graph, "AddN", name);

            var inputs = new TF_Output[]
            {
                new TF_Output(l, 0),
                new TF_Output(r, 0),
            };

            c_api.TF_AddInputList(desc, inputs, inputs.Length);

            var op = c_api.TF_FinishOperation(desc, s);

            s.Check();

            return(op);
        }
示例#9
0
        /*void TestGradientsError(bool grad_inputs_provided)
         * {
         *  var inputs = new TF_Output[1];
         *  var outputs = new TF_Output[1];
         *  var grad_outputs = new TF_Output[1];
         *
         *  BuildErrorGraph(inputs, outputs);
         *
         *  AddGradients(grad_inputs_provided, nullptr, inputs, 1, outputs, 1,
         *               grad_outputs);
         *
         *  string expected_msg =
         *      "No gradient defined for op: TestOpWithNoGradient. Please see "
         * "https://www.tensorflow.org/code/"
         * "tensorflow/cc/gradients/README.md"
         * " for instructions on how to add C++ gradients.";
         *  EXPECT_EQ(expected_msg, TF_Message(s_));
         * }*/

        private void AddGradients(bool grad_inputs_provided, string prefix, TF_Output[] inputs, int ninputs,
                                  TF_Output[] outputs, int noutputs, TF_Output[] grad_outputs)
        {
            if (grad_inputs_provided)
            {
                var     grad_inputs     = new TF_Output[1];
                float[] grad_inputs_val = { 1.0f, 1.0f, 1.0f, 1.0f };
                var     grad_inputs_op  = FloatConst2x2(graph_, s_, grad_inputs_val, "GradInputs");
                grad_inputs[0] = new TF_Output(grad_inputs_op, 0);

                IntPtr[] handles = new IntPtr[2] {
                    IntPtr.Zero, IntPtr.Zero
                };
                c_api.TF_AddGradientsWithPrefix(graph_, prefix, outputs, noutputs, inputs,
                                                ninputs, grad_inputs, s_, handles);

                var op = new Operation(handles[0]);
            }
            else
            {
                //c_api.TF_AddGradientsWithPrefix(graph_, prefix, outputs, noutputs, inputs,
                //ninputs, null, s_, grad_outputs);
            }
        }
示例#10
0
        public void Session()
        {
            lock (Locks.ProcessWide)
            {
                var s     = new Status();
                var graph = new Graph().as_default();

                // Make a placeholder operation.
                var feed = c_test_util.Placeholder(graph, s);

                // Make a constant operation with the scalar "2".
                var two = c_test_util.ScalarConst(2, graph, s);

                // Add operation.
                var add = c_test_util.Add(feed, two, graph, s);

                var csession = new CSession(graph, s);
                ASSERT_EQ(TF_Code.TF_OK, s.Code);

                // Run the graph.
                var inputs = new Dictionary <Operation, Tensor>();
                inputs.Add(feed, new Tensor(3));
                csession.SetInputs(inputs);

                var outputs = new TF_Output[] { new TF_Output(add, 0) };
                csession.SetOutputs(outputs);

                csession.Run(s);
                Tensor outTensor = csession.output_tensor(0);
                EXPECT_EQ(TF_DataType.TF_INT32, outTensor.dtype);
                EXPECT_EQ(0, outTensor.NDims);
                ASSERT_EQ((ulong)sizeof(uint), outTensor.bytesize);
                var output_contents = outTensor.ToArray <int>();
                EXPECT_EQ(3 + 2, output_contents[0]);

                // Add another operation to the graph.
                var neg = c_test_util.Neg(add, graph, s);
                ASSERT_EQ(TF_Code.TF_OK, s.Code);

                // Run up to the new operation.
                inputs = new Dictionary <Operation, Tensor>();
                inputs.Add(feed, new Tensor(7));
                csession.SetInputs(inputs);
                outputs = new TF_Output[] { new TF_Output(neg, 0) };
                csession.SetOutputs(outputs);
                csession.Run(s);
                ASSERT_EQ(TF_Code.TF_OK, s.Code);

                outTensor = csession.output_tensor(0);
                ASSERT_TRUE(outTensor != IntPtr.Zero);
                EXPECT_EQ(TF_DataType.TF_INT32, outTensor.dtype);
                EXPECT_EQ(0, outTensor.NDims); // scalar
                ASSERT_EQ((ulong)sizeof(uint), outTensor.bytesize);
                output_contents = outTensor.ToArray <int>();
                EXPECT_EQ(-(7 + 2), output_contents[0]);

                // Clean up
                csession.CloseAndDelete(s);
                ASSERT_EQ(TF_Code.TF_OK, s.Code);
            }
        }
示例#11
0
        public void SetShape()
        {
            var s     = new Status();
            var graph = new Graph().as_default();

            var feed       = c_test_util.Placeholder(graph, s);
            var feed_out_0 = new TF_Output(feed, 0);

            // Fetch the shape, it should be completely unknown.
            int num_dims = c_api.TF_GraphGetTensorNumDims(graph, feed_out_0, s.Handle);

            Assert.IsTrue(s.Code == TF_Code.TF_OK);
            EXPECT_EQ(-1, num_dims);

            // Set the shape to be unknown, expect no change.
            c_api.TF_GraphSetTensorShape(graph, feed_out_0, null, -1, s.Handle);
            Assert.IsTrue(s.Code == TF_Code.TF_OK);
            num_dims = c_api.TF_GraphGetTensorNumDims(graph, feed_out_0, s.Handle);
            EXPECT_EQ(-1, num_dims);

            // Set the shape to be 2 x Unknown
            long[] dims = { 2, -1 };
            c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, dims.Length, s.Handle);
            Assert.IsTrue(s.Code == TF_Code.TF_OK);
            num_dims = c_api.TF_GraphGetTensorNumDims(graph, feed_out_0, s.Handle);
            EXPECT_EQ(2, num_dims);

            // Get the dimension vector appropriately.
            var returned_dims = new long[dims.Length];

            c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s.Handle);
            Assert.IsTrue(s.Code == TF_Code.TF_OK);
            Assert.IsTrue(Enumerable.SequenceEqual(dims, returned_dims));

            // Set to a new valid shape: [2, 3]
            dims[1] = 3;
            c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, dims.Length, s.Handle);
            Assert.IsTrue(s.Code == TF_Code.TF_OK);

            // Fetch and see that the new value is returned.
            c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s.Handle);
            Assert.IsTrue(s.Code == TF_Code.TF_OK);
            Assert.IsTrue(Enumerable.SequenceEqual(dims, returned_dims));

            // Try to set 'unknown' with unknown rank on the shape and see that
            // it doesn't change.
            c_api.TF_GraphSetTensorShape(graph, feed_out_0, null, -1, s.Handle);
            Assert.IsTrue(s.Code == TF_Code.TF_OK);
            c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s.Handle);
            Assert.IsTrue(s.Code == TF_Code.TF_OK);
            EXPECT_EQ(2, num_dims);
            EXPECT_EQ(2, (int)returned_dims[0]);
            EXPECT_EQ(3, (int)returned_dims[1]);

            // Try to set 'unknown' with same rank on the shape and see that
            // it doesn't change.
            dims[0] = -1;
            dims[1] = -1;
            c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, 2, s.Handle);
            Assert.IsTrue(s.Code == TF_Code.TF_OK);
            c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s.Handle);
            Assert.IsTrue(s.Code == TF_Code.TF_OK);
            EXPECT_EQ(2, num_dims);
            EXPECT_EQ(2, (int)returned_dims[0]);
            EXPECT_EQ(3, (int)returned_dims[1]);

            // Try to fetch a shape with the wrong num_dims
            c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, 5, s.Handle);
            Assert.IsTrue(s.Code == TF_Code.TF_INVALID_ARGUMENT);

            // Try to set an invalid shape (cannot change 2x3 to a 2x5).
            dims[1] = 5;
            c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, 2, s.Handle);
            Assert.IsTrue(s.Code == TF_Code.TF_INVALID_ARGUMENT);

            // Test for a scalar.
            var three = c_test_util.ScalarConst(3, graph, s);

            Assert.IsTrue(s.Code == TF_Code.TF_OK);
            var three_out_0 = new TF_Output(three, 0);

            num_dims = c_api.TF_GraphGetTensorNumDims(graph, three_out_0, s.Handle);
            Assert.IsTrue(s.Code == TF_Code.TF_OK);
            EXPECT_EQ(0, num_dims);
            c_api.TF_GraphGetTensorShape(graph, feed_out_0, null, num_dims, s.Handle);
            //Assert.IsTrue(s.Code == TF_Code.TF_OK);

            // graph.Dispose();
            s.Dispose();
        }
示例#12
0
 protected void TF_AddInput(OperationDescription desc, TF_Output input)
 {
     c_api.TF_AddInput(desc, input);
 }