Example #1
0
def resnet_v1_slim_fc(inputs, scope):
    """ slim version of resnet, can be replaced with
        
        resnet_v1.resnet_v1_50(inputs, num_classes=None, global_pool=True,
                               output_stride=None, reuse=False, scope=scope)

        or any of the other resnsets
    """
    blocks = [
        resnet_utils.Block('block1', resnet_v1.bottleneck,
                           [(64, 32, 1)] * 2 + [(64, 32, 2)]),
        resnet_utils.Block('block2', resnet_v1.bottleneck,
                           [(128, 64, 1)] * 3 + [(128, 64, 2)]),
        resnet_utils.Block('block3', resnet_v1.bottleneck,
                           [(256, 64, 1)] * 3 + [(256, 64, 2)]),
        resnet_utils.Block('block4', resnet_v1.bottleneck, [(128, 64, 1)] * 1)
    ]
    return resnet_v1.resnet_v1(
        inputs,
        blocks,
        # all parameters below can be passed to resnet_v1.resnet_v1_??
        num_classes=None,  # don't produce final prediction
        global_pool=
        True,  # produce 1x1 output, equivalent to input of a FC layer
        output_stride=None,
        include_root_block=True,
        reuse=False,  # do not re-use network
        # my understanding
        # task1      image -> resnet1 -> output
        # task2      image -> resnet2 -> output
        # if both resnets are defined under the same scope,
        # with reuse set to True, then some of the parameters
        # will be shared between two tasks
        scope=scope)
Example #2
0
 def testEndPointsV1(self):
     """Test the end points of a tiny v1 bottleneck network."""
     bottleneck = resnet_v1.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_v1/shortcut',
         'tiny/block1/unit_1/bottleneck_v1/conv1',
         'tiny/block1/unit_1/bottleneck_v1/conv2',
         'tiny/block1/unit_1/bottleneck_v1/conv3',
         'tiny/block1/unit_2/bottleneck_v1/conv1',
         'tiny/block1/unit_2/bottleneck_v1/conv2',
         'tiny/block1/unit_2/bottleneck_v1/conv3',
         'tiny/block2/unit_1/bottleneck_v1/shortcut',
         'tiny/block2/unit_1/bottleneck_v1/conv1',
         'tiny/block2/unit_1/bottleneck_v1/conv2',
         'tiny/block2/unit_1/bottleneck_v1/conv3',
         'tiny/block2/unit_2/bottleneck_v1/conv1',
         'tiny/block2/unit_2/bottleneck_v1/conv2',
         'tiny/block2/unit_2/bottleneck_v1/conv3'
     ]
     self.assertItemsEqual(expected, end_points)
    def _build_tail(self, inputs, is_training=False):
        if not self._use_tail:
            return inputs

        if self._architecture == 'resnet_v1_101':
            train_batch_norm = (is_training
                                and self._config.get('train_batch_norm'))
            with self._enter_variable_scope():
                weight_decay = (self._config.get('arg_scope',
                                                 {}).get('weight_decay', 0))
                with tf.variable_scope(self._architecture, reuse=True):
                    resnet_arg_scope = resnet_utils.resnet_arg_scope(
                        batch_norm_epsilon=1e-5,
                        batch_norm_scale=True,
                        weight_decay=weight_decay)
                    with slim.arg_scope(resnet_arg_scope):
                        with slim.arg_scope([slim.batch_norm],
                                            is_training=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(
                                    inputs, blocks))
        else:
            proposal_classifier_features = inputs

        return proposal_classifier_features
    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
def resnet_v1_block(scope, base_depth, num_units, stride, rate=1):
    """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.
  """
    minor_depth = int(base_depth)
    major_depth = int(base_depth * 4)
    return resnet_utils.Block(scope, bottleneck, [{
        'depth': major_depth,
        'depth_bottleneck': minor_depth,
        'stride': 1,
        'overide_rate': rate
    }] * (num_units - 1) + [{
        'depth': major_depth,
        'depth_bottleneck': minor_depth,
        'stride': stride,
        'overide_rate': rate
    }])
