/tensorflow/python/kernel_tests/lrn_op_test.py

https://gitlab.com/github-cloud-corporation/tensorflow
Python | 142 lines | 99 code | 15 blank | 28 comment | 18 complexity | 3ff26393e1e7b97fefd9c2f7de5481d5 MD5 | raw file
  1. # Copyright 2015 The TensorFlow Authors. All Rights Reserved.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. # ==============================================================================
  15. """Tests for local response normalization."""
  16. from __future__ import absolute_import
  17. from __future__ import division
  18. from __future__ import print_function
  19. import copy
  20. import numpy as np
  21. import tensorflow as tf
  22. class LRNOpTest(tf.test.TestCase):
  23. def _LRN(self, input_image, lrn_depth_radius=5, bias=1.0,
  24. alpha=1.0, beta=0.5):
  25. """Compute expected result."""
  26. output = copy.deepcopy(input_image)
  27. batch_size = input_image.shape[0]
  28. rows = input_image.shape[1]
  29. cols = input_image.shape[2]
  30. depth = input_image.shape[3]
  31. for b in range(batch_size):
  32. for r in range(rows):
  33. for c in range(cols):
  34. for d in range(depth):
  35. begin = max(0, d - lrn_depth_radius)
  36. end = min(depth, d + lrn_depth_radius + 1)
  37. patch = input_image[b, r, c, begin:end]
  38. output[b, r, c, d] /= (
  39. np.power(bias + alpha * np.sum(patch * patch), beta))
  40. return output
  41. def _RunAndVerify(self, dtype):
  42. with self.test_session():
  43. # random shape
  44. shape = np.random.randint(1, 16, size=4)
  45. # Make depth at least 2 to make it meaningful
  46. shape[3] += 1
  47. p = tf.placeholder(dtype, shape=shape)
  48. # random depth_radius, bias, alpha, beta. cuDNN requires depth_radius to
  49. # be in [1, 7].
  50. lrn_depth_radius = np.random.randint(1, min(8, shape[3]))
  51. bias = 1.0 + np.random.rand()
  52. alpha = 2.0 * np.random.rand()
  53. # cuDNN requires beta >= 0.01.
  54. beta = 0.01 + 2.0 * np.random.rand()
  55. lrn_t = tf.nn.local_response_normalization(
  56. p, name="lrn", depth_radius=lrn_depth_radius, bias=bias,
  57. alpha=alpha, beta=beta)
  58. params = {p: np.random.rand(*shape).astype("f")}
  59. result = lrn_t.eval(feed_dict=params)
  60. expected = self._LRN(
  61. params[p], lrn_depth_radius=lrn_depth_radius, bias=bias, alpha=alpha,
  62. beta=beta)
  63. err = np.amax(np.abs(result - expected))
  64. print("LRN error for bias ", bias, "alpha ", alpha, " beta ", beta, " is ", err)
  65. if dtype == tf.float32:
  66. self.assertTrue(err < 1e-4)
  67. else:
  68. self.assertTrue(err < 1e-2)
  69. self.assertShapeEqual(expected, lrn_t)
  70. def testCompute(self):
  71. for _ in range(2):
  72. self._RunAndVerify(tf.float32)
  73. # Enable when LRN supports tf.float16 on GPU.
  74. if not tf.test.is_gpu_available():
  75. self._RunAndVerify(tf.float16)
  76. def testGradientsZeroInput(self):
  77. with self.test_session():
  78. shape = [4, 4, 4, 4]
  79. p = tf.placeholder(tf.float32, shape=shape)
  80. inp_array = np.zeros(shape).astype("f")
  81. lrn_op = tf.nn.local_response_normalization(p, 2, 1.0, 0.0,
  82. 1.0, name="lrn")
  83. grad = tf.gradients([lrn_op], [p])[0]
  84. params = {p: inp_array}
  85. r = grad.eval(feed_dict=params)
  86. expected = np.ones(shape).astype("f")
  87. self.assertAllClose(r, expected)
  88. self.assertShapeEqual(expected, grad)
  89. def _RunAndVerifyGradients(self, dtype):
  90. with self.test_session():
  91. # random shape
  92. shape = np.random.randint(1, 5, size=4)
  93. # Make depth at least 2 to make it meaningful
  94. shape[3] += 1
  95. # random depth_radius, bias, alpha, beta. cuDNN requires depth_radius to
  96. # be in [1, 7].
  97. lrn_depth_radius = np.random.randint(1, min(8, shape[3]))
  98. bias = 1.0 + np.random.rand()
  99. alpha = 1.0 * np.random.rand()
  100. # cuDNN requires beta >= 0.01.
  101. beta = 0.01 + 1.0 * np.random.rand()
  102. if dtype == tf.float32:
  103. inp_array = np.random.rand(*shape).astype(np.float32)
  104. else:
  105. inp_array = np.random.rand(*shape).astype(np.float16)
  106. inp = tf.constant(
  107. list(inp_array.ravel(order="C")),
  108. shape=shape,
  109. dtype=dtype)
  110. lrn_op = tf.nn.local_response_normalization(
  111. inp, name="lrn", depth_radius=lrn_depth_radius, bias=bias,
  112. alpha=alpha, beta=beta)
  113. err = tf.test.compute_gradient_error(inp, shape, lrn_op, shape)
  114. print("LRN Gradient error for bias ", bias, "alpha ", alpha, " beta ", beta,
  115. " is ", err)
  116. if dtype == tf.float32:
  117. self.assertLess(err, 1e-4)
  118. else:
  119. self.assertLess(err, 1.0)
  120. def testGradients(self):
  121. for _ in range(2):
  122. self._RunAndVerifyGradients(tf.float32)
  123. # Enable when LRN supports tf.float16 on GPU.
  124. if not tf.test.is_gpu_available():
  125. self._RunAndVerifyGradients(tf.float16)
  126. if __name__ == "__main__":
  127. tf.test.main()