+++ /dev/null
-# Copyright 2018 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for mobilenet_v2."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-import copy
-import tensorflow as tf
-from nets.mobilenet import conv_blocks as ops
-from nets.mobilenet import mobilenet
-from nets.mobilenet import mobilenet_v2
-
-
-slim = tf.contrib.slim
-
-
-def find_ops(optype):
- """Find ops of a given type in graphdef or a graph.
-
- Args:
- optype: operation type (e.g. Conv2D)
- Returns:
- List of operations.
- """
- gd = tf.get_default_graph()
- return [var for var in gd.get_operations() if var.type == optype]
-
-
-class MobilenetV2Test(tf.test.TestCase):
-
- def setUp(self):
- tf.reset_default_graph()
-
- def testCreation(self):
- spec = dict(mobilenet_v2.V2_DEF)
- _, ep = mobilenet.mobilenet(
- tf.placeholder(tf.float32, (10, 224, 224, 16)), conv_defs=spec)
- num_convs = len(find_ops('Conv2D'))
-
- # This is mostly a sanity test. No deep reason for these particular
- # constants.
- #
- # All but first 2 and last one have two convolutions, and there is one
- # extra conv that is not in the spec. (logits)
- self.assertEqual(num_convs, len(spec['spec']) * 2 - 2)
- # Check that depthwise are exposed.
- for i in range(2, 17):
- self.assertIn('layer_%d/depthwise_output' % i, ep)
-
- def testCreationNoClasses(self):
- spec = copy.deepcopy(mobilenet_v2.V2_DEF)
- net, ep = mobilenet.mobilenet(
- tf.placeholder(tf.float32, (10, 224, 224, 16)), conv_defs=spec,
- num_classes=None)
- self.assertIs(net, ep['global_pool'])
-
- def testImageSizes(self):
- for input_size, output_size in [(224, 7), (192, 6), (160, 5),
- (128, 4), (96, 3)]:
- tf.reset_default_graph()
- _, ep = mobilenet_v2.mobilenet(
- tf.placeholder(tf.float32, (10, input_size, input_size, 3)))
-
- self.assertEqual(ep['layer_18/output'].get_shape().as_list()[1:3],
- [output_size] * 2)
-
- def testWithSplits(self):
- spec = copy.deepcopy(mobilenet_v2.V2_DEF)
- spec['overrides'] = {
- (ops.expanded_conv,): dict(split_expansion=2),
- }
- _, _ = mobilenet.mobilenet(
- tf.placeholder(tf.float32, (10, 224, 224, 16)), conv_defs=spec)
- num_convs = len(find_ops('Conv2D'))
- # All but 3 op has 3 conv operatore, the remainign 3 have one
- # and there is one unaccounted.
- self.assertEqual(num_convs, len(spec['spec']) * 3 - 5)
-
- def testWithOutputStride8(self):
- out, _ = mobilenet.mobilenet_base(
- tf.placeholder(tf.float32, (10, 224, 224, 16)),
- conv_defs=mobilenet_v2.V2_DEF,
- output_stride=8,
- scope='MobilenetV2')
- self.assertEqual(out.get_shape().as_list()[1:3], [28, 28])
-
- def testDivisibleBy(self):
- tf.reset_default_graph()
- mobilenet_v2.mobilenet(
- tf.placeholder(tf.float32, (10, 224, 224, 16)),
- conv_defs=mobilenet_v2.V2_DEF,
- divisible_by=16,
- min_depth=32)
- s = [op.outputs[0].get_shape().as_list()[-1] for op in find_ops('Conv2D')]
- s = set(s)
- self.assertSameElements([32, 64, 96, 160, 192, 320, 384, 576, 960, 1280,
- 1001], s)
-
- def testDivisibleByWithArgScope(self):
- tf.reset_default_graph()
- # Verifies that depth_multiplier arg scope actually works
- # if no default min_depth is provided.
- with slim.arg_scope((mobilenet.depth_multiplier,), min_depth=32):
- mobilenet_v2.mobilenet(
- tf.placeholder(tf.float32, (10, 224, 224, 2)),
- conv_defs=mobilenet_v2.V2_DEF, depth_multiplier=0.1)
- s = [op.outputs[0].get_shape().as_list()[-1] for op in find_ops('Conv2D')]
- s = set(s)
- self.assertSameElements(s, [32, 192, 128, 1001])
-
- def testFineGrained(self):
- tf.reset_default_graph()
- # Verifies that depth_multiplier arg scope actually works
- # if no default min_depth is provided.
-
- mobilenet_v2.mobilenet(
- tf.placeholder(tf.float32, (10, 224, 224, 2)),
- conv_defs=mobilenet_v2.V2_DEF, depth_multiplier=0.01,
- finegrain_classification_mode=True)
- s = [op.outputs[0].get_shape().as_list()[-1] for op in find_ops('Conv2D')]
- s = set(s)
- # All convolutions will be 8->48, except for the last one.
- self.assertSameElements(s, [8, 48, 1001, 1280])
-
- def testMobilenetBase(self):
- tf.reset_default_graph()
- # Verifies that mobilenet_base returns pre-pooling layer.
- with slim.arg_scope((mobilenet.depth_multiplier,), min_depth=32):
- net, _ = mobilenet_v2.mobilenet_base(
- tf.placeholder(tf.float32, (10, 224, 224, 16)),
- conv_defs=mobilenet_v2.V2_DEF, depth_multiplier=0.1)
- self.assertEqual(net.get_shape().as_list(), [10, 7, 7, 128])
-
- def testWithOutputStride16(self):
- tf.reset_default_graph()
- out, _ = mobilenet.mobilenet_base(
- tf.placeholder(tf.float32, (10, 224, 224, 16)),
- conv_defs=mobilenet_v2.V2_DEF,
- output_stride=16)
- self.assertEqual(out.get_shape().as_list()[1:3], [14, 14])
-
- def testWithOutputStride8AndExplicitPadding(self):
- tf.reset_default_graph()
- out, _ = mobilenet.mobilenet_base(
- tf.placeholder(tf.float32, (10, 224, 224, 16)),
- conv_defs=mobilenet_v2.V2_DEF,
- output_stride=8,
- use_explicit_padding=True,
- scope='MobilenetV2')
- self.assertEqual(out.get_shape().as_list()[1:3], [28, 28])
-
- def testWithOutputStride16AndExplicitPadding(self):
- tf.reset_default_graph()
- out, _ = mobilenet.mobilenet_base(
- tf.placeholder(tf.float32, (10, 224, 224, 16)),
- conv_defs=mobilenet_v2.V2_DEF,
- output_stride=16,
- use_explicit_padding=True)
- self.assertEqual(out.get_shape().as_list()[1:3], [14, 14])
-
-
-if __name__ == '__main__':
- tf.test.main()