1 # Copyright 2017 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 parse_layer_parameters module.""" 16 17 from __future__ import absolute_import 18 from __future__ import division 19 from __future__ import print_function 20 21 from tensorflow.contrib import slim 22 from tensorflow.contrib.receptive_field.python.util import graph_compute_order 23 from tensorflow.contrib.receptive_field.python.util import parse_layer_parameters 24 from tensorflow.python.framework import dtypes 25 from tensorflow.python.framework import ops 26 from tensorflow.python.ops import array_ops 27 from tensorflow.python.ops import gen_math_ops 28 from tensorflow.python.ops import nn 29 from tensorflow.python.platform import test 30 31 32 def create_test_network(): 33 """Convolutional neural network for test. 34 35 Returns: 36 name_to_node: Dict keyed by node name, each entry containing the node's 37 NodeDef. 38 """ 39 g = ops.Graph() 40 with g.as_default(): 41 # An input test image with unknown spatial resolution. 42 x = array_ops.placeholder( 43 dtypes.float32, (None, None, None, 1), name='input_image') 44 # Left branch before first addition. 45 l1 = slim.conv2d(x, 1, [1, 1], stride=4, scope='L1', padding='VALID') 46 # Right branch before first addition. 47 l2_pad = array_ops.pad(x, [[0, 0], [1, 0], [1, 0], [0, 0]], name='L2_pad') 48 l2 = slim.conv2d(l2_pad, 1, [3, 3], stride=2, scope='L2', padding='VALID') 49 l3 = slim.max_pool2d(l2, [3, 3], stride=2, scope='L3', padding='SAME') 50 # First addition. 51 l4 = nn.relu(l1 + l3, name='L4_relu') 52 # Left branch after first addition. 53 l5 = slim.conv2d(l4, 1, [1, 1], stride=2, scope='L5', padding='SAME') 54 # Right branch after first addition. 55 l6 = slim.conv2d(l4, 1, [3, 3], stride=2, scope='L6', padding='SAME') 56 # Final addition. 57 gen_math_ops.add(l5, l6, name='L7_add') 58 59 name_to_node = graph_compute_order.parse_graph_nodes(g.as_graph_def()) 60 return name_to_node 61 62 63 class ParseLayerParametersTest(test.TestCase): 64 65 def testParametersAreParsedCorrectly(self): 66 """Checks parameters from create_test_network() are parsed correctly.""" 67 name_to_node = create_test_network() 68 69 # L1. 70 l1_node_name = 'L1/Conv2D' 71 l1_params = parse_layer_parameters.get_layer_params( 72 name_to_node[l1_node_name], name_to_node) 73 expected_l1_params = (1, 1, 4, 4, 0, 0, 0, 0) 74 self.assertEqual(l1_params, expected_l1_params) 75 76 # L2 padding. 77 l2_pad_name = 'L2_pad' 78 l2_pad_params = parse_layer_parameters.get_layer_params( 79 name_to_node[l2_pad_name], name_to_node) 80 expected_l2_pad_params = (1, 1, 1, 1, 1, 1, 1, 1) 81 self.assertEqual(l2_pad_params, expected_l2_pad_params) 82 83 # L2. 84 l2_node_name = 'L2/Conv2D' 85 l2_params = parse_layer_parameters.get_layer_params( 86 name_to_node[l2_node_name], name_to_node) 87 expected_l2_params = (3, 3, 2, 2, 0, 0, 0, 0) 88 self.assertEqual(l2_params, expected_l2_params) 89 90 # L3. 91 l3_node_name = 'L3/MaxPool' 92 # - Without knowing input size. 93 l3_params = parse_layer_parameters.get_layer_params( 94 name_to_node[l3_node_name], name_to_node) 95 expected_l3_params = (3, 3, 2, 2, None, None, None, None) 96 self.assertEqual(l3_params, expected_l3_params) 97 # - Input size is even. 98 l3_even_params = parse_layer_parameters.get_layer_params( 99 name_to_node[l3_node_name], name_to_node, input_resolution=[4, 4]) 100 expected_l3_even_params = (3, 3, 2, 2, 0, 0, 1, 1) 101 self.assertEqual(l3_even_params, expected_l3_even_params) 102 # - Input size is odd. 103 l3_odd_params = parse_layer_parameters.get_layer_params( 104 name_to_node[l3_node_name], name_to_node, input_resolution=[5, 5]) 105 expected_l3_odd_params = (3, 3, 2, 2, 1, 1, 2, 2) 106 self.assertEqual(l3_odd_params, expected_l3_odd_params) 107 108 # L4. 109 l4_node_name = 'L4_relu' 110 l4_params = parse_layer_parameters.get_layer_params( 111 name_to_node[l4_node_name], name_to_node) 112 expected_l4_params = (1, 1, 1, 1, 0, 0, 0, 0) 113 self.assertEqual(l4_params, expected_l4_params) 114 115 # L5. 116 l5_node_name = 'L5/Conv2D' 117 l5_params = parse_layer_parameters.get_layer_params( 118 name_to_node[l5_node_name], name_to_node) 119 expected_l5_params = (1, 1, 2, 2, 0, 0, 0, 0) 120 self.assertEqual(l5_params, expected_l5_params) 121 122 # L6. 123 l6_node_name = 'L6/Conv2D' 124 # - Without knowing input size. 125 l6_params = parse_layer_parameters.get_layer_params( 126 name_to_node[l6_node_name], name_to_node) 127 expected_l6_params = (3, 3, 2, 2, None, None, None, None) 128 self.assertEqual(l6_params, expected_l6_params) 129 # - Input size is even. 130 l6_even_params = parse_layer_parameters.get_layer_params( 131 name_to_node[l6_node_name], name_to_node, input_resolution=[4, 4]) 132 expected_l6_even_params = (3, 3, 2, 2, 0, 0, 1, 1) 133 self.assertEqual(l6_even_params, expected_l6_even_params) 134 # - Input size is odd. 135 l6_odd_params = parse_layer_parameters.get_layer_params( 136 name_to_node[l6_node_name], name_to_node, input_resolution=[5, 5]) 137 expected_l6_odd_params = (3, 3, 2, 2, 1, 1, 2, 2) 138 self.assertEqual(l6_odd_params, expected_l6_odd_params) 139 140 # L7. 141 l7_node_name = 'L7_add' 142 l7_params = parse_layer_parameters.get_layer_params( 143 name_to_node[l7_node_name], name_to_node) 144 expected_l7_params = (1, 1, 1, 1, 0, 0, 0, 0) 145 self.assertEqual(l7_params, expected_l7_params) 146 147 148 if __name__ == '__main__': 149 test.main() 150