def resnet_v1_beta_block(scope,
                         base_depth,
                         num_units,
                         stride,
                         dropout=False,
                         num_drop=4):
    """Helper function for creating a resnet_v1 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_v1 bottleneck block.
  """
    if dropout == True:
        return resnet_utils.Block(scope, bottleneck, [{
            'depth': base_depth * 4,
            'depth_bottleneck': base_depth,
            'stride': 1,
            'unit_rate': 1,
            'dropout': True
        }] * (num_drop) + [{
            'depth': base_depth * 4,
            'depth_bottleneck': base_depth,
            'stride': 1,
            'unit_rate': 1
        }] * (num_units - 1 - num_drop) + [{
            'depth': base_depth * 4,
            'depth_bottleneck': base_depth,
            'stride': stride,
            'unit_rate': 1
        }])
    return resnet_utils.Block(scope, bottleneck, [{
        'depth': base_depth * 4,
        'depth_bottleneck': base_depth,
        'stride': 1,
        'unit_rate': 1
    }] * (num_units - 1) + [{
        'depth': base_depth * 4,
        'depth_bottleneck': base_depth,
        'stride': stride,
        'unit_rate': 1
    }])
Example #7
0
def resnet_tiny2(inputs, num_classes=2, scope='resnet_tiny'):
    # seperate cls and fcn, add stop_gradient after fcn output
    blocks = [
        resnet_utils.Block('block1', resnet_v1.bottleneck,
                           [(64, 32, 1)] + [(64, 32, 2)]),
        resnet_utils.Block('block2', resnet_v1.bottleneck,
                           [(128, 64, 1)] + [(128, 64, 2)]),
        resnet_utils.Block('block3', resnet_v1.bottleneck,
                           [(256, 64, 1)] + [(128, 64, 2)]),
        resnet_utils.Block('block4', resnet_v1.bottleneck, [(128, 64, 1)])
    ]
    net, _ = resnet_v1.resnet_v1(
        inputs,
        blocks,
        # all parameters below can be passed to resnet_v1.resnet_v1_??
        num_classes=None,  # don't produce final prediction
        global_pool=
        False,  # produce 1x1 output, equivalent to input of a FC layer
        output_stride=16,
        include_root_block=True,
        reuse=False,  # do not re-use network
        scope=scope)
    res_out = net  # keep this for later CLS usage
    net = slim.batch_norm(slim.conv2d_transpose(net, 64, 5, 2))
    net = slim.batch_norm(slim.conv2d_transpose(net, 32, 5, 2))
    net = slim.batch_norm(slim.conv2d_transpose(net, 16, 5, 2))
    net = slim.batch_norm(slim.conv2d_transpose(net, 8, 5, 2))
    net = slim.conv2d(net, num_classes, 5, 1, activation_fn=None)
    logits_fcn = tf.identity(net, 'logits_fcn')

    net = res_out
    net = tf.stop_gradient(net)
    # add a few layers to make the image size even smaller
    net = slim.conv2d(net, 128, 3, 1)
    net = slim.max_pool2d(net, 2, 2)
    net = slim.conv2d(net, 128, 3, 1)
    net = slim.max_pool2d(net, 2, 2)
    net = tf.reduce_mean(net, [1, 2], keep_dims=True)
    # add an extra layer
    net = slim.conv2d(net, 64, [1, 1])
    net = slim.conv2d(net,
                      num_classes, [1, 1],
                      activation_fn=None,
                      normalizer_fn=None)
    logits_cls = tf.identity(net, 'logits_cls')

    return logits_fcn, logits_cls, 16
Example #8
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(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.initialize_all_variables())
                        output, expected = sess.run([output, expected])
                        self.assertAllClose(output,
                                            expected,
                                            atol=1e-4,
                                            rtol=1e-4)
