inception_v2_test.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. # Copyright 2016 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 nets.inception_v2."""
  16. from __future__ import absolute_import
  17. from __future__ import division
  18. from __future__ import print_function
  19. import numpy as np
  20. import tensorflow as tf
  21. from nets import inception
  22. slim = tf.contrib.slim
  23. class InceptionV2Test(tf.test.TestCase):
  24. def testBuildClassificationNetwork(self):
  25. batch_size = 5
  26. height, width = 224, 224
  27. num_classes = 1000
  28. inputs = tf.random_uniform((batch_size, height, width, 3))
  29. logits, end_points = inception.inception_v2(inputs, num_classes)
  30. self.assertTrue(logits.op.name.startswith(
  31. 'InceptionV2/Logits/SpatialSqueeze'))
  32. self.assertListEqual(logits.get_shape().as_list(),
  33. [batch_size, num_classes])
  34. self.assertTrue('Predictions' in end_points)
  35. self.assertListEqual(end_points['Predictions'].get_shape().as_list(),
  36. [batch_size, num_classes])
  37. def testBuildPreLogitsNetwork(self):
  38. batch_size = 5
  39. height, width = 224, 224
  40. num_classes = None
  41. inputs = tf.random_uniform((batch_size, height, width, 3))
  42. net, end_points = inception.inception_v2(inputs, num_classes)
  43. self.assertTrue(net.op.name.startswith('InceptionV2/Logits/AvgPool'))
  44. self.assertListEqual(net.get_shape().as_list(), [batch_size, 1, 1, 1024])
  45. self.assertFalse('Logits' in end_points)
  46. self.assertFalse('Predictions' in end_points)
  47. def testBuildBaseNetwork(self):
  48. batch_size = 5
  49. height, width = 224, 224
  50. inputs = tf.random_uniform((batch_size, height, width, 3))
  51. mixed_5c, end_points = inception.inception_v2_base(inputs)
  52. self.assertTrue(mixed_5c.op.name.startswith('InceptionV2/Mixed_5c'))
  53. self.assertListEqual(mixed_5c.get_shape().as_list(),
  54. [batch_size, 7, 7, 1024])
  55. expected_endpoints = ['Mixed_3b', 'Mixed_3c', 'Mixed_4a', 'Mixed_4b',
  56. 'Mixed_4c', 'Mixed_4d', 'Mixed_4e', 'Mixed_5a',
  57. 'Mixed_5b', 'Mixed_5c', 'Conv2d_1a_7x7',
  58. 'MaxPool_2a_3x3', 'Conv2d_2b_1x1', 'Conv2d_2c_3x3',
  59. 'MaxPool_3a_3x3']
  60. self.assertItemsEqual(end_points.keys(), expected_endpoints)
  61. def testBuildOnlyUptoFinalEndpoint(self):
  62. batch_size = 5
  63. height, width = 224, 224
  64. endpoints = ['Conv2d_1a_7x7', 'MaxPool_2a_3x3', 'Conv2d_2b_1x1',
  65. 'Conv2d_2c_3x3', 'MaxPool_3a_3x3', 'Mixed_3b', 'Mixed_3c',
  66. 'Mixed_4a', 'Mixed_4b', 'Mixed_4c', 'Mixed_4d', 'Mixed_4e',
  67. 'Mixed_5a', 'Mixed_5b', 'Mixed_5c']
  68. for index, endpoint in enumerate(endpoints):
  69. with tf.Graph().as_default():
  70. inputs = tf.random_uniform((batch_size, height, width, 3))
  71. out_tensor, end_points = inception.inception_v2_base(
  72. inputs, final_endpoint=endpoint)
  73. self.assertTrue(out_tensor.op.name.startswith(
  74. 'InceptionV2/' + endpoint))
  75. self.assertItemsEqual(endpoints[:index+1], end_points)
  76. def testBuildAndCheckAllEndPointsUptoMixed5c(self):
  77. batch_size = 5
  78. height, width = 224, 224
  79. inputs = tf.random_uniform((batch_size, height, width, 3))
  80. _, end_points = inception.inception_v2_base(inputs,
  81. final_endpoint='Mixed_5c')
  82. endpoints_shapes = {'Mixed_3b': [batch_size, 28, 28, 256],
  83. 'Mixed_3c': [batch_size, 28, 28, 320],
  84. 'Mixed_4a': [batch_size, 14, 14, 576],
  85. 'Mixed_4b': [batch_size, 14, 14, 576],
  86. 'Mixed_4c': [batch_size, 14, 14, 576],
  87. 'Mixed_4d': [batch_size, 14, 14, 576],
  88. 'Mixed_4e': [batch_size, 14, 14, 576],
  89. 'Mixed_5a': [batch_size, 7, 7, 1024],
  90. 'Mixed_5b': [batch_size, 7, 7, 1024],
  91. 'Mixed_5c': [batch_size, 7, 7, 1024],
  92. 'Conv2d_1a_7x7': [batch_size, 112, 112, 64],
  93. 'MaxPool_2a_3x3': [batch_size, 56, 56, 64],
  94. 'Conv2d_2b_1x1': [batch_size, 56, 56, 64],
  95. 'Conv2d_2c_3x3': [batch_size, 56, 56, 192],
  96. 'MaxPool_3a_3x3': [batch_size, 28, 28, 192]}
  97. self.assertItemsEqual(endpoints_shapes.keys(), end_points.keys())
  98. for endpoint_name in endpoints_shapes:
  99. expected_shape = endpoints_shapes[endpoint_name]
  100. self.assertTrue(endpoint_name in end_points)
  101. self.assertListEqual(end_points[endpoint_name].get_shape().as_list(),
  102. expected_shape)
  103. def testModelHasExpectedNumberOfParameters(self):
  104. batch_size = 5
  105. height, width = 224, 224
  106. inputs = tf.random_uniform((batch_size, height, width, 3))
  107. with slim.arg_scope(inception.inception_v2_arg_scope()):
  108. inception.inception_v2_base(inputs)
  109. total_params, _ = slim.model_analyzer.analyze_vars(
  110. slim.get_model_variables())
  111. self.assertAlmostEqual(10173112, total_params)
  112. def testBuildEndPointsWithDepthMultiplierLessThanOne(self):
  113. batch_size = 5
  114. height, width = 224, 224
  115. num_classes = 1000
  116. inputs = tf.random_uniform((batch_size, height, width, 3))
  117. _, end_points = inception.inception_v2(inputs, num_classes)
  118. endpoint_keys = [key for key in end_points.keys()
  119. if key.startswith('Mixed') or key.startswith('Conv')]
  120. _, end_points_with_multiplier = inception.inception_v2(
  121. inputs, num_classes, scope='depth_multiplied_net',
  122. depth_multiplier=0.5)
  123. for key in endpoint_keys:
  124. original_depth = end_points[key].get_shape().as_list()[3]
  125. new_depth = end_points_with_multiplier[key].get_shape().as_list()[3]
  126. self.assertEqual(0.5 * original_depth, new_depth)
  127. def testBuildEndPointsWithDepthMultiplierGreaterThanOne(self):
  128. batch_size = 5
  129. height, width = 224, 224
  130. num_classes = 1000
  131. inputs = tf.random_uniform((batch_size, height, width, 3))
  132. _, end_points = inception.inception_v2(inputs, num_classes)
  133. endpoint_keys = [key for key in end_points.keys()
  134. if key.startswith('Mixed') or key.startswith('Conv')]
  135. _, end_points_with_multiplier = inception.inception_v2(
  136. inputs, num_classes, scope='depth_multiplied_net',
  137. depth_multiplier=2.0)
  138. for key in endpoint_keys:
  139. original_depth = end_points[key].get_shape().as_list()[3]
  140. new_depth = end_points_with_multiplier[key].get_shape().as_list()[3]
  141. self.assertEqual(2.0 * original_depth, new_depth)
  142. def testRaiseValueErrorWithInvalidDepthMultiplier(self):
  143. batch_size = 5
  144. height, width = 224, 224
  145. num_classes = 1000
  146. inputs = tf.random_uniform((batch_size, height, width, 3))
  147. with self.assertRaises(ValueError):
  148. _ = inception.inception_v2(inputs, num_classes, depth_multiplier=-0.1)
  149. with self.assertRaises(ValueError):
  150. _ = inception.inception_v2(inputs, num_classes, depth_multiplier=0.0)
  151. def testBuildEndPointsWithUseSeparableConvolutionFalse(self):
  152. batch_size = 5
  153. height, width = 224, 224
  154. inputs = tf.random_uniform((batch_size, height, width, 3))
  155. _, end_points = inception.inception_v2_base(inputs)
  156. endpoint_keys = [
  157. key for key in end_points.keys()
  158. if key.startswith('Mixed') or key.startswith('Conv')
  159. ]
  160. _, end_points_with_replacement = inception.inception_v2_base(
  161. inputs, use_separable_conv=False)
  162. # The endpoint shapes must be equal to the original shape even when the
  163. # separable convolution is replaced with a normal convolution.
  164. for key in endpoint_keys:
  165. original_shape = end_points[key].get_shape().as_list()
  166. self.assertTrue(key in end_points_with_replacement)
  167. new_shape = end_points_with_replacement[key].get_shape().as_list()
  168. self.assertListEqual(original_shape, new_shape)
  169. def testBuildEndPointsNCHWDataFormat(self):
  170. batch_size = 5
  171. height, width = 224, 224
  172. inputs = tf.random_uniform((batch_size, height, width, 3))
  173. _, end_points = inception.inception_v2_base(inputs)
  174. endpoint_keys = [
  175. key for key in end_points.keys()
  176. if key.startswith('Mixed') or key.startswith('Conv')
  177. ]
  178. inputs_in_nchw = tf.random_uniform((batch_size, 3, height, width))
  179. _, end_points_with_replacement = inception.inception_v2_base(
  180. inputs_in_nchw, use_separable_conv=False, data_format='NCHW')
  181. # With the 'NCHW' data format, all endpoint activations have a transposed
  182. # shape from the original shape with the 'NHWC' layout.
  183. for key in endpoint_keys:
  184. transposed_original_shape = tf.transpose(
  185. end_points[key], [0, 3, 1, 2]).get_shape().as_list()
  186. self.assertTrue(key in end_points_with_replacement)
  187. new_shape = end_points_with_replacement[key].get_shape().as_list()
  188. self.assertListEqual(transposed_original_shape, new_shape)
  189. def testBuildErrorsForDataFormats(self):
  190. batch_size = 5
  191. height, width = 224, 224
  192. inputs = tf.random_uniform((batch_size, height, width, 3))
  193. # 'NCWH' data format is not supported.
  194. with self.assertRaises(ValueError):
  195. _ = inception.inception_v2_base(inputs, data_format='NCWH')
  196. # 'NCHW' data format is not supported for separable convolution.
  197. with self.assertRaises(ValueError):
  198. _ = inception.inception_v2_base(inputs, data_format='NCHW')
  199. def testHalfSizeImages(self):
  200. batch_size = 5
  201. height, width = 112, 112
  202. num_classes = 1000
  203. inputs = tf.random_uniform((batch_size, height, width, 3))
  204. logits, end_points = inception.inception_v2(inputs, num_classes)
  205. self.assertTrue(logits.op.name.startswith('InceptionV2/Logits'))
  206. self.assertListEqual(logits.get_shape().as_list(),
  207. [batch_size, num_classes])
  208. pre_pool = end_points['Mixed_5c']
  209. self.assertListEqual(pre_pool.get_shape().as_list(),
  210. [batch_size, 4, 4, 1024])
  211. def testUnknownImageShape(self):
  212. tf.reset_default_graph()
  213. batch_size = 2
  214. height, width = 224, 224
  215. num_classes = 1000
  216. input_np = np.random.uniform(0, 1, (batch_size, height, width, 3))
  217. with self.test_session() as sess:
  218. inputs = tf.placeholder(tf.float32, shape=(batch_size, None, None, 3))
  219. logits, end_points = inception.inception_v2(inputs, num_classes)
  220. self.assertTrue(logits.op.name.startswith('InceptionV2/Logits'))
  221. self.assertListEqual(logits.get_shape().as_list(),
  222. [batch_size, num_classes])
  223. pre_pool = end_points['Mixed_5c']
  224. feed_dict = {inputs: input_np}
  225. tf.global_variables_initializer().run()
  226. pre_pool_out = sess.run(pre_pool, feed_dict=feed_dict)
  227. self.assertListEqual(list(pre_pool_out.shape), [batch_size, 7, 7, 1024])
  228. def testGlobalPoolUnknownImageShape(self):
  229. tf.reset_default_graph()
  230. batch_size = 2
  231. height, width = 300, 400
  232. num_classes = 1000
  233. input_np = np.random.uniform(0, 1, (batch_size, height, width, 3))
  234. with self.test_session() as sess:
  235. inputs = tf.placeholder(tf.float32, shape=(batch_size, None, None, 3))
  236. logits, end_points = inception.inception_v2(inputs, num_classes,
  237. global_pool=True)
  238. self.assertTrue(logits.op.name.startswith('InceptionV2/Logits'))
  239. self.assertListEqual(logits.get_shape().as_list(),
  240. [batch_size, num_classes])
  241. pre_pool = end_points['Mixed_5c']
  242. feed_dict = {inputs: input_np}
  243. tf.global_variables_initializer().run()
  244. pre_pool_out = sess.run(pre_pool, feed_dict=feed_dict)
  245. self.assertListEqual(list(pre_pool_out.shape), [batch_size, 10, 13, 1024])
  246. def testUnknowBatchSize(self):
  247. batch_size = 1
  248. height, width = 224, 224
  249. num_classes = 1000
  250. inputs = tf.placeholder(tf.float32, (None, height, width, 3))
  251. logits, _ = inception.inception_v2(inputs, num_classes)
  252. self.assertTrue(logits.op.name.startswith('InceptionV2/Logits'))
  253. self.assertListEqual(logits.get_shape().as_list(),
  254. [None, num_classes])
  255. images = tf.random_uniform((batch_size, height, width, 3))
  256. with self.test_session() as sess:
  257. sess.run(tf.global_variables_initializer())
  258. output = sess.run(logits, {inputs: images.eval()})
  259. self.assertEquals(output.shape, (batch_size, num_classes))
  260. def testEvaluation(self):
  261. batch_size = 2
  262. height, width = 224, 224
  263. num_classes = 1000
  264. eval_inputs = tf.random_uniform((batch_size, height, width, 3))
  265. logits, _ = inception.inception_v2(eval_inputs, num_classes,
  266. is_training=False)
  267. predictions = tf.argmax(logits, 1)
  268. with self.test_session() as sess:
  269. sess.run(tf.global_variables_initializer())
  270. output = sess.run(predictions)
  271. self.assertEquals(output.shape, (batch_size,))
  272. def testTrainEvalWithReuse(self):
  273. train_batch_size = 5
  274. eval_batch_size = 2
  275. height, width = 150, 150
  276. num_classes = 1000
  277. train_inputs = tf.random_uniform((train_batch_size, height, width, 3))
  278. inception.inception_v2(train_inputs, num_classes)
  279. eval_inputs = tf.random_uniform((eval_batch_size, height, width, 3))
  280. logits, _ = inception.inception_v2(eval_inputs, num_classes, reuse=True)
  281. predictions = tf.argmax(logits, 1)
  282. with self.test_session() as sess:
  283. sess.run(tf.global_variables_initializer())
  284. output = sess.run(predictions)
  285. self.assertEquals(output.shape, (eval_batch_size,))
  286. def testLogitsNotSqueezed(self):
  287. num_classes = 25
  288. images = tf.random_uniform([1, 224, 224, 3])
  289. logits, _ = inception.inception_v2(images,
  290. num_classes=num_classes,
  291. spatial_squeeze=False)
  292. with self.test_session() as sess:
  293. tf.global_variables_initializer().run()
  294. logits_out = sess.run(logits)
  295. self.assertListEqual(list(logits_out.shape), [1, 1, 1, num_classes])
  296. if __name__ == '__main__':
  297. tf.test.main()