| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| """Base test class SSDFeatureExtractors.""" |
|
|
| from abc import abstractmethod |
|
|
| import itertools |
| import numpy as np |
| import tensorflow as tf |
|
|
| from google.protobuf import text_format |
| from object_detection.builders import hyperparams_builder |
| from object_detection.protos import hyperparams_pb2 |
| from object_detection.utils import test_case |
|
|
|
|
| class SsdFeatureExtractorTestBase(test_case.TestCase): |
|
|
| def _build_conv_hyperparams(self, add_batch_norm=True): |
| conv_hyperparams = hyperparams_pb2.Hyperparams() |
| conv_hyperparams_text_proto = """ |
| activation: RELU_6 |
| regularizer { |
| l2_regularizer { |
| } |
| } |
| initializer { |
| truncated_normal_initializer { |
| } |
| } |
| """ |
| if add_batch_norm: |
| batch_norm_proto = """ |
| batch_norm { |
| scale: false |
| } |
| """ |
| conv_hyperparams_text_proto += batch_norm_proto |
| text_format.Merge(conv_hyperparams_text_proto, conv_hyperparams) |
| return hyperparams_builder.KerasLayerHyperparams(conv_hyperparams) |
|
|
| def conv_hyperparams_fn(self): |
| with tf.contrib.slim.arg_scope([]) as sc: |
| return sc |
|
|
| @abstractmethod |
| def _create_feature_extractor(self, depth_multiplier, pad_to_multiple, |
| use_explicit_padding=False, use_keras=False): |
| """Constructs a new feature extractor. |
| |
| Args: |
| depth_multiplier: float depth multiplier for feature extractor |
| pad_to_multiple: the nearest multiple to zero pad the input height and |
| width dimensions to. |
| use_explicit_padding: use 'VALID' padding for convolutions, but prepad |
| inputs so that the output dimensions are the same as if 'SAME' padding |
| were used. |
| use_keras: if True builds a keras-based feature extractor, if False builds |
| a slim-based one. |
| Returns: |
| an ssd_meta_arch.SSDFeatureExtractor or an |
| ssd_meta_arch.SSDKerasFeatureExtractor object. |
| """ |
| pass |
|
|
| def _extract_features(self, image_tensor, depth_multiplier, pad_to_multiple, |
| use_explicit_padding=False, use_keras=False): |
| try: |
| feature_extractor = self._create_feature_extractor(depth_multiplier, |
| pad_to_multiple, |
| use_explicit_padding, |
| use_keras=use_keras) |
| |
| except TypeError: |
| feature_extractor = self._create_feature_extractor(depth_multiplier, |
| pad_to_multiple, |
| use_explicit_padding) |
| if use_keras: |
| feature_maps = feature_extractor(image_tensor) |
| else: |
| feature_maps = feature_extractor.extract_features(image_tensor) |
| return feature_maps |
|
|
| def check_extract_features_returns_correct_shape( |
| self, batch_size, image_height, image_width, depth_multiplier, |
| pad_to_multiple, expected_feature_map_shapes, use_explicit_padding=False, |
| use_keras=False): |
| def graph_fn(image_tensor): |
| return self._extract_features(image_tensor, |
| depth_multiplier, |
| pad_to_multiple, |
| use_explicit_padding, |
| use_keras=use_keras) |
|
|
| image_tensor = np.random.rand(batch_size, image_height, image_width, |
| 3).astype(np.float32) |
| feature_maps = self.execute(graph_fn, [image_tensor]) |
| for feature_map, expected_shape in itertools.izip( |
| feature_maps, expected_feature_map_shapes): |
| self.assertAllEqual(feature_map.shape, expected_shape) |
|
|
| def check_extract_features_returns_correct_shapes_with_dynamic_inputs( |
| self, batch_size, image_height, image_width, depth_multiplier, |
| pad_to_multiple, expected_feature_map_shapes, use_explicit_padding=False, |
| use_keras=False): |
| def graph_fn(image_height, image_width): |
| image_tensor = tf.random_uniform([batch_size, image_height, image_width, |
| 3], dtype=tf.float32) |
| return self._extract_features(image_tensor, |
| depth_multiplier, |
| pad_to_multiple, |
| use_explicit_padding, |
| use_keras=use_keras) |
|
|
| feature_maps = self.execute_cpu(graph_fn, [ |
| np.array(image_height, dtype=np.int32), |
| np.array(image_width, dtype=np.int32) |
| ]) |
| for feature_map, expected_shape in itertools.izip( |
| feature_maps, expected_feature_map_shapes): |
| self.assertAllEqual(feature_map.shape, expected_shape) |
|
|
| def check_extract_features_raises_error_with_invalid_image_size( |
| self, image_height, image_width, depth_multiplier, pad_to_multiple, |
| use_keras=False): |
| preprocessed_inputs = tf.placeholder(tf.float32, (4, None, None, 3)) |
| feature_maps = self._extract_features(preprocessed_inputs, |
| depth_multiplier, |
| pad_to_multiple, |
| use_keras=use_keras) |
| test_preprocessed_image = np.random.rand(4, image_height, image_width, 3) |
| with self.test_session() as sess: |
| sess.run(tf.global_variables_initializer()) |
| with self.assertRaises(tf.errors.InvalidArgumentError): |
| sess.run(feature_maps, |
| feed_dict={preprocessed_inputs: test_preprocessed_image}) |
|
|
| def check_feature_extractor_variables_under_scope( |
| self, depth_multiplier, pad_to_multiple, scope_name, use_keras=False): |
| variables = self.get_feature_extractor_variables( |
| depth_multiplier, pad_to_multiple, use_keras) |
| for variable in variables: |
| self.assertTrue(variable.name.startswith(scope_name)) |
|
|
| def get_feature_extractor_variables( |
| self, depth_multiplier, pad_to_multiple, use_keras=False): |
| g = tf.Graph() |
| with g.as_default(): |
| preprocessed_inputs = tf.placeholder(tf.float32, (4, None, None, 3)) |
| self._extract_features(preprocessed_inputs, |
| depth_multiplier, |
| pad_to_multiple, |
| use_keras=use_keras) |
| return g.get_collection(tf.GraphKeys.GLOBAL_VARIABLES) |
|
|