Example #9
0
def resnet_v1_200(inputs,
                  num_classes=None,
                  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, global_pool, output_stride,
                   include_root_block=True, reuse=reuse, scope=scope)
Example #10
0
def resnet_v1_50_beta(inputs,
                      num_classes=None,
                      is_training=None,
                      global_pool=False,
                      output_stride=None,
                      multi_grid=None,
                      reuse=None,
                      scope='resnet_v1_50'):
    """Resnet v1 50 beta 变体

    Args:
    :param inputs:tensor 尺寸,[batch, height_in, width, channels]
    :param num_classes: 用于分类任务的预测类别数
    :param is_training:是否用BN进行训练
    :param global_pool: 如果为真,则在计算logits前执行全局平均池化。真用于图像分类,假用于预测
    :param output_stride:如果为None,则输出将在标称网络步长处计算。 如果output_stride不是None,则它指定所请求的输入与输出空间分辨率的比率。
    :param multi_grid:在网络中使用不同的atrous卷积率的层次结构
    :param reuse:是否应该重用网络及其变量。 重用的话,必须给定重用的'scope'
    :param scope:可选variable_scope
    :return:net:4级张量的大小[batch,height_out,width_out,channels_out]。 如果global_pool为False,
    则height_out和width_out与相应的height_in和width_in相比减少了output_stride因子,
    否则height_out和width_out都等于1。 如果num_classes为None,则net是最后一个ResNet块的输出,可能是在全局平均池之后。
    如果num_classes不是None,则net包含pre-softmax激活。
    end_points: 从网络组件到相应激活的字典。
    :raise ValueError:如果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=6, 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)
Example #11
0
 def _resnet_small(self,
                   inputs,
                   num_classes=None,
                   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, global_pool,
                              output_stride, include_root_block, reuse, scope)
Example #12
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)
Example #13
0
    def _resnet_small(self,
                      inputs,
                      num_classes=None,
                      is_training=True,
                      global_pool=True,
                      output_stride=None,
                      store_non_strided_activations=False,
                      multi_grid=None,
                      reuse=None,
                      scope='resnet_v1_small'):
        """A shallow and thin ResNet v1 for faster tests."""
        if multi_grid is None:
            multi_grid = [1, 1, 1]
        else:
            if len(multi_grid) != 3:
                raise ValueError('Expect multi_grid to have length 3.')

        block = resnet_v1_beta.resnet_v1_beta_block
        blocks = [
            block('block1', base_depth=1, num_units=3, stride=2),
            block('block2', base_depth=2, num_units=3, stride=2),
            block('block3', base_depth=4, num_units=3, stride=2),
            resnet_utils.Block('block4', resnet_v1_beta.bottleneck,
                               [{
                                   'depth': 32,
                                   'depth_bottleneck': 8,
                                   'stride': 1,
                                   'unit_rate': rate
                               } for rate in multi_grid])
        ]

        return resnet_v1_beta.resnet_v1_beta(
            inputs,
            blocks,
            num_classes=num_classes,
            is_training=is_training,
            global_pool=global_pool,
            output_stride=output_stride,
            root_block_fn=functools.partial(
                resnet_v1_beta.root_block_fn_for_beta_variant),
            store_non_strided_activations=store_non_strided_activations,
            reuse=reuse,
            scope=scope)
Example #14
0
def resnet_v1_beta_block(scope, base_depth, num_units, stride):
    """辅助函数,用于创建resnet_v1 beta变量的瓶颈块

    Args:
    :param scope:块的范围
    :param base_depth:对于每个单元的瓶颈层的深度
    :param num_units:块中的单元数量
    :param stride:该块的步幅,作为最后一个单元的步幅实现。 所有其他单位的步幅= 1。
    :return:一个resnet_v1 瓶颈块
    """
    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,
        'unit_rate': 1
    }])
def resnet_v2_block(scope, base_depth, num_units, stride):
    """Helper function for creating a resnet_v2 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_v2 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
    }])
