pcb defect detetcion application
[ealt-edge.git] / example-apps / PDD / pcb-defect-detection / libs / networks / mobilenet / mobilenet_v2_test.py
diff --git a/example-apps/PDD/pcb-defect-detection/libs/networks/mobilenet/mobilenet_v2_test.py b/example-apps/PDD/pcb-defect-detection/libs/networks/mobilenet/mobilenet_v2_test.py
new file mode 100755 (executable)
index 0000000..40e48fa
--- /dev/null
@@ -0,0 +1,176 @@
+# 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()