예제 #1
0
def resnet_v1_200(inputs,
                  num_classes=None,
                  is_training=True,
                  global_pool=True,
                  output_stride=None,
                  reuse=None,
                  scope='resnet_v1_200'):
    """ResNet-200 model of [2]. See resnet_v1() for arg and return description."""
    blocks = [
        resnet_utils.Block('block1', bottleneck,
                           [(256, 64, 1)] * 2 + [(256, 64, 2)]),
        resnet_utils.Block('block2', bottleneck,
                           [(512, 128, 1)] * 23 + [(512, 128, 2)]),
        resnet_utils.Block('block3', bottleneck,
                           [(1024, 256, 1)] * 35 + [(1024, 256, 2)]),
        resnet_utils.Block('block4', bottleneck, [(2048, 512, 1)] * 3)
    ]
    return resnet_v1(inputs,
                     blocks,
                     num_classes,
                     is_training,
                     global_pool=global_pool,
                     output_stride=output_stride,
                     include_root_block=True,
                     reuse=reuse,
                     scope=scope)
예제 #2
0
 def _resnet_small(self,
                   inputs,
                   num_classes=None,
                   is_training=True,
                   global_pool=True,
                   output_stride=None,
                   include_root_block=True,
                   reuse=None,
                   scope='resnet_v1_small'):
   """A shallow and thin ResNet v1 for faster tests."""
   bottleneck = resnet_v1.bottleneck
   blocks = [
       resnet_utils.Block(
           'block1', bottleneck, [(4, 1, 1)] * 2 + [(4, 1, 2)]),
       resnet_utils.Block(
           'block2', bottleneck, [(8, 2, 1)] * 2 + [(8, 2, 2)]),
       resnet_utils.Block(
           'block3', bottleneck, [(16, 4, 1)] * 2 + [(16, 4, 2)]),
       resnet_utils.Block(
           'block4', bottleneck, [(32, 8, 1)] * 2)]
   return resnet_v1.resnet_v1(inputs, blocks, num_classes,
                              is_training=is_training,
                              global_pool=global_pool,
                              output_stride=output_stride,
                              include_root_block=include_root_block,
                              reuse=reuse,
                              scope=scope)
예제 #3
0
 def testEndPointsV2(self):
     """Test the end points of a tiny v2 bottleneck network."""
     bottleneck = resnet_v2.bottleneck
     blocks = [
         resnet_utils.Block('block1', bottleneck, [(4, 1, 1), (4, 1, 2)]),
         resnet_utils.Block('block2', bottleneck, [(8, 2, 1), (8, 2, 1)])
     ]
     inputs = create_test_input(2, 32, 16, 3)
     with slim.arg_scope(resnet_utils.resnet_arg_scope()):
         _, end_points = self._resnet_plain(inputs, blocks, scope='tiny')
     expected = [
         'tiny/block1/unit_1/bottleneck_v2/shortcut',
         'tiny/block1/unit_1/bottleneck_v2/conv1',
         'tiny/block1/unit_1/bottleneck_v2/conv2',
         'tiny/block1/unit_1/bottleneck_v2/conv3',
         'tiny/block1/unit_2/bottleneck_v2/conv1',
         'tiny/block1/unit_2/bottleneck_v2/conv2',
         'tiny/block1/unit_2/bottleneck_v2/conv3',
         'tiny/block2/unit_1/bottleneck_v2/shortcut',
         'tiny/block2/unit_1/bottleneck_v2/conv1',
         'tiny/block2/unit_1/bottleneck_v2/conv2',
         'tiny/block2/unit_1/bottleneck_v2/conv3',
         'tiny/block2/unit_2/bottleneck_v2/conv1',
         'tiny/block2/unit_2/bottleneck_v2/conv2',
         'tiny/block2/unit_2/bottleneck_v2/conv3'
     ]
     self.assertItemsEqual(expected, end_points)
예제 #4
0
    def _atrousValues(self, bottleneck):
        """Verify the values of dense feature extraction by atrous convolution.

    Make sure that dense feature extraction by stack_blocks_dense() followed by
    subsampling gives identical results to feature extraction at the nominal
    network output stride using the simple self._stack_blocks_nondense() above.

    Args:
      bottleneck: The bottleneck function.
    """
        blocks = [
            resnet_utils.Block('block1', bottleneck, [(4, 1, 1), (4, 1, 2)]),
            resnet_utils.Block('block2', bottleneck, [(8, 2, 1), (8, 2, 2)]),
            resnet_utils.Block('block3', bottleneck, [(16, 4, 1), (16, 4, 2)]),
            resnet_utils.Block('block4', bottleneck, [(32, 8, 1), (32, 8, 1)])
        ]
        nominal_stride = 8

        # Test both odd and even input dimensions.
        height = 30
        width = 31
        with slim.arg_scope(resnet_utils.resnet_arg_scope()):
            with slim.arg_scope([slim.batch_norm], is_training=False):
                for output_stride in [1, 2, 4, 8, None]:
                    with tf.Graph().as_default():
                        with self.test_session() as sess:
                            tf.set_random_seed(0)
                            inputs = create_test_input(1, height, width, 3)
                            # Dense feature extraction followed by subsampling.
                            output = resnet_utils.stack_blocks_dense(
                                inputs, blocks, output_stride)
                            if output_stride is None:
                                factor = 1
                            else:
                                factor = nominal_stride // output_stride

                            output = resnet_utils.subsample(output, factor)
                            # Make the two networks use the same weights.
                            tf.get_variable_scope().reuse_variables()
                            # Feature extraction at the nominal network rate.
                            expected = self._stack_blocks_nondense(
                                inputs, blocks)
                            sess.run(tf.global_variables_initializer())
                            output, expected = sess.run([output, expected])
                            self.assertAllClose(output,
                                                expected,
                                                atol=1e-4,
                                                rtol=1e-4)