def resnet_rcnn(features, num_classes):
    resnet_arg_scope = resnet_utils.resnet_arg_scope(batch_norm_epsilon=1e-5,
                                                     batch_norm_scale=True,
                                                     weight_decay=5e-4)
    with slim.arg_scope(resnet_arg_scope):
        with slim.arg_scope([slim.batch_norm], is_training=True):
            blocks = [
                resnet_utils.Block('block4', resnet_v1.bottleneck,
                                   [{
                                       'depth': 2048,
                                       'depth_bottleneck': 512,
                                       'stride': 1
                                   }] * 3)
            ]
            net = resnet_utils.stack_blocks_dense(features, blocks)
    flat = tf.layers.flatten(net)
    cls_score = tf.layers.dense(flat, units=(num_classes + 1))

    reg_score = tf.layers.dense(flat, units=(num_classes * 4))

    cls_probs = tf.nn.softmax(cls_score)

    return cls_score, cls_probs, reg_score
Example #17
0
    def _build_tail(self, inputs, is_training=False):
        if not self._use_tail:
            return inputs

        if self._architecture == "resnet_v1_101":
            train_batch_norm = is_training and self._config.get(
                "train_batch_norm")
            with self._enter_variable_scope():
                weight_decay = self._config.get("arg_scope",
                                                {}).get("weight_decay", 0)
                with tf.variable_scope(self._architecture, reuse=True):
                    resnet_arg_scope = resnet_utils.resnet_arg_scope(
                        batch_norm_epsilon=1e-5,
                        batch_norm_scale=True,
                        weight_decay=weight_decay,
                    )
                    with slim.arg_scope(resnet_arg_scope):
                        with slim.arg_scope([slim.batch_norm],
                                            is_training=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(
                                    inputs, blocks))
        else:
            proposal_classifier_features = inputs

        return proposal_classifier_features
Example #18
0
 def _resnet_small_lite_bottleneck(self,
                                   inputs,
                                   num_classes=None,
                                   is_training=True,
                                   global_pool=True,
                                   output_stride=None,
                                   multi_grid=None,
                                   reuse=None,
                                   scope='resnet_v1_small'):
   """A shallow and thin ResNet v1 with lite_bottleneck."""
   if multi_grid is None:
     multi_grid = [1, 1]
   else:
     if len(multi_grid) != 2:
       raise ValueError('Expect multi_grid to have length 2.')
   block = resnet_v1_beta.resnet_v1_small_beta_block
   blocks = [
       block('block1', base_depth=1, num_units=1, stride=2),
       block('block2', base_depth=2, num_units=1, stride=2),
       block('block3', base_depth=4, num_units=1, stride=2),
       resnet_utils.Block('block4', resnet_v1_beta.lite_bottleneck, [
           {'depth': 8,
            'stride': 1,
            'unit_rate': rate} for rate in multi_grid])]
   return resnet_v1_beta.resnet_v1_beta(
       inputs,
       blocks,
       num_classes=num_classes,
       is_training=is_training,
       global_pool=global_pool,
       output_stride=output_stride,
       root_block_fn=functools.partial(
           resnet_v1_beta.root_block_fn_for_beta_variant,
           depth_multiplier=0.25),
       reuse=reuse,
       scope=scope)
