def test_batch_norm(self, is_training, strategy):
        inputs = tf.random.uniform([8, 40, 40, 3])
        expect_results = utils.batch_norm_act(inputs, is_training, None)

        # Call batch norm layer with is_training parameter.
        bn_layer = utils_keras.build_batch_norm(is_training, strategy=strategy)
        self.assertAllClose(expect_results, bn_layer(inputs, is_training))
Example #2
0
def box_net(images,
            level,
            num_anchors,
            num_filters,
            is_training,
            act_type,
            repeats=4,
            separable_conv=True,
            survival_prob=None,
            strategy=None,
            data_format='channels_last'):
  """Box regression network."""
  if separable_conv:
    conv_op = functools.partial(
        tf.layers.separable_conv2d, depth_multiplier=1,
        data_format=data_format,
        pointwise_initializer=tf.initializers.variance_scaling(),
        depthwise_initializer=tf.initializers.variance_scaling())
  else:
    conv_op = functools.partial(
        tf.layers.conv2d,
        data_format=data_format,
        kernel_initializer=tf.random_normal_initializer(stddev=0.01))

  for i in range(repeats):
    orig_images = images
    images = conv_op(
        images,
        num_filters,
        kernel_size=3,
        activation=None,
        bias_initializer=tf.zeros_initializer(),
        padding='same',
        name='box-%d' % i)
    images = utils.batch_norm_act(
        images,
        is_training,
        act_type=act_type,
        init_zero=False,
        strategy=strategy,
        data_format=data_format,
        name='box-%d-bn-%d' % (i, level))

    if i > 0 and survival_prob:
      images = utils.drop_connect(images, is_training, survival_prob)
      images = images + orig_images

  boxes = conv_op(
      images,
      4 * num_anchors,
      kernel_size=3,
      bias_initializer=tf.zeros_initializer(),
      padding='same',
      name='box-predict')

  return boxes
Example #3
0
 def test_batchnorm_compatibility(self):
     x = tf.Variable(tf.ones((4, 1, 1, 1)) * [[1.0], [2.0], [4.0], [8.0]])
     for act_type in ['swish', 'swish_native', 'relu', 'relu6']:
         bna = utils_keras.BatchNormAct(is_training_bn=False,
                                        act_type=act_type)
         self.assertEqual(
             tf.reduce_sum(
                 utils.batch_norm_act(x,
                                      is_training_bn=False,
                                      act_type=act_type).numpy()),
             tf.reduce_sum(bna.call(x).numpy()))
Example #4
0
 def _maybe_apply_1x1(feat):
     """Apply 1x1 conv to change layer width if necessary."""
     if num_channels != target_num_channels:
         feat = tf.keras.layers.Conv2D(feat,
                                       filters=target_num_channels,
                                       kernel_size=(1, 1),
                                       padding='same')
         feat = utils.batch_norm_act(feat,
                                     is_training_bn=is_training,
                                     act_type=None,
                                     name='bn')
     return feat
 def _maybe_apply_1x1(self, feat):
     """Apply 1x1 conv to change layer width if necessary."""
     if self.num_channels != self.target_num_channels:
         feat = self.conv2d(feat)
         if self.apply_bn:
             feat = utils.batch_norm_act(feat,
                                         is_training_bn=self.is_training,
                                         act_type=None,
                                         data_format=self.data_format,
                                         use_tpu=self.use_tpu,
                                         name='bn')
     return feat
Example #6
0
def class_net(images,
              level,
              num_classes,
              num_anchors,
              num_filters,
              is_training,
              act_type,
              separable_conv=True,
              repeats=4,
              survival_prob=None,
              use_tpu=False):
    """Class prediction network."""
    if separable_conv:
        conv_op = functools.partial(
            tf.layers.separable_conv2d,
            depth_multiplier=1,
            pointwise_initializer=tf.initializers.variance_scaling(),
            depthwise_initializer=tf.initializers.variance_scaling())
    else:
        conv_op = functools.partial(
            tf.layers.conv2d,
            kernel_initializer=tf.random_normal_initializer(stddev=0.01))

    for i in range(repeats):
        orig_images = images
        images = conv_op(images,
                         num_filters,
                         kernel_size=3,
                         bias_initializer=tf.zeros_initializer(),
                         activation=None,
                         padding='same',
                         name='class-%d' % i)
        images = utils.batch_norm_act(images,
                                      is_training,
                                      act_type=act_type,
                                      init_zero=False,
                                      use_tpu=use_tpu,
                                      name='class-%d-bn-%d' % (i, level))

        if i > 0 and survival_prob:
            images = utils.drop_connect(images, is_training, survival_prob)
            images = images + orig_images

    classes = conv_op(
        images,
        num_classes * num_anchors,
        kernel_size=3,
        bias_initializer=tf.constant_initializer(-np.log((1 - 0.01) / 0.01)),
        padding='same',
        name='class-predict')
    return classes