예제 #5
0
    def _extract_box_classifier_features(self, proposal_feature_maps, scope):
        """Extracts second stage box classifier features.

    Args:
      proposal_feature_maps: A 4-D float tensor with shape
        [batch_size * self.max_num_proposals, crop_height, crop_width, depth]
        representing the feature map cropped to each proposal.
      scope: A scope name (unused).

    Returns:
      proposal_classifier_features: A 4-D float tensor with shape
        [batch_size * self.max_num_proposals, height, width, depth]
        representing box classifier features for each proposal.
    """
        with tf.variable_scope(self._architecture, reuse=self._reuse_weights):
            with slim.arg_scope(
                    resnet_utils.resnet_arg_scope(
                        batch_norm_epsilon=1e-5,
                        batch_norm_scale=True,
                        weight_decay=self._weight_decay)):
                with slim.arg_scope([slim.batch_norm],
                                    is_training=self._train_batch_norm):
                    blocks = [
                        resnet_utils.Block('block4', resnet_v1.bottleneck,
                                           [{
                                               'depth': 2048,
                                               'depth_bottleneck': 512,
                                               'stride': 1
                                           }] * 3)
                    ]
                    proposal_classifier_features = resnet_utils.stack_blocks_dense(
                        proposal_feature_maps, blocks)
        return proposal_classifier_features
예제 #6
0
def resnet_v2_small_beta_block(scope, base_depth, num_units, stride):
    """helper for resnet v2"""
    block_args = []
    for _ in range(num_units - 1):
        block_args.append({'depth': base_depth, 'stride': 1, 'unit_rate': 1})
    block_args.append({'depth': base_depth, 'stride': stride, 'unit_rate': 1})
    return resnet_utils.Block(scope, lite_bottleneck_v2, block_args)
예제 #7
0
def resnet_v1_small_beta_block(scope, base_depth, num_units, stride):
    """Helper function for creating a resnet_18 beta variant bottleneck block.

  Args:
    scope: The scope of the block.
    base_depth: The depth of the bottleneck layer for each unit.
    num_units: The number of units in the block.
    stride: The stride of the block, implemented as a stride in the last unit.
      All other units have stride=1.

  Returns:
    A resnet_18 bottleneck block.
  """
    block_args = []
    for _ in range(num_units - 1):
        block_args.append({'depth': base_depth, 'stride': 1, 'unit_rate': 1})
    block_args.append({'depth': base_depth, 'stride': stride, 'unit_rate': 1})
    return resnet_utils.Block(scope, lite_bottleneck, block_args)
예제 #8
0
def resnet_v1_block(scope, base_depth, num_units, stride):
    """Helper function for creating a resnet_v1 bottleneck block.

  Args:
    scope: The scope of the block.
    base_depth: The depth of the bottleneck layer for each unit.
    num_units: The number of units in the block.
    stride: The stride of the block, implemented as a stride in the last unit.
      All other units have stride=1.

  Returns:
    A resnet_v1 bottleneck block.
  """
    return resnet_utils.Block(scope, bottleneck, [{
        'depth': base_depth * 4,
        'depth_bottleneck': base_depth,
        'stride': 1
    }] * (num_units - 1) + [{
        'depth': base_depth * 4,
        'depth_bottleneck': base_depth,
        'stride': stride
    }])