Example #19
0
def resnet_tiny (X, scope=None, reuse=True):
    blocks = [ 
        resnet_utils.Block('block1', resnet_v1.bottleneck,
                           [(64, 32, 1)] + [(64, 32, 2)]),
        resnet_utils.Block('block2', resnet_v1.bottleneck,
                           [(128, 64, 1)] + [(128, 64, 2)]),
        resnet_utils.Block('block3', resnet_v1.bottleneck,
                           [(256, 64, 1)]  + [(128, 64, 2)]),
        resnet_utils.Block('block4', resnet_v1.bottleneck,
                           [(256, 64, 1)]  + [(128, 64, 2)]),
        resnet_utils.Block('block5', resnet_v1.bottleneck,
                           [(256, 64, 1)]  + [(128, 64, 2)]),
        resnet_utils.Block('block6', resnet_v1.bottleneck, [(128, 64, 1)])
    	]   
    net,_ = resnet_v1.resnet_v1(
        X, blocks,
        # all parameters below can be passed to resnet_v1.resnet_v1_??
        num_classes = 2,       # don't produce final prediction
        global_pool = True,       # produce 1x1 output, equivalent to input of a FC layer
        reuse=reuse,              # do not re-use network
        scope=scope)
    return net
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'):
    """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.

    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)
def resnet_v1_101(inputs,
                  num_classes=None,
                  is_training=None,
                  global_pool=False,
                  output_stride=None,
                  store_non_strided_activations=False,
                  multi_grid=None,
                  use_bounded_activations=False,
                  reuse=None,
                  scope='resnet_v1_101'):
    """Resnet v1 101.

    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.
      store_non_strided_activations: If True, we compute non-strided (undecimated)
        activations at the last unit of each block and store them in the
        `outputs_collections` before subsampling them. This gives us access to
        higher resolution intermediate activations which are useful in some
        dense prediction problems but increases 4x the computation and memory cost
        at the last unit of each block.
      multi_grid: Employ a hierarchy of different atrous rates within network.
      use_bounded_activations: Whether or not to use bounded activations. Bounded
        activations better lend themselves to quantized inference.
      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.

    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,
        store_non_strided_activations=store_non_strided_activations,
        reuse=reuse,
        scope=scope,
        use_bounded_activations=use_bounded_activations)
Example #22
0
def resnet_v1_slim(
    inputs,
    num_classes=None,
    global_pool=True,
    output_stride=None,
    reuse=None,  # the above parameters will be directly passed to
    # resnet.resnet_v1
    scope='resnet_v1_slim'):
    blocks = [
        resnet_utils.Block('block1', resnet_v1.bottleneck,
                           [(64, 32, 1)] * 2 + [(64, 32, 2)]),
        # the last argument of Block is a list of "bottleneck" unit
        # configurations. Each entry is of the form  [depth, in-depth, stride]
        # Each "bottleneck" unit consists 3 layers:
        #    convolution from depth channels to in-depth channels
        #    convolution from in-depth channels to in-depth channels
        #    convolution from in-depth channels to depth channels
        # It's called "bottleneck" because the overall input and output
        # depth (# channels) are the same, while the in-depth in the
        # middle is smaller.

        # Because each bottleneck has 3 layers, the above chain has
        # 3 * (2 + 1) = 9 layers.

        # By convention alll bottleneck units have stride = 1 except for the last which has
        # stride of 2.  The overall effect is after the whole chain, image size
        # is reduced by 2.

        # The original resnet implementation has:
        #   -- very long chains
        #   -- very large depth and in-depth values.
        # This is necessary for very big datasets like ImageNet, but for
        # smaller and simpler datasets we should be able to substantially
        # reduce these, as is what we do in this resnet_slim
        #
        resnet_utils.Block('block2', resnet_v1.bottleneck,
                           [(128, 64, 1)] * 4 + [(128, 64, 2)]),
        # 3 * (4+1) = 15 layers
        resnet_utils.Block('block3', resnet_v1.bottleneck,
                           [(256, 64, 1)] * 4 + [(256, 64, 2)]),
        # 3 * (4+1) = 15 layers
        resnet_utils.Block('block4', resnet_v1.bottleneck, [(256, 64, 1)] * 2)
        # 3 * 2 = 6 layers
        # so we have  9 + 15 + 15 + 6 = 45 layers
        # there are two extra layers added by the system, so
        # by the reset nomenclature this network can be called a reset_v1_47

        # The first 3 Blocks each have stride = 2, and last Block is 1,
        # so the overall stride of this architecture is 8

        # If "output_stride" is smaller than 8, resnet_v1.resnet_v1
        # will add extra down-sizing layers to meet the requirement.
    ]
    return resnet_v1.resnet_v1(inputs,
                               blocks,
                               num_classes,
                               global_pool,
                               output_stride,
                               include_root_block=True,
                               reuse=reuse,
                               scope=scope)