Example #7
0
 def _maybe_apply_1x1(feat):
     """Apply 1x1 conv to change layer width if necessary."""
     if num_channels != target_num_channels:
         feat = tf.layers.conv2d(feat,
                                 filters=target_num_channels,
                                 kernel_size=(1, 1),
                                 padding='same')
         if apply_bn:
             feat = utils.batch_norm_act(feat,
                                         is_training_bn=is_training,
                                         act_type=None,
                                         data_format='channels_last',
                                         use_tpu=use_tpu,
                                         name='bn')
     return feat
Example #8
0
def box_net(images,
            level,
            num_anchors,
            num_filters,
            is_training,
            act_type,
            repeats=4,
            separable_conv=True,
            survival_prob=None):
    """Box regression network."""

    for i in range(repeats):
        orig_images = images
        images = tf.keras.layers.SeparableConv2D(
            images,
            num_filters,
            kernel_size=3,
            activation=None,
            bias_initializer=tf.zeros_initializer(),
            padding='same',
            name='box-%d' % i,
            depth_multiplier=1,
            pointwise_initializer=tf.keras.initializers.VarianceScaling(),
            depthwise_initializer=tf.keras.initializers.VarianceScaling())
        images = utils.batch_norm_act(images,
                                      is_training,
                                      act_type=act_type,
                                      init_zero=False,
                                      name='box-%d-bn-%d' % (i, level))

        if i > 0 and survival_prob:
            images = utils.drop_connect(images, is_training, survival_prob)
            images = images + orig_images

    boxes = tf.keras.layers.SeparableConv2D(
        images,
        4 * num_anchors,
        kernel_size=3,
        bias_initializer=tf.zeros_initializer(),
        padding='same',
        name='box-predict',
        depth_multiplier=1,
        pointwise_initializer=tf.keras.initializers.VarianceScaling(),
        depthwise_initializer=tf.keras.initializers.VarianceScaling())

    return boxes
Example #9
0
def class_net(images,
              level,
              num_classes,
              num_anchors,
              num_filters,
              is_training,
              act_type,
              repeats=4,
              survival_prob=None):
    """Class prediction network."""

    for i in range(repeats):
        orig_images = images
        images = tf.keras.layers.SeparableConv2D(
            images,
            num_filters,
            kernel_size=3,
            bias_initializer=tf.keras.initializers.zeros(),
            activation=None,
            padding='same',
            name='class-%d' % i,
            depth_multiplier=1,
            pointwise_initializer=tf.keras.initializers.VarianceScaling(),
            depthwise_initializer=tf.keras.initializers.VarianceScaling())
        images = utils.batch_norm_act(images,
                                      is_training,
                                      act_type=act_type,
                                      init_zero=False,
                                      name='class-%d-bn-%d' % (i, level))

        if i > 0 and survival_prob:
            images = utils.drop_connect(images, is_training, survival_prob)
            images = images + orig_images

    classes = tf.keras.layers.SeparableConv2D(
        images,
        num_classes * num_anchors,
        kernel_size=3,
        bias_initializer=tf.keras.initializers.Constant(-np.log((1 - 0.01) /
                                                                0.01)),
        padding='same',
        name='class-predict',
        depth_multiplier=1,
        pointwise_initializer=tf.keras.initializers.VarianceScaling(),
        depthwise_initializer=tf.keras.initializers.VarianceScaling())
    return classes
Example #10
0
def build_bifpn_layer(feats, feat_sizes, config):
    """Builds a feature pyramid given previous feature pyramid and config."""
    p = config  # use p to denote the network config.
    if p.fpn_config:
        fpn_config = p.fpn_config
    else:
        fpn_config = fpn_configs.get_fpn_config(p.fpn_name, p.min_level,
                                                p.max_level,
                                                p.fpn_weight_method)

    num_output_connections = [0 for _ in feats]
    for i, fnode in enumerate(fpn_config.nodes):
        with tf.variable_scope('fnode{}'.format(i)):
            logging.info('fnode %d : %s', i, fnode)
            new_node_height = feat_sizes[fnode['feat_level']]['height']
            new_node_width = feat_sizes[fnode['feat_level']]['width']
            nodes = []
            for idx, input_offset in enumerate(fnode['inputs_offsets']):
                input_node = feats[input_offset]
                num_output_connections[input_offset] += 1
                input_node = resample_feature_map(
                    input_node,
                    '{}_{}_{}'.format(idx, input_offset, len(feats)),
                    new_node_height,
                    new_node_width,
                    p.fpn_num_filters,
                    p.apply_bn_for_resampling,
                    p.is_training_bn,
                    p.conv_after_downsample,
                    strategy=p.strategy,
                    data_format=config.data_format)
                nodes.append(input_node)

            new_node = fuse_features(nodes, fpn_config.weight_method)

            with tf.variable_scope('op_after_combine{}'.format(len(feats))):
                if not p.conv_bn_act_pattern:
                    new_node = utils.activation_fn(new_node, p.act_type)

                if p.separable_conv:
                    conv_op = functools.partial(tf.layers.separable_conv2d,
                                                depth_multiplier=1)
                else:
                    conv_op = tf.layers.conv2d

                new_node = conv_op(new_node,
                                   filters=p.fpn_num_filters,
                                   kernel_size=(3, 3),
                                   padding='same',
                                   use_bias=not p.conv_bn_act_pattern,
                                   data_format=config.data_format,
                                   name='conv')

                new_node = utils.batch_norm_act(
                    new_node,
                    is_training_bn=p.is_training_bn,
                    act_type=None if not p.conv_bn_act_pattern else p.act_type,
                    data_format=config.data_format,
                    strategy=p.strategy,
                    name='bn')

            feats.append(new_node)
            num_output_connections.append(0)

    output_feats = {}
    for l in range(p.min_level, p.max_level + 1):
        for i, fnode in enumerate(reversed(fpn_config.nodes)):
            if fnode['feat_level'] == l:
                output_feats[l] = feats[-1 - i]
                break
    return output_feats