예제 #9
0
def resnet_v1_101_beta(inputs,
                       num_classes=None,
                       is_training=None,
                       global_pool=False,
                       output_stride=None,
                       multi_grid=None,
                       reuse=None,
                       scope='resnet_v1_101',
                       sync_batch_norm_method='None'):
    """Resnet v1 101 beta variant.

  This variant modifies the first convolution layer of ResNet-v1-101. In
  particular, it changes the original one 7x7 convolution to three 3x3
  convolutions.

  Args:
    inputs: A tensor of size [batch, height_in, width_in, channels].
    num_classes: Number of predicted classes for classification tasks. If None
      we return the features before the logit layer.
    is_training: Enable/disable is_training for batch normalization.
    global_pool: If True, we perform global average pooling before computing the
      logits. Set to True for image classification, False for dense prediction.
    output_stride: If None, then the output will be computed at the nominal
      network stride. If output_stride is not None, it specifies the requested
      ratio of input to output spatial resolution.
    multi_grid: Employ a hierarchy of different atrous rates within network.
    reuse: whether or not the network and its variables should be reused. To be
      able to reuse 'scope' must be given.
    scope: Optional variable_scope.
    sync_batch_norm_method: String, sync batchnorm method.

  Returns:
    net: A rank-4 tensor of size [batch, height_out, width_out, channels_out].
      If global_pool is False, then height_out and width_out are reduced by a
      factor of output_stride compared to the respective height_in and width_in,
      else both height_out and width_out equal one. If num_classes is None, then
      net is the output of the last ResNet block, potentially after global
      average pooling. If num_classes is not None, net contains the pre-softmax
      activations.
    end_points: A dictionary from components of the network to the corresponding
      activation.

  Raises:
    ValueError: if multi_grid is not None and does not have length = 3.
  """
    if multi_grid is None:
        multi_grid = _DEFAULT_MULTI_GRID
    else:
        if len(multi_grid) != 3:
            raise ValueError('Expect multi_grid to have length 3.')

    blocks = [
        resnet_v1_beta_block('block1', base_depth=64, num_units=3, stride=2),
        resnet_v1_beta_block('block2', base_depth=128, num_units=4, stride=2),
        resnet_v1_beta_block('block3', base_depth=256, num_units=23, stride=2),
        resnet_utils.Block('block4', bottleneck, [{
            'depth': 2048,
            'depth_bottleneck': 512,
            'stride': 1,
            'unit_rate': rate
        } for rate in multi_grid]),
    ]
    return resnet_v1_beta(
        inputs,
        blocks=blocks,
        num_classes=num_classes,
        is_training=is_training,
        global_pool=global_pool,
        output_stride=output_stride,
        root_block_fn=functools.partial(root_block_fn_for_beta_variant),
        reuse=reuse,
        scope=scope,
        sync_batch_norm_method=sync_batch_norm_method)
예제 #10
0
def resnet_mod(inputs,
               num_classes=None,
               is_training=None,
               global_pool=False,
               output_stride=None,
               multi_grid=None,
               root_depth_multiplier=0.25,
               reuse=None,
               scope='resnet_v1_18',
               sync_batch_norm_method='None'):
    """
    A custom Resnet variant based on v2 preact architecture.
    """

    ## define the multi_grid/atrous blocks
    if multi_grid is None:
        multi_grid = [1, 1]
    else:
        if len(multi_grid) != 2:
            raise ValueError('Expect multi_grid to have length 2.')

    block4_args = []
    for rate in multi_grid:
        block4_args.append({'depth': 512, 'stride': 1, 'unit_rate': rate})

    blocks = [
        resnet_v2_small_beta_block('block1',
                                   base_depth=64,
                                   num_units=1,
                                   stride=2),
        resnet_v2_small_beta_block('block2',
                                   base_depth=128,
                                   num_units=1,
                                   stride=2),
        resnet_v2_small_beta_block('block3',
                                   base_depth=256,
                                   num_units=1,
                                   stride=2),
        resnet_utils.Block('block4', lite_bottleneck_v2, block4_args),
    ]

    #     root_block_fn = root_block_fn_for_beta_variant
    root_block_fn = functools.partial(conv2d_ws.conv2d_same,
                                      num_outputs=64,
                                      kernel_size=3,
                                      stride=2,
                                      scope='root_conv1')

    batch_norm = utils.get_batch_norm_fn(sync_batch_norm_method)
    with tf.variable_scope(scope, 'resnet_mod', [inputs], reuse=reuse) as sc:
        end_points_collection = sc.original_name_scope + '_end_points'
        with slim.arg_scope([
                slim.conv2d, conv2d_ws.conv2d, lite_bottleneck_v2,
                resnet_utils.stack_blocks_dense
        ],
                            outputs_collections=end_points_collection):
            if is_training is not None:
                arg_scope = slim.arg_scope([batch_norm],
                                           is_training=is_training)
            else:
                arg_scope = slim.arg_scope([])
            with arg_scope:
                net = inputs
                if output_stride is not None:
                    if output_stride % 4 != 0:
                        raise ValueError(
                            'The output_stride needs to be a multiple of 4.')
                    output_stride //= 2
                net = root_block_fn(net)
                #             net = slim.max_pool2d(net, 3, stride=2, padding='SAME', scope='pool1')
                net = resnet_utils.stack_blocks_dense(net, blocks,
                                                      output_stride)
                ## add a batchnorm and relu layer since the last conv output don't have them in v2
                net = slim.batch_norm(net,
                                      activation_fn=tf.nn.relu,
                                      scope='postnorm')
                # Convert end_points_collection into a dictionary of end_points.
                end_points = slim.utils.convert_collection_to_dict(
                    end_points_collection)
                return net, end_points