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.

GradientDescentOptimizerTests.cs 9.7 kB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. using Microsoft.VisualStudio.TestTools.UnitTesting;
  2. using System;
  3. using System.Linq;
  4. using Tensorflow;
  5. using Tensorflow.NumPy;
  6. using static Tensorflow.Binding;
  7. namespace TensorFlowNET.UnitTest.Training
  8. {
  9. [TestClass]
  10. public class GradientDescentOptimizerTest : PythonTest
  11. {
  12. private static TF_DataType GetTypeForNumericType<T>() where T : struct
  13. {
  14. return Type.GetTypeCode(typeof(T)) switch
  15. {
  16. TypeCode.Single => np.float32,
  17. TypeCode.Double => np.float64,
  18. _ => throw new NotImplementedException(),
  19. };
  20. }
  21. private void TestBasic<T>() where T : struct
  22. {
  23. var dtype = GetTypeForNumericType<T>();
  24. // train.GradientDescentOptimizer is V1 only API.
  25. tf.Graph().as_default();
  26. using (var sess = self.cached_session())
  27. {
  28. var var0 = tf.Variable(new[] { 1.0, 2.0 }, dtype: dtype);
  29. var var1 = tf.Variable(new[] { 3.0, 4.0 }, dtype: dtype);
  30. var grads0 = tf.constant(new[] { 0.1, 0.1 }, dtype: dtype);
  31. var grads1 = tf.constant(new[] { 0.01, 0.01 }, dtype: dtype);
  32. var optimizer = tf.train.GradientDescentOptimizer(3.0f);
  33. var grads_and_vars = new[] {
  34. Tuple.Create(grads0, var0 as IVariableV1),
  35. Tuple.Create(grads1, var1 as IVariableV1)
  36. };
  37. var sgd_op = optimizer.apply_gradients(grads_and_vars);
  38. var global_variables = tf.global_variables_initializer();
  39. sess.run(global_variables);
  40. var initialVar0 = sess.run(var0);
  41. var initialVar1 = sess.run(var1);
  42. // Fetch params to validate initial values
  43. self.assertAllCloseAccordingToType(new[] { 1.0, 2.0 }, self.evaluate<T[]>(var0));
  44. self.assertAllCloseAccordingToType(new[] { 3.0, 4.0 }, self.evaluate<T[]>(var1));
  45. // Run 1 step of sgd
  46. sgd_op.run();
  47. // Validate updated params
  48. self.assertAllCloseAccordingToType(
  49. new[] { 1.0 - 3.0 * 0.1, 2.0 - 3.0 * 0.1 },
  50. self.evaluate<T[]>(var0));
  51. self.assertAllCloseAccordingToType(
  52. new[] { 3.0 - 3.0 * 0.01, 4.0 - 3.0 * 0.01 },
  53. self.evaluate<T[]>(var1));
  54. // TODO: self.assertEqual(0, len(optimizer.variables()));
  55. }
  56. }
  57. [TestMethod]
  58. public void TestBasic()
  59. {
  60. //TODO: add np.half
  61. TestBasic<float>();
  62. TestBasic<double>();
  63. }
  64. private void TestMinimizeResourceVariable<T>() where T : struct
  65. {
  66. var dtype = GetTypeForNumericType<T>();
  67. // train.GradientDescentOptimizer is V1 only API.
  68. tf.Graph().as_default();
  69. using (var sess = self.cached_session())
  70. {
  71. var var0 = tf.Variable(new[,] { { 1.0f, 2.0f } }, dtype: dtype);
  72. var var1 = tf.Variable(new[] { 3.0 }, dtype: dtype);
  73. var x = tf.constant(new[,] { { 4.0f }, { 5.0f } }, dtype: dtype);
  74. var pred = math_ops.matmul(var0, x) + var1;
  75. var loss = pred * pred;
  76. var sgd_op = tf.train.GradientDescentOptimizer(3.0f).minimize(loss);
  77. var global_variables = tf.global_variables_initializer();
  78. sess.run(global_variables);
  79. sess.run(new[] { var0, var1 });
  80. // Fetch params to validate initial values
  81. self.assertAllCloseAccordingToType<T>(new[,] { { 1.0, 2.0 } }, self.evaluate<T[,]>(var0));
  82. self.assertAllCloseAccordingToType(new[] { 3.0 }, self.evaluate<T[]>(var1));
  83. // Run 1 step of sgd
  84. sgd_op.run();
  85. // Validate updated params
  86. var np_pred = 1.0 * 4.0 + 2.0 * 5.0 + 3.0;
  87. var np_grad = 2 * np_pred;
  88. self.assertAllCloseAccordingToType(
  89. new[,] { { 1.0 - np_grad * 4.0, 2.0 - np_grad * 5.0 } },
  90. self.evaluate<T[,]>(var0));
  91. self.assertAllCloseAccordingToType(
  92. new[] { 3.0 - np_grad },
  93. self.evaluate<T[]>(var1));
  94. }
  95. }
  96. [TestMethod]
  97. public void TestMinimizeResourceVariable()
  98. {
  99. //TODO: add np.half
  100. TestMinimizeResourceVariable<float>();
  101. TestMinimizeResourceVariable<double>();
  102. }
  103. private void TestTensorLearningRate<T>() where T : struct
  104. {
  105. var dtype = GetTypeForNumericType<T>();
  106. // train.GradientDescentOptimizer is V1 only API.
  107. tf.Graph().as_default();
  108. using (var sess = self.cached_session())
  109. {
  110. var var0 = tf.Variable(new[] { 1.0, 2.0 }, dtype: dtype);
  111. var var1 = tf.Variable(new[] { 3.0, 4.0 }, dtype: dtype);
  112. var grads0 = tf.constant(new[] { 0.1, 0.1 }, dtype: dtype);
  113. var grads1 = tf.constant(new[] { 0.01, 0.01 }, dtype: dtype);
  114. var lrate = constant_op.constant(3.0);
  115. var grads_and_vars = new[] {
  116. Tuple.Create(grads0, var0 as IVariableV1),
  117. Tuple.Create(grads1, var1 as IVariableV1)
  118. };
  119. var sgd_op = tf.train.GradientDescentOptimizer(lrate)
  120. .apply_gradients(grads_and_vars);
  121. var global_variables = tf.global_variables_initializer();
  122. sess.run(global_variables);
  123. var initialVar0 = sess.run(var0);
  124. var initialVar1 = sess.run(var1);
  125. // Fetch params to validate initial values
  126. self.assertAllCloseAccordingToType(new[] { 1.0, 2.0 }, self.evaluate<T[]>(var0));
  127. self.assertAllCloseAccordingToType(new[] { 3.0, 4.0 }, self.evaluate<T[]>(var1));
  128. // Run 1 step of sgd
  129. sgd_op.run();
  130. // Validate updated params
  131. self.assertAllCloseAccordingToType(
  132. new[] { 1.0 - 3.0 * 0.1, 2.0 - 3.0 * 0.1 },
  133. self.evaluate<T[]>(var0));
  134. self.assertAllCloseAccordingToType(
  135. new[] { 3.0 - 3.0 * 0.01, 4.0 - 3.0 * 0.01 },
  136. self.evaluate<T[]>(var1));
  137. // TODO: self.assertEqual(0, len(optimizer.variables()));
  138. }
  139. }
  140. [TestMethod]
  141. public void TestTensorLearningRate()
  142. {
  143. //TODO: add np.half
  144. TestTensorLearningRate<float>();
  145. TestTensorLearningRate<double>();
  146. }
  147. public void TestGradWrtRef<T>() where T : struct
  148. {
  149. var dtype = GetTypeForNumericType<T>();
  150. var graph = tf.Graph().as_default();
  151. using (var sess = self.cached_session())
  152. {
  153. var opt = tf.train.GradientDescentOptimizer(3.0f);
  154. var values = new[] { 1.0, 3.0 };
  155. var vars_ = values.Select(
  156. v => tf.Variable(new[] { v }, dtype: dtype) as IVariableV1
  157. ).ToList();
  158. var grads_and_vars = opt.compute_gradients(tf.add(vars_[0], vars_[1]), vars_);
  159. sess.run(tf.global_variables_initializer());
  160. foreach (var (grad, _) in grads_and_vars)
  161. self.assertAllCloseAccordingToType(new[] { 1.0 }, self.evaluate<T[]>(grad));
  162. }
  163. }
  164. [TestMethod]
  165. public void TestGradWrtRef()
  166. {
  167. TestGradWrtRef<float>();
  168. TestGradWrtRef<double>();
  169. }
  170. public void TestWithGlobalStep<T>() where T : struct
  171. {
  172. var dtype = GetTypeForNumericType<T>();
  173. tf.Graph().as_default();
  174. using (var sess = self.cached_session())
  175. {
  176. var global_step = tf.Variable(0, trainable: false);
  177. var var0 = tf.Variable(new[] { 1.0, 2.0 }, dtype: dtype);
  178. var var1 = tf.Variable(new[] { 3.0, 4.0 }, dtype: dtype);
  179. var grads0 = tf.constant(new[] { 0.1, 0.1 }, dtype: dtype);
  180. var grads1 = tf.constant(new[] { 0.01, 0.01 }, dtype: dtype);
  181. var grads_and_vars = new[] {
  182. Tuple.Create(grads0, var0 as IVariableV1),
  183. Tuple.Create(grads1, var1 as IVariableV1)
  184. };
  185. var sgd_op = tf.train.GradientDescentOptimizer(3.0f)
  186. .apply_gradients(grads_and_vars, global_step: global_step);
  187. sess.run(tf.global_variables_initializer());
  188. // Fetch params to validate initial values
  189. self.assertAllCloseAccordingToType(new[] { 1.0, 2.0 }, self.evaluate<T[]>(var0));
  190. self.assertAllCloseAccordingToType(new[] { 3.0, 4.0 }, self.evaluate<T[]>(var1));
  191. // Run 1 step of sgd
  192. sgd_op.run();
  193. // Validate updated params and global_step
  194. self.assertAllCloseAccordingToType(new[] { 1.0 - 3.0 * 0.1, 2.0 - 3.0 * 0.1 }, self.evaluate<T[]>(var0));
  195. self.assertAllCloseAccordingToType(new[] { 3.0 - 3.0 * 0.01, 4.0 - 3.0 * 0.01 }, self.evaluate<T[]>(var1));
  196. Assert.AreEqual(1, self.evaluate<int>(global_step));
  197. }
  198. }
  199. [TestMethod]
  200. public void TestWithGlobalStep()
  201. {
  202. TestWithGlobalStep<float>();
  203. TestWithGlobalStep<double>();
  204. }
  205. }
  206. }