Example #23
0
def resnet_v1_18(inputs,
                 num_classes=None,
                 is_training=None,
                 global_pool=False,
                 output_stride=None,
                 multi_grid=None,
                 reuse=None,
                 scope='resnet_v1_18',
                 sync_batch_norm_method='None'):
    """Resnet v1 18.

  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_RESNET_18
    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_v1_small_beta_block('block1',
                                   base_depth=64,
                                   num_units=2,
                                   stride=2),
        resnet_v1_small_beta_block('block2',
                                   base_depth=128,
                                   num_units=2,
                                   stride=2),
        resnet_v1_small_beta_block('block3',
                                   base_depth=256,
                                   num_units=2,
                                   stride=2),
        resnet_utils.Block('block4', lite_bottleneck, block4_args),
    ]
    return resnet_v1_beta(inputs,
                          blocks=blocks,
                          num_classes=num_classes,
                          is_training=is_training,
                          global_pool=global_pool,
                          output_stride=output_stride,
                          reuse=reuse,
                          scope=scope,
                          sync_batch_norm_method=sync_batch_norm_method)
Example #24
0
  def build_network(self, sess, is_training=True):
    # select initializers
    if cfg.TRAIN.TRUNCATED:
      initializer = tf.truncated_normal_initializer(mean=0.0, stddev=0.01)
      initializer_bbox = tf.truncated_normal_initializer(mean=0.0, stddev=0.001)
    else:
      initializer = tf.random_normal_initializer(mean=0.0, stddev=0.01)
      initializer_bbox = tf.random_normal_initializer(mean=0.0, stddev=0.001)
    bottleneck = resnet_v1.bottleneck
    blocks = [
      resnet_utils.Block('block1', bottleneck,
                         [(256, 64, 1)] * 2 + [(256, 64, 2)]),
      resnet_utils.Block('block2', bottleneck,
                         [(512, 128, 1)] * 3 + [(512, 128, 2)]),
      resnet_utils.Block('block3', bottleneck,
                         [(1024, 256, 1)] * 22 + [(1024, 256, 1)]),
      resnet_utils.Block('block4', bottleneck, [(2048, 512, 1)] * 3)
    ]
    if cfg.RESNET.FIXED_BLOCKS > 0:
      with slim.arg_scope(resnet_arg_scope(is_training=False)):
        net, _ = resnet_v1.resnet_v1(self._image,
                                              blocks[0:cfg.RESNET.FIXED_BLOCKS],
                                              global_pool=False,
                                              include_root_block=True,
                                              scope='resnet_v1_101')
      with slim.arg_scope(resnet_arg_scope(is_training=is_training)):
        net_conv5, _ = resnet_v1.resnet_v1(net,
                                              blocks[cfg.RESNET.FIXED_BLOCKS:-1],
                                              global_pool=False,
                                              include_root_block=False,
                                              scope='resnet_v1_101')
    else:
      with slim.arg_scope(resnet_arg_scope(is_training=is_training)):
        net_conv5, _ = resnet_v1.resnet_v1(self._image,
                                              blocks[0:-1],
                                              global_pool=False,
                                              include_root_block=True,
                                              scope='resnet_v1_101')

    self._act_summaries.append(net_conv5)
    self._layers['conv5_3'] = net_conv5
    with tf.variable_scope('resnet_v1_101', 'resnet_v1_101',
                           regularizer=tf.contrib.layers.l2_regularizer(cfg.TRAIN.WEIGHT_DECAY)):
      # build the anchors for the image
      self._anchor_component()

      # rpn
      rpn = slim.conv2d(net_conv5, 512, [3, 3], trainable=is_training, weights_initializer=initializer,
                        scope="rpn_conv/3x3")
      self._act_summaries.append(rpn)
      rpn_cls_score = slim.conv2d(rpn, self._num_scales * 6, [1, 1], trainable=is_training,
                                  weights_initializer=initializer,
                                  padding='VALID', activation_fn=None, scope='rpn_cls_score')
      # change it so that the score has 2 as its channel size
      rpn_cls_score_reshape = self._reshape_layer(rpn_cls_score, 2, 'rpn_cls_score_reshape')
      rpn_cls_prob_reshape = self._softmax_layer(rpn_cls_score_reshape, "rpn_cls_prob_reshape")
      rpn_cls_prob = self._reshape_layer(rpn_cls_prob_reshape, self._num_scales * 6, "rpn_cls_prob")
      rpn_bbox_pred = slim.conv2d(rpn, self._num_scales * 12, [1, 1], trainable=is_training,
                                  weights_initializer=initializer,
                                  padding='VALID', activation_fn=None, scope='rpn_bbox_pred')
      if is_training:
        rois, roi_scores = self._proposal_layer(rpn_cls_prob, rpn_bbox_pred, "rois")
        rpn_labels = self._anchor_target_layer(rpn_cls_score, "anchor")
        # Try to have a determinestic order for the computing graph, for reproducibility
        with tf.control_dependencies([rpn_labels]):
          rois, _ = self._proposal_target_layer(rois, roi_scores, "rpn_rois")
      else:
        if cfg.TEST.MODE == 'nms':
          rois, _ = self._proposal_layer(rpn_cls_prob, rpn_bbox_pred, "rois")
        elif cfg.TEST.MODE == 'top':
          rois, _ = self._proposal_top_layer(rpn_cls_prob, rpn_bbox_pred, "rois")
        else:
          raise NotImplementedError

      # rcnn
      if cfg.POOLING_MODE == 'crop':
        pool5 = self._crop_pool_layer(net_conv5, rois, "pool5")
      else:
        raise NotImplementedError

    with slim.arg_scope(resnet_arg_scope(is_training=is_training)):
      fc7, _ = resnet_v1.resnet_v1(pool5,
                                    blocks[-1:],
                                    global_pool=False,
                                    include_root_block=False,
                                    scope='resnet_v1_101')
    with tf.variable_scope('resnet_v1_101', 'resnet_v1_101',
                           regularizer=tf.contrib.layers.l2_regularizer(cfg.TRAIN.WEIGHT_DECAY)):
      # Average pooling done by reduce_mean
      fc7 = tf.reduce_mean(fc7, axis=[1,2])
      cls_score = slim.fully_connected(fc7, self._num_classes, weights_initializer=initializer, trainable=is_training,
                              activation_fn=None, scope='cls_score')
      cls_prob = self._softmax_layer(cls_score, "cls_prob")
      bbox_pred = slim.fully_connected(fc7, self._num_classes * 4, weights_initializer=initializer_bbox,
                              trainable=is_training, 
                              activation_fn=None, scope='bbox_pred')
    self._predictions["rpn_cls_score"] = rpn_cls_score
    self._predictions["rpn_cls_score_reshape"] = rpn_cls_score_reshape
    self._predictions["rpn_cls_prob"] = rpn_cls_prob
    self._predictions["rpn_bbox_pred"] = rpn_bbox_pred
    self._predictions["cls_score"] = cls_score
    self._predictions["cls_prob"] = cls_prob
    self._predictions["bbox_pred"] = bbox_pred
    self._predictions["rois"] = rois

    self._score_summaries.update(self._predictions)

    return rois, cls_prob, bbox_pred