You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

CreateOpFromTfOperationTest.cs 12 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Microsoft.VisualStudio.TestTools.UnitTesting;
  6. using Tensorflow;
  7. using Tensorflow.Operations;
  8. namespace TensorFlowNET.UnitTest.ops_test
  9. {
  10. /// <summary>
  11. /// excerpt of tensorflow/python/framework/ops_test.py
  12. /// # These cases test the private Graph._create_op_from_tf_operation
  13. /// # method. Arguably we should only test the public APIs that depend on this
  14. /// # method. However, this logic is complex and tricky, and it can be difficult to
  15. /// # ascertain if we have adequate coverage (e.g. a graph may run successfully if
  16. /// # the control flow context isn't set properly, but a more complicated use case
  17. /// # that might not be obvious to test will fail). Thus we instead explicitly test
  18. /// # the low-level behavior.
  19. /// </summary>
  20. [TestClass]
  21. public class CreateOpFromTfOperationTest : PythonTest
  22. {
  23. [TestMethod]
  24. public void TestShape()
  25. {
  26. var graph = tf.Graph().as_default();
  27. with<Graph>(graph, g =>
  28. {
  29. var x = constant_op.constant(new[,] { { 1, 2, 3 }, { 4, 5, 6 } });
  30. var (c_op, op_desc) = ops._create_c_op(g, ops._NodeDef("Identity", "myop"), new[] { x }, new Operation[0]);
  31. var op = g._create_op_from_tf_operation(c_op);
  32. Assert.AreEqual("myop", op.name);
  33. Assert.AreEqual("Identity", op.type);
  34. Assert.AreEqual(1, len(op.outputs));
  35. assertItemsEqual(new[] { 2, 3 }, op.outputs[0].shape);
  36. });
  37. }
  38. [TestMethod]
  39. public void TestUniqueName()
  40. {
  41. var graph = tf.Graph().as_default();
  42. with<Graph>(graph, g =>
  43. {
  44. //var (c_op,op_desc) = ops._create_c_op(g, ops._NodeDef("Const", "myop"), new Tensor[0], new Operation[0]);
  45. //var (c_op2, op_desc1) = ops._create_c_op(g, ops._NodeDef("Const", "myop_1"), new Tensor[0], new Operation[0]);
  46. //var op = g._create_op_from_tf_operation(c_op);
  47. //var op2 = g._create_op_from_tf_operation(c_op2);
  48. var op = constant_op.constant(0, name: "myop").op;
  49. var op2 = constant_op.constant(0, name: "myop_1").op;
  50. // Create ops with same names as op1 and op2. We expect the new names to be
  51. // uniquified.
  52. var op3 = constant_op.constant(0, name: "myop").op;
  53. var op4 = constant_op.constant(0, name: "myop_1").op;
  54. self.assertEqual(op.name, "myop");
  55. self.assertEqual(op2.name, "myop_1");
  56. self.assertEqual(op3.name, "myop_2");
  57. self.assertEqual(op4.name, "myop_1_1");
  58. });
  59. }
  60. [Ignore("Switch op gets not inserted correctly in the graph")]
  61. [TestMethod]
  62. public void TestCond()
  63. {
  64. var graph = tf.Graph().as_default();
  65. with<Graph>(graph, g =>
  66. {
  67. var x = constant_op.constant(10);
  68. var true_fn = new Func<Tensor>(() =>
  69. {
  70. var (c_op, op_desc) = ops._create_c_op(g, ops._NodeDef("Identity", "cond/myop"), new[] { x }, new Operation[0]);
  71. var new_ops = g._add_new_tf_operations();
  72. self.assertEqual(len(new_ops), 1);
  73. return x;
  74. });
  75. control_flow_ops.cond(x < 10, true_fn, () => x);
  76. var op = g.get_operation_by_name("cond/myop");
  77. self.assertIsNotNone(op);
  78. self.assertEqual(op.name, "cond/myop");
  79. self.assertEqual(op.type, "Identity");
  80. //self.assertEqual(op.outputs, new object[0]);
  81. var op_input = op.inputs[0].op;
  82. self.assertEqual(op_input.type, "Switch");
  83. self.assertEqual(op_input.inputs[0], x);
  84. self.assertEqual(op.graph, g);
  85. self.assertIsNotNone(op._get_control_flow_context());
  86. self.assertEqual((op._get_control_flow_context() as ControlFlowContext).name, "cond/cond_text");
  87. });
  88. /*
  89. @test_util.run_v1_only("b/120545219")
  90. def testCond(self):
  91. g = ops.Graph()
  92. with g.as_default():
  93. x = test_ops.int_output()
  94. def true_fn():
  95. ops._create_c_op(ops.get_default_graph(),
  96. ops._NodeDef("IntInput", "cond/myop"), [x], [])
  97. new_ops = g._add_new_tf_operations()
  98. self.assertEqual(len(new_ops), 1)
  99. return x
  100. control_flow_ops.cond(x < 10, true_fn, lambda: x)
  101. op = g.get_operation_by_name("cond/myop")
  102. self.assertIsNotNone(op)
  103. self.assertEqual(op.name, "cond/myop")
  104. self.assertEqual(op.type, "IntInput")
  105. self.assertEqual(op.outputs, [])
  106. op_input = op.inputs[0].op
  107. self.assertEqual(op_input.type, "Switch")
  108. self.assertEqual(op_input.inputs[0], x)
  109. self.assertEqual(op.graph, g)
  110. # pylint: disable=protected-access
  111. self.assertIsNotNone(op._get_control_flow_context())
  112. self.assertEqual(op._get_control_flow_context().name,
  113. "cond/cond_text")
  114. # pylint: enable=protected-access
  115. */
  116. }
  117. [Ignore("Todo: Port")]
  118. [TestMethod]
  119. public void TestWhileLoop()
  120. {
  121. var graph = tf.Graph().as_default();
  122. Operation x=null;
  123. with<Graph>(graph, g =>
  124. {
  125. x = constant_op.constant(42);
  126. var body = new Func<int, int>(i =>
  127. {
  128. ops._create_c_op(ops.get_default_graph(), ops._NodeDef("Identity", "myloop/myop"), new[] {x},
  129. new Operation[0]);
  130. var new_ops = g._add_new_tf_operations();
  131. self.assertEqual(len(new_ops), 1);
  132. return i;
  133. });
  134. // TODO: port control_flow_ops.while_loop
  135. //control_flow_ops.while_loop( i => i < 10, body, new int[]{0}, name = "myloop");
  136. });
  137. var op = graph.get_operation_by_name("myloop/myop");
  138. self.assertIsNotNone(op);
  139. self.assertEqual(op.name, "myloop/myop");
  140. self.assertEqual(op.type, "Identity");
  141. self.assertEqual(op.outputs.Length, 0);
  142. var op_input = op.inputs[0].op;
  143. self.assertEqual(op_input.type, "Enter");
  144. self.assertItemsEqual(op_input.inputs.OfType<Operation>().ToArray(), new[] {x});
  145. self.assertEqual(op.graph, graph);
  146. self.assertIsNotNone(op._get_control_flow_context());
  147. self.assertEqual(((ControlFlowContext)op._get_control_flow_context()).name, "myloop/while_context");
  148. /*
  149. @test_util.run_v1_only("b/120545219")
  150. def testWhileLoop(self):
  151. g = ops.Graph()
  152. with g.as_default():
  153. x = test_ops.int_output()
  154. def body(i):
  155. ops._create_c_op(ops.get_default_graph(),
  156. ops._NodeDef("IntInput", "myloop/myop"), [x], [])
  157. new_ops = g._add_new_tf_operations()
  158. self.assertEqual(len(new_ops), 1)
  159. return i
  160. control_flow_ops.while_loop(lambda i: i < 10, body, [0], name="myloop")
  161. op = g.get_operation_by_name("myloop/myop")
  162. self.assertIsNotNone(op)
  163. self.assertEqual(op.name, "myloop/myop")
  164. self.assertEqual(op.type, "IntInput")
  165. self.assertEqual(op.outputs, [])
  166. op_input = op.inputs[0].op
  167. self.assertEqual(op_input.type, "Enter")
  168. self.assertEqual(list(op_input.inputs), [x])
  169. self.assertEqual(op.graph, g)
  170. # pylint: disable=protected-access
  171. self.assertIsNotNone(op._get_control_flow_context())
  172. self.assertEqual(op._get_control_flow_context().name,
  173. "myloop/while_context")
  174. # pylint: enable=protected-access
  175. */
  176. }
  177. [Ignore("Todo: Port")]
  178. [TestMethod]
  179. public void TestWhileLoopWithInternalControlDep()
  180. {
  181. /*
  182. @test_util.run_v1_only("b/120545219")
  183. def testWhileLoopWithInternalControlDep(self):
  184. g = ops.Graph()
  185. with g.as_default():
  186. x = test_ops.int_output()
  187. def body(i):
  188. c = constant_op.constant(1.0, name="c")
  189. ops._create_c_op(ops.get_default_graph(),
  190. ops._NodeDef("IntInput", "myloop/myop"), [x], [])
  191. with ops.control_dependencies([c]):
  192. new_ops = g._add_new_tf_operations()
  193. self.assertEqual(len(new_ops), 1)
  194. return i
  195. control_flow_ops.while_loop(lambda i: i < 10, body, [0], name="myloop")
  196. op = g.get_operation_by_name("myloop/myop")
  197. self.assertIsNotNone(op)
  198. c = g.get_operation_by_name("myloop/c")
  199. self.assertIsNotNone(c)
  200. # Internal control dep is preserved
  201. self.assertEqual(op.control_inputs, [c])
  202. */
  203. }
  204. [Ignore("Todo: Port")]
  205. [TestMethod]
  206. public void TestWhileLoopWithExternalControlDep()
  207. {
  208. /*
  209. @test_util.run_v1_only("b/120545219")
  210. def testWhileLoopWithExternalControlDep(self):
  211. g = ops.Graph()
  212. with g.as_default():
  213. x = test_ops.int_output()
  214. c = constant_op.constant(1.0)
  215. def body(i):
  216. ops._create_c_op(ops.get_default_graph(),
  217. ops._NodeDef("IntInput", "myloop/myop"), [x], [])
  218. with ops.control_dependencies([c]):
  219. new_ops = g._add_new_tf_operations()
  220. self.assertEqual(len(new_ops), 1)
  221. return i
  222. control_flow_ops.while_loop(lambda i: i < 10, body, [0], name="myloop")
  223. op = g.get_operation_by_name("myloop/myop")
  224. self.assertIsNotNone(op)
  225. # External control dep is removed and replaced with internal control dep
  226. self.assertNotEqual(op.control_inputs[0], c.op)
  227. self.assertIsNotNone(op.control_inputs[0]._get_control_flow_context())
  228. */
  229. }
  230. }
  231. }

tensorflow框架的.NET版本,提供了丰富的特性和API,可以借此很方便地在.NET平台下搭建深度学习训练与推理流程。