Example #11
0
def build_bifpn_layer(feats, feat_sizes, config):
  """Builds a feature pyramid given previous feature pyramid and config."""
  p = config  # use p to denote the network config.
  if p.fpn_config:
    fpn_config = p.fpn_config
  else:
    fpn_config = get_fpn_config(p.fpn_name, p.min_level, p.max_level,
                                p.fpn_weight_method)

  num_output_connections = [0 for _ in feats]
  for i, fnode in enumerate(fpn_config.nodes):
    with tf.variable_scope('fnode{}'.format(i)):
      logging.info('fnode %d : %s', i, fnode)
      new_node_height = feat_sizes[fnode['feat_level']]['height']
      new_node_width = feat_sizes[fnode['feat_level']]['width']
      nodes = []
      for idx, input_offset in enumerate(fnode['inputs_offsets']):
        input_node = feats[input_offset]
        num_output_connections[input_offset] += 1
        input_node = resample_feature_map(
            input_node, '{}_{}_{}'.format(idx, input_offset, len(feats)),
            new_node_height, new_node_width, p.fpn_num_filters,
            p.apply_bn_for_resampling, p.is_training_bn,
            p.conv_after_downsample,
            p.use_native_resize_op,
            p.pooling_type,
            data_format=config.data_format)
        nodes.append(input_node)

      # Combine all nodes.
      dtype = nodes[0].dtype
      if fpn_config.weight_method == 'attn':
        edge_weights = [tf.cast(tf.Variable(1.0, name='WSM'), dtype=dtype)
                        for _ in range(len(fnode['inputs_offsets']))]
        normalized_weights = tf.nn.softmax(tf.stack(edge_weights))
        nodes = tf.stack(nodes, axis=-1)
        new_node = tf.reduce_sum(tf.multiply(nodes, normalized_weights), -1)
      elif fpn_config.weight_method == 'fastattn':
        edge_weights = [
            tf.nn.relu(tf.cast(tf.Variable(1.0, name='WSM'), dtype=dtype))
            for _ in range(len(fnode['inputs_offsets']))
        ]
        weights_sum = tf.add_n(edge_weights)
        nodes = [nodes[i] * edge_weights[i] / (weights_sum + 0.0001)
                 for i in range(len(nodes))]
        new_node = tf.add_n(nodes)
      elif fpn_config.weight_method == 'sum':
        new_node = tf.add_n(nodes)
      else:
        raise ValueError(
            'unknown weight_method {}'.format(fpn_config.weight_method))

      with tf.variable_scope('op_after_combine{}'.format(len(feats))):
        if not p.conv_bn_act_pattern:
          new_node = utils.activation_fn(new_node, p.act_type)

        if p.separable_conv:
          conv_op = functools.partial(
              tf.layers.separable_conv2d, depth_multiplier=1)
        else:
          conv_op = tf.layers.conv2d

        new_node = conv_op(
            new_node,
            filters=p.fpn_num_filters,
            kernel_size=(3, 3),
            padding='same',
            use_bias=True if not p.conv_bn_act_pattern else False,
            data_format=config.data_format,
            name='conv')

        new_node = utils.batch_norm_act(
            new_node,
            is_training_bn=p.is_training_bn,
            act_type=None if not p.conv_bn_act_pattern else p.act_type,
            data_format=config.data_format,
            use_tpu=p.use_tpu,
            name='bn')

      feats.append(new_node)
      num_output_connections.append(0)

  output_feats = {}
  for l in range(p.min_level, p.max_level + 1):
    for i, fnode in enumerate(reversed(fpn_config.nodes)):
      if fnode['feat_level'] == l:
        output_feats[l] = feats[-1 - i]
        break
  return output_feats