Пример #1
0
 def testAtrousFullyConvolutionalValues(self):
     """Verify dense feature extraction with atrous convolution."""
     nominal_stride = 32
     for output_stride in [4, 8, 16, 32, None]:
         with arg_scope(resnet_utils.resnet_arg_scope()):
             with ops.Graph().as_default():
                 with self.cached_session() as sess:
                     random_seed.set_random_seed(0)
                     inputs = create_test_input(2, 81, 81, 3)
                     # Dense feature extraction followed by subsampling.
                     output, _ = self._resnet_small(
                         inputs,
                         None,
                         is_training=False,
                         global_pool=False,
                         output_stride=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.
                     variable_scope.get_variable_scope().reuse_variables()
                     # Feature extraction at the nominal network rate.
                     expected, _ = self._resnet_small(inputs,
                                                      None,
                                                      is_training=False,
                                                      global_pool=False)
                     sess.run(variables.global_variables_initializer())
                     self.assertAllClose(output.eval(),
                                         expected.eval(),
                                         atol=2e-4,
                                         rtol=1e-4)
Пример #2
0
 def testAtrousFullyConvolutionalValues(self):
   """Verify dense feature extraction with atrous convolution."""
   nominal_stride = 32
   for output_stride in [4, 8, 16, 32, None]:
     with arg_scope(resnet_utils.resnet_arg_scope()):
       with ops.Graph().as_default():
         with self.test_session() as sess:
           random_seed.set_random_seed(0)
           inputs = create_test_input(2, 81, 81, 3)
           # Dense feature extraction followed by subsampling.
           output, _ = self._resnet_small(
               inputs,
               None,
               is_training=False,
               global_pool=False,
               output_stride=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.
           variable_scope.get_variable_scope().reuse_variables()
           # Feature extraction at the nominal network rate.
           expected, _ = self._resnet_small(
               inputs, None, is_training=False, global_pool=False)
           sess.run(variables.global_variables_initializer())
           self.assertAllClose(
               output.eval(), expected.eval(), atol=1e-4, rtol=1e-4)
Пример #3
0
 def testSubsampleFourByFour(self):
   x = array_ops.reshape(math_ops.to_float(math_ops.range(16)), [1, 4, 4, 1])
   x = resnet_utils.subsample(x, 2)
   expected = array_ops.reshape(
       constant_op.constant([0, 2, 8, 10]), [1, 2, 2, 1])
   with self.test_session():
     self.assertAllClose(x.eval(), expected.eval())
Пример #4
0
 def testSubsampleThreeByThree(self):
   x = array_ops.reshape(math_ops.to_float(math_ops.range(9)), [1, 3, 3, 1])
   x = resnet_utils.subsample(x, 2)
   expected = array_ops.reshape(
       constant_op.constant([0, 2, 6, 8]), [1, 2, 2, 1])
   with self.test_session():
     self.assertAllClose(x.eval(), expected.eval())
Пример #5
0
def bottleneck(inputs,
               depth,
               depth_bottleneck,
               stride,
               rate=1,
               outputs_collections=None,
               scope=None):
    """Bottleneck residual unit variant with BN after convolutions.

  This is the original residual unit proposed in [1]. See Fig. 1(a) of [2] for
  its definition. Note that we use here the bottleneck variant which has an
  extra bottleneck layer.

  When putting together two consecutive ResNet blocks that use this unit, one
  should use stride = 2 in the last unit of the first block.

  Args:
    inputs: A tensor of size [batch, height, width, channels].
    depth: The depth of the ResNet unit output.
    depth_bottleneck: The depth of the bottleneck layers.
    stride: The ResNet unit's stride. Determines the amount of downsampling of
      the units output compared to its input.
    rate: An integer, rate for atrous convolution.
    outputs_collections: Collection to add the ResNet unit output.
    scope: Optional variable_scope.

  Returns:
    The ResNet unit's output.
  """
    with variable_scope.variable_scope(scope, 'bottleneck_v1', [inputs]) as sc:
        depth_in = utils.last_dimension(inputs.get_shape(), min_rank=4)
        if depth == depth_in:
            shortcut = resnet_utils.subsample(inputs, stride, 'shortcut')
        else:
            shortcut = layers.conv2d(inputs,
                                     depth, [1, 1],
                                     stride=stride,
                                     activation_fn=None,
                                     scope='shortcut')

        residual = layers.conv2d(inputs,
                                 depth_bottleneck, [1, 1],
                                 stride=1,
                                 scope='conv1')
        residual = resnet_utils.conv2d_same(residual,
                                            depth_bottleneck,
                                            3,
                                            stride,
                                            rate=rate,
                                            scope='conv2')
        residual = layers.conv2d(residual,
                                 depth, [1, 1],
                                 stride=1,
                                 activation_fn=None,
                                 scope='conv3')

        output = nn_ops.relu(shortcut + residual)

        return utils.collect_named_outputs(outputs_collections, sc.name,
                                           output)
def bottleneck_hole(inputs,
               depth,
               depth_bottleneck,
               stride,
               rate=2,
               outputs_collections=None,
               scope=None):
  with variable_scope.variable_scope(scope, 'bottleneck_v1', [inputs]) as sc:
    depth_in = utils.last_dimension(inputs.get_shape(), min_rank=4)
    if depth == depth_in:
      shortcut = resnet_utils.subsample(inputs, stride, 'shortcut')
    else:
      shortcut = layers.conv2d(
          inputs,
          depth, [1, 1],
          stride=stride,
          activation_fn=None,
          scope='shortcut')

    residual = layers.conv2d(
        inputs, depth_bottleneck, [1, 1], stride=1, scope='conv1')
    residual = layers_lib.conv2d(residual, depth_bottleneck, [3, 3], stride=1, rate=rate, padding='SAME', scope='conv2')
    residual = layers.conv2d(
        residual, depth, [1, 1], stride=1, activation_fn=None, scope='conv3')

    output = nn_ops.relu(shortcut + residual)

    return utils.collect_named_outputs(outputs_collections, sc.name, output)
Пример #7
0
 def testSubsampleFourByFour(self):
   x = array_ops.reshape(math_ops.to_float(math_ops.range(16)), [1, 4, 4, 1])
   x = resnet_utils.subsample(x, 2)
   expected = array_ops.reshape(
       constant_op.constant([0, 2, 8, 10]), [1, 2, 2, 1])
   with self.test_session():
     self.assertAllClose(x.eval(), expected.eval())
def bottleneck_hole(inputs,
               depth,
               depth_bottleneck,
               stride,
               rate=2,
               outputs_collections=None,
               scope=None):
  with variable_scope.variable_scope(scope, 'bottleneck_v1', [inputs]) as sc:
    depth_in = utils.last_dimension(inputs.get_shape(), min_rank=4)
    if depth == depth_in:
      shortcut = resnet_utils.subsample(inputs, stride, 'shortcut')
    else:
      shortcut = layers.conv2d(
          inputs,
          depth, [1, 1],
          stride=stride,
          activation_fn=None,
          scope='shortcut')

    residual = layers.conv2d(
        inputs, depth_bottleneck, [1, 1], stride=1, scope='conv1')
    residual = layers_lib.conv2d(residual, depth_bottleneck, [3, 3], stride=1, rate=rate, padding='SAME', scope='conv2')
    residual = layers.conv2d(
        residual, depth, [1, 1], stride=1, activation_fn=None, scope='conv3')

    output = nn_ops.relu(shortcut + residual)

    return utils.collect_named_outputs(outputs_collections, sc.name, output)
Пример #9
0
 def testSubsampleThreeByThree(self):
   x = array_ops.reshape(math_ops.to_float(math_ops.range(9)), [1, 3, 3, 1])
   x = resnet_utils.subsample(x, 2)
   expected = array_ops.reshape(
       constant_op.constant([0, 2, 6, 8]), [1, 2, 2, 1])
   with self.test_session():
     self.assertAllClose(x.eval(), expected.eval())
Пример #10
0
def bottleneck(inputs,
               depth,
               depth_bottleneck,
               stride,
               rate=1,
               outputs_collections=None,
               scope=None):
  """Bottleneck residual unit variant with BN before convolutions.

  This is the full preactivation residual unit variant proposed in [2]. See
  Fig. 1(b) of [2] for its definition. Note that we use here the bottleneck
  variant which has an extra bottleneck layer.

  When putting together two consecutive ResNet blocks that use this unit, one
  should use stride = 2 in the last unit of the first block.

  Args:
    inputs: A tensor of size [batch, height, width, channels].
    depth: The depth of the ResNet unit output.
    depth_bottleneck: The depth of the bottleneck layers.
    stride: The ResNet unit's stride. Determines the amount of downsampling of
      the units output compared to its input.
    rate: An integer, rate for atrous convolution.
    outputs_collections: Collection to add the ResNet unit output.
    scope: Optional variable_scope.

  Returns:
    The ResNet unit's output.
  """
  with variable_scope.variable_scope(scope, 'bottleneck_v2', [inputs]) as sc:
    depth_in = utils.last_dimension(inputs.get_shape(), min_rank=4)
    preact = layers.batch_norm(
        inputs, activation_fn=nn_ops.relu, scope='preact')
    if depth == depth_in:
      shortcut = resnet_utils.subsample(inputs, stride, 'shortcut')
    else:
      shortcut = layers_lib.conv2d(
          preact,
          depth, [1, 1],
          stride=stride,
          normalizer_fn=None,
          activation_fn=None,
          scope='shortcut')

    residual = layers_lib.conv2d(
        preact, depth_bottleneck, [1, 1], stride=1, scope='conv1')
    residual = resnet_utils.conv2d_same(
        residual, depth_bottleneck, 3, stride, rate=rate, scope='conv2')
    residual = layers_lib.conv2d(
        residual,
        depth, [1, 1],
        stride=1,
        normalizer_fn=None,
        activation_fn=None,
        scope='conv3')

    output = shortcut + residual

    return utils.collect_named_outputs(outputs_collections, sc.name, output)
Пример #11
0
def bottleneck(inputs, depth, depth_bottleneck, stride, rate=1, outputs_collections=None, scope=None):
    with tf.variable_scope(scope, 'bottleneck_v1', [inputs]) as sc:
        depth_in = slim.utils.last_dimension(inputs.get_shape(), min_rank=4)
        if depth == depth_in:
            shortcut = resnet_utils.subsample(inputs, stride, 'shortcut')
        else:
            shortcut = slim.conv2d(inputs, depth, [1, 1], stride=stride, activation_fn=None, scope='shortcut')
        residual = slim.conv2d(inputs, depth_bottleneck, [1, 1], stride=1, scope='conv1')
        residual = resnet_utils.conv2d_same(residual, depth_bottleneck, 3, stride, rate=rate, scope='conv2')
        residual = slim.conv2d(residual, depth, [1, 1], stride=1, activation_fn=None, scope='conv3')
        output = tf.nn.relu(shortcut + residual)

    return slim.utils.collect_named_outputs(outputs_collections, sc.original_name_scope, output)
Пример #12
0
def bottleneck(inputs, depth, depth_bottleneck, stride, rate=1, outputs_collections=None, scope=None):
    with tf.variable_scope(scope, 'bottleneck_v1', [inputs]) as sc:
        depth_in = slim.utils.last_dimension(inputs.get_shape(), min_rank=4)
        if depth == depth_in:
            shortcut = resnet_utils.subsample(inputs, stride, 'shortcut')
        else:
            shortcut = slim.conv2d(inputs, depth, [1, 1], stride=stride, activation_fn=None, scope='shortcut')
        residual = slim.conv2d(inputs, depth_bottleneck, [1, 1], stride=1, scope='conv1')
        residual = resnet_utils.conv2d_same(residual, depth_bottleneck, 3, stride, rate=rate, scope='conv2')
        residual = slim.conv2d(residual, depth, [1, 1], stride=1, activation_fn=None, scope='conv3')
        output = tf.nn.relu(shortcut + residual)

    return slim.utils.collect_named_outputs(outputs_collections, sc.original_name_scope, output)
Пример #13
0
    def testAtrousValuesBottleneck(self):
        """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.
    """
        block = resnet_v1.resnet_v1_block
        blocks = [
            block('block1', base_depth=1, num_units=2, stride=2),
            block('block2', base_depth=2, num_units=2, stride=2),
            block('block3', base_depth=4, num_units=2, stride=2),
            block('block4', base_depth=8, num_units=2, stride=1),
        ]
        nominal_stride = 8

        # Test both odd and even input dimensions.
        height = 30
        width = 31
        with arg_scope(resnet_utils.resnet_arg_scope()):
            with arg_scope([layers.batch_norm], is_training=False):
                for output_stride in [1, 2, 4, 8, None]:
                    with ops.Graph().as_default():
                        with self.cached_session() as sess:
                            random_seed.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.
                            variable_scope.get_variable_scope(
                            ).reuse_variables()
                            # Feature extraction at the nominal network rate.
                            expected = self._stack_blocks_nondense(
                                inputs, blocks)
                            sess.run(variables.global_variables_initializer())
                            output, expected = sess.run([output, expected])
                            self.assertAllClose(output,
                                                expected,
                                                atol=1e-4,
                                                rtol=1e-4)
Пример #14
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 arg_scope(resnet_utils.resnet_arg_scope(is_training=False)):
            for output_stride in [1, 2, 4, 8, None]:
                with ops.Graph().as_default():
                    with self.test_session() as sess:
                        random_seed.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.
                        variable_scope.get_variable_scope().reuse_variables()
                        # Feature extraction at the nominal network rate.
                        expected = self._stack_blocks_nondense(inputs, blocks)
                        sess.run(variables.global_variables_initializer())
                        output, expected = sess.run([output, expected])
                        self.assertAllClose(output,
                                            expected,
                                            atol=1e-4,
                                            rtol=1e-4)
def bottleneck(inputs,
               depth,
               depth_bottleneck,
               stride,
               rate=1,
               outputs_collections=None,
               scope=None):
  with variable_scope.variable_scope(scope, 'bottleneck_v2', [inputs]) as sc:
    depth_in = utils.last_dimension(inputs.get_shape(), min_rank=4)
    preact = layers.batch_norm(
        inputs, activation_fn=nn_ops.relu, scope='preact')
    if depth == depth_in:
      shortcut = resnet_utils.subsample(inputs, stride, 'shortcut')
    else:
      shortcut = layers_lib.conv2d(
          preact,
          depth, [1, 1],
          stride=stride,
          normalizer_fn=None,
          activation_fn=None,
          scope='shortcut')

    residual = preact
    residual = tf.layers.batch_normalization(residual)
    residual = tf.nn.relu(residual)
    residual = layers_lib.conv2d(
        residual, depth_bottleneck, [1, 1], stride=1, scope='conv1')
    residual = tf.layers.batch_normalization(residual)
    residual = tf.nn.relu(residual)
    residual = resnet_utils.conv2d_same(
        residual, depth_bottleneck, 3, stride, rate=rate, scope='conv2')
    residual = tf.layers.batch_normalization(residual)
    residual = tf.nn.relu(residual)
    residual = layers_lib.conv2d(
        residual,
        depth, [1, 1],
        stride=1,
        normalizer_fn=None,
        activation_fn=None,
        scope='conv3')

    output = shortcut + residual

    return utils.collect_named_outputs(outputs_collections, sc.name, output)
Пример #16
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 arg_scope(resnet_utils.resnet_arg_scope(is_training=False)):
      for output_stride in [1, 2, 4, 8, None]:
        with ops.Graph().as_default():
          with self.test_session() as sess:
            random_seed.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.
            variable_scope.get_variable_scope().reuse_variables()
            # Feature extraction at the nominal network rate.
            expected = self._stack_blocks_nondense(inputs, blocks)
            sess.run(variables.global_variables_initializer())
            output, expected = sess.run([output, expected])
            self.assertAllClose(output, expected, atol=1e-4, rtol=1e-4)
Пример #17
0
  def testAtrousValuesBottleneck(self):
    """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.
    """
    block = resnet_v2.resnet_v2_block
    blocks = [
        block('block1', base_depth=1, num_units=2, stride=2),
        block('block2', base_depth=2, num_units=2, stride=2),
        block('block3', base_depth=4, num_units=2, stride=2),
        block('block4', base_depth=8, num_units=2, stride=1),
    ]
    nominal_stride = 8

    # Test both odd and even input dimensions.
    height = 30
    width = 31
    with arg_scope(resnet_utils.resnet_arg_scope()):
      with arg_scope([layers.batch_norm], is_training=False):
        for output_stride in [1, 2, 4, 8, None]:
          with ops.Graph().as_default():
            with self.test_session() as sess:
              random_seed.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.
              variable_scope.get_variable_scope().reuse_variables()
              # Feature extraction at the nominal network rate.
              expected = self._stack_blocks_nondense(inputs, blocks)
              sess.run(variables.global_variables_initializer())
              output, expected = sess.run([output, expected])
              self.assertAllClose(output, expected, atol=1e-4, rtol=1e-4)
Пример #18
0
  def testConv2DSameOdd(self):
    n, n2 = 5, 3

    # Input image.
    x = create_test_input(1, n, n, 1)

    # Convolution kernel.
    w = create_test_input(1, 3, 3, 1)
    w = array_ops.reshape(w, [3, 3, 1, 1])

    variable_scope.get_variable('Conv/weights', initializer=w)
    variable_scope.get_variable('Conv/biases', initializer=array_ops.zeros([1]))
    variable_scope.get_variable_scope().reuse_variables()

    y1 = layers.conv2d(x, 1, [3, 3], stride=1, scope='Conv')
    y1_expected = math_ops.cast([[14, 28, 43, 58, 34],
                                 [28, 48, 66, 84, 46],
                                 [43, 66, 84, 102, 55],
                                 [58, 84, 102, 120, 64],
                                 [34, 46, 55, 64, 30]],
                                dtypes.float32)
    y1_expected = array_ops.reshape(y1_expected, [1, n, n, 1])

    y2 = resnet_utils.subsample(y1, 2)
    y2_expected = math_ops.cast([[14, 43, 34],
                                 [43, 84, 55],
                                 [34, 55, 30]],
                                dtypes.float32)
    y2_expected = array_ops.reshape(y2_expected, [1, n2, n2, 1])

    y3 = resnet_utils.conv2d_same(x, 1, 3, stride=2, scope='Conv')
    y3_expected = y2_expected

    y4 = layers.conv2d(x, 1, [3, 3], stride=2, scope='Conv')
    y4_expected = y2_expected

    with self.cached_session() as sess:
      sess.run(variables.global_variables_initializer())
      self.assertAllClose(y1.eval(), y1_expected.eval())
      self.assertAllClose(y2.eval(), y2_expected.eval())
      self.assertAllClose(y3.eval(), y3_expected.eval())
      self.assertAllClose(y4.eval(), y4_expected.eval())
Пример #19
0
    def testConv2DSameOdd(self):
        n, n2 = 5, 3

        # Input image.
        x = create_test_input(1, n, n, 1)

        # Convolution kernel.
        w = create_test_input(1, 3, 3, 1)
        w = array_ops.reshape(w, [3, 3, 1, 1])

        variable_scope.get_variable('Conv/weights', initializer=w)
        variable_scope.get_variable('Conv/biases',
                                    initializer=array_ops.zeros([1]))
        variable_scope.get_variable_scope().reuse_variables()

        y1 = layers.conv2d(x, 1, [3, 3], stride=1, scope='Conv')
        y1_expected = math_ops.to_float([[14, 28, 43, 58, 34],
                                         [28, 48, 66, 84, 46],
                                         [43, 66, 84, 102, 55],
                                         [58, 84, 102, 120, 64],
                                         [34, 46, 55, 64, 30]])
        y1_expected = array_ops.reshape(y1_expected, [1, n, n, 1])

        y2 = resnet_utils.subsample(y1, 2)
        y2_expected = math_ops.to_float([[14, 43, 34], [43, 84, 55],
                                         [34, 55, 30]])
        y2_expected = array_ops.reshape(y2_expected, [1, n2, n2, 1])

        y3 = resnet_utils.conv2d_same(x, 1, 3, stride=2, scope='Conv')
        y3_expected = y2_expected

        y4 = layers.conv2d(x, 1, [3, 3], stride=2, scope='Conv')
        y4_expected = y2_expected

        with self.cached_session() as sess:
            sess.run(variables.global_variables_initializer())
            self.assertAllClose(y1.eval(), y1_expected.eval())
            self.assertAllClose(y2.eval(), y2_expected.eval())
            self.assertAllClose(y3.eval(), y3_expected.eval())
            self.assertAllClose(y4.eval(), y4_expected.eval())
Пример #20
0
  def testConv2DSameEven(self):
    n, n2 = 4, 2

    # Input image.
    x = create_test_input(1, n, n, 1)

    # Convolution kernel.
    w = create_test_input(1, 3, 3, 1)
    w = array_ops.reshape(w, [3, 3, 1, 1])

    variable_scope.get_variable('Conv/weights', initializer=w)
    variable_scope.get_variable('Conv/biases', initializer=array_ops.zeros([1]))
    variable_scope.get_variable_scope().reuse_variables()

    y1 = layers.conv2d(x, 1, [3, 3], stride=1, scope='Conv')
    y1_expected = math_ops.to_float([[14, 28, 43, 26], [28, 48, 66, 37],
                                     [43, 66, 84, 46], [26, 37, 46, 22]])
    y1_expected = array_ops.reshape(y1_expected, [1, n, n, 1])

    y2 = resnet_utils.subsample(y1, 2)
    y2_expected = math_ops.to_float([[14, 43], [43, 84]])
    y2_expected = array_ops.reshape(y2_expected, [1, n2, n2, 1])

    y3 = resnet_utils.conv2d_same(x, 1, 3, stride=2, scope='Conv')
    y3_expected = y2_expected

    y4 = layers.conv2d(x, 1, [3, 3], stride=2, scope='Conv')
    y4_expected = math_ops.to_float([[48, 37], [37, 22]])
    y4_expected = array_ops.reshape(y4_expected, [1, n2, n2, 1])

    with self.test_session() as sess:
      sess.run(variables.global_variables_initializer())
      self.assertAllClose(y1.eval(), y1_expected.eval())
      self.assertAllClose(y2.eval(), y2_expected.eval())
      self.assertAllClose(y3.eval(), y3_expected.eval())
      self.assertAllClose(y4.eval(), y4_expected.eval())
Пример #21
0
def bottleneck(inputs,
               depth,
               depth_bottleneck,
               stride,
               rate=1,
               outputs_collections=None,
               scope=None):
    """Bottleneck residual unit variant with BN before convolutions. 

  This is the full preactivation residual unit variant proposed in [2]. See
  Fig. 1(b) of [2] for its definition. Note that we use here the bottleneck
  variant which has an extra bottleneck layer.

  When putting together two consecutive ResNet blocks that use this unit, one
  should use stride = 2 in the last unit of the first block.
  
  意思是root_block的最后一个unit的stride为2?????????

  Args:
    inputs: A tensor of size [batch, height, width, channels].
    depth: The depth of the ResNet unit output.
    depth_bottleneck: The depth of the bottleneck layers.
    stride: The ResNet unit's stride. Determines the amount of downsampling of
      the units output compared to its input.
    rate: An integer, rate for atrous convolution.
    outputs_collections: Collection to add the ResNet unit output.
    scope: Optional variable_scope.

  Returns:
    The ResNet unit's output.
  """
    with variable_scope.variable_scope(scope, 'bottleneck_v2', [inputs]) as sc:
        '''获取输入的通道数'''
        depth_in = utils.last_dimension(inputs.get_shape(), min_rank=4)
        '''正则化在前'''
        preact = layers.batch_norm(inputs,
                                   activation_fn=nn_ops.relu,
                                   scope='preact')
        '''计算shortcut,ifelse目的是保证与输出通道数一致,也即块与块连接处'''
        if depth == depth_in:
            shortcut = resnet_utils.subsample(inputs, stride, 'shortcut')
        else:
            shortcut = layers_lib.conv2d(preact,
                                         depth, [1, 1],
                                         stride=stride,
                                         normalizer_fn=None,
                                         activation_fn=None,
                                         scope='shortcut')
        '''计算residual,depth_bottleneck为输出通道数,[1x1]->relu->[3x3]->relu->[1x1],这里有3层'''
        residual = layers_lib.conv2d(preact,
                                     depth_bottleneck, [1, 1],
                                     stride=1,
                                     scope='conv1')
        residual = resnet_utils.conv2d_same(residual,
                                            depth_bottleneck,
                                            3,
                                            stride,
                                            rate=rate,
                                            scope='conv2')
        residual = layers_lib.conv2d(residual,
                                     depth, [1, 1],
                                     stride=1,
                                     normalizer_fn=None,
                                     activation_fn=None,
                                     scope='conv3')
        '''关键在于弄清楚resnet unit的输出'''
        output = shortcut + residual

        return utils.collect_named_outputs(outputs_collections, sc.name,
                                           output)
Пример #22
0
    def stack_blocks_dense(self,
                           net,
                           blocks,
                           output_stride=None,
                           store_non_strided_activations=False,
                           outputs_collections=None,
                           weights_regularizer=None,
                           weights_initializer=None,
                           biases_initializer=None):
        """Stacks ResNet `Blocks` and controls output feature density.
      First, this function creates scopes for the ResNet in the form of
      'block_name/unit_1', 'block_name/unit_2', etc.
      Second, this function allows the user to explicitly control the ResNet
      output_stride, which is the ratio of the input to output spatial resolution.
      This is useful for dense prediction tasks such as semantic segmentation or
      object detection.
      Most ResNets consist of 4 ResNet blocks and subsample the activations by a
      factor of 2 when transitioning between consecutive ResNet blocks. This results
      to a nominal ResNet output_stride equal to 8. If we set the output_stride to
      half the nominal network stride (e.g., output_stride=4), then we compute
      responses twice.
      Control of the output feature density is implemented by atrous convolution.
      Args:
        net: A `Tensor` of size [batch, height, width, channels].
        blocks: A list of length equal to the number of ResNet `Blocks`. Each
          element is a ResNet `Block` object describing the units in the `Block`.
        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, which needs to be equal to
          the product of unit strides from the start up to some level of the ResNet.
          For example, if the ResNet employs units with strides 1, 2, 1, 3, 4, 1,
          then valid values for the output_stride are 1, 2, 6, 24 or None (which
          is equivalent to output_stride=24).
        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.
        outputs_collections: Collection to add the ResNet block outputs.
      Returns:
        net: Output tensor with stride equal to the specified output_stride.
      Raises:
        ValueError: If the target output_stride is not valid.
      """
        # The current_stride variable keeps track of the effective stride of the
        # activations. This allows us to invoke atrous convolution whenever applying
        # the next residual unit would result in the activations having stride larger
        # than the target output_stride.
        current_stride = 1

        # The atrous convolution rate parameter.
        rate = 1

        for block in blocks:
            with tf.variable_scope(block.scope, 'block', [net]) as sc:
                block_stride = 1
                for i, unit in enumerate(block.args):
                    if store_non_strided_activations and i == len(
                            block.args) - 1:
                        # Move stride from the block's last unit to the end of the block.
                        block_stride = unit.get('stride', 1)
                        unit = dict(unit, stride=1)

                    with tf.variable_scope('unit_%d' % (i + 1), values=[net]):
                        # If we have reached the target output_stride, then we need to employ
                        # atrous convolution with stride=1 and multiply the atrous rate by the
                        # current unit's stride for use in subsequent layers.
                        if output_stride is not None and current_stride == output_stride:
                            net = block.unit_fn(net,
                                                rate=rate,
                                                **dict(unit, stride=1))
                            rate *= unit.get('stride', 1)

                        else:
                            net = block.unit_fn(net, rate=1, **unit)
                            if isinstance(unit.get('stride', 1), int):
                                st = unit.get('stride', 1)
                            else:
                                st = unit.get('stride', 1)[0]
                            current_stride *= st
                            if output_stride is not None and current_stride > output_stride:
                                raise ValueError(
                                    'The target output_stride cannot be reached.'
                                )

                # Collect activations at the block's end before performing subsampling.
                net = slim.utils.collect_named_outputs(outputs_collections,
                                                       sc.name, net)

                # Subsampling of the block's output activations.
                if output_stride is not None and current_stride == output_stride:
                    rate *= block_stride
                else:
                    net = resnet_utils.subsample(net, block_stride)
                    current_stride *= block_stride
                    if output_stride is not None and current_stride > output_stride:
                        raise ValueError(
                            'The target output_stride cannot be reached.')

        if output_stride is not None and current_stride != output_stride:
            raise ValueError('The target output_stride cannot be reached.')

        return net
Пример #23
0
def bottleneck(inputs,
               depth,
               depth_bottleneck,
               stride,
               rate=1,
               outputs_collections=None,
               scope=None):
    """Bottleneck residual unit variant with BN before convolutions.

    This is the full preactivation residual unit variant proposed in [2]. See
    Fig. 1(b) of [2] for its definition. Note that we use here the bottleneck
    variant which has an extra bottleneck layer.

    When putting together two consecutive ResNet blocks that use this unit, one
    should use stride = 2 in the last unit of the first block.

    Args:
      inputs: A tensor of size [batch, height, width, channels].
      depth: The depth of the ResNet unit output.
      depth_bottleneck: The depth of the bottleneck layers.
      stride: The ResNet unit's stride. Determines the amount of downsampling of
        the units output compared to its input.
      rate: An integer, rate for atrous convolution.
      outputs_collections: Collection to add the ResNet unit output.
      scope: Optional variable_scope.

    Returns:
      The ResNet unit's output.
    """
    with variable_scope.variable_scope(scope, 'bottleneck_v2', [inputs]) as sc:
        depth_in = utils.last_dimension(inputs.get_shape(), min_rank=4)
        preact = layers.batch_norm(inputs,
                                   activation_fn=nn_ops.relu,
                                   scope='preact')
        if depth == depth_in:
            shortcut = resnet_utils.subsample(inputs, stride, 'shortcut')
        else:
            shortcut = layers_lib.conv2d(preact,
                                         depth, [1, 1],
                                         stride=stride,
                                         normalizer_fn=None,
                                         activation_fn=None,
                                         scope='shortcut')

        residual = layers_lib.conv2d(preact,
                                     depth_bottleneck, [1, 1],
                                     stride=1,
                                     scope='conv1')
        residual = resnet_utils.conv2d_same(residual,
                                            depth_bottleneck,
                                            3,
                                            stride,
                                            rate=rate,
                                            scope='conv2')
        residual = layers_lib.conv2d(residual,
                                     depth, [1, 1],
                                     stride=1,
                                     normalizer_fn=None,
                                     activation_fn=None,
                                     scope='conv3')

        random_range = 0.12  #if FLAGS.optimal else FLAGS.random_range
        weight = tf.random_uniform((depth, ),
                                   minval=1 - random_range,
                                   maxval=1 + random_range)
        # weight = tf.random_uniform((depth,), minval=5 - random_range, maxval=5 + random_range)
        output = weight * shortcut + residual
        # output = weight * shortcut + 0.5*residual

        return utils.collect_named_outputs(outputs_collections, sc.name,
                                           output)
Пример #24
0
def bottleneck(inputs,
               depth,
               depth_bottleneck,
               stride,
               rate=1,
               outputs_collections=None,
               scope=None):
  """Bottleneck residual unit variant with BN before convolutions.

  This is the full preactivation residual unit variant proposed in [2]. See
  Fig. 1(b) of [2] for its definition. Note that we use here the bottleneck
  variant which has an extra bottleneck layer.

  When putting together two consecutive ResNet blocks that use this unit, one
  should use stride = 2 in the last unit of the first block.

  Args:
    inputs: A tensor of size [batch, height, width, channels].
    depth: The depth of the ResNet unit output.
    depth_bottleneck: The depth of the bottleneck layers.
    stride: The ResNet unit's stride. Determines the amount of downsampling of
      the units output compared to its input.
    rate: An integer, rate for atrous convolution.
    outputs_collections: Collection to add the ResNet unit output.
    scope: Optional variable_scope.

  Returns:
    The ResNet unit's output.
  """
  with variable_scope.variable_scope(scope, 'bottleneck_v2', [inputs]) as sc:
    depth_in = utils.last_dimension(inputs.get_shape(), min_rank=4)
    preact = layers.batch_norm(
        inputs, activation_fn=nn_ops.relu, scope='preact')
    if depth == depth_in:
      shortcut = resnet_utils.subsample(inputs, stride, 'shortcut')
    else:
      shortcut = layers_lib.conv2d(
          preact,
          depth, [1, 1],
          stride=stride,
          normalizer_fn=None,
          activation_fn=None,
          scope='shortcut')

    residual = layers_lib.conv2d(
        preact, depth_bottleneck, [1, 1], stride=1, scope='conv1')
    residual = resnet_utils.conv2d_same(
        residual, depth_bottleneck, 3, stride, rate=rate, scope='conv2')
    residual = layers_lib.conv2d(
        residual,
        depth, [1, 1],
        stride=1,
        normalizer_fn=None,
        activation_fn=None,
        scope='conv3')
    with variable_scope.variable_scope('CBAM'):
        max_c = math_ops.reduce_max(residual, axis=[1, 2], name='max_c')
        max_c = layers_lib.fully_connected(max_c, int(depth / 8), nn_ops.relu, normalizer_fn=None,
                                           scope='share1', weights_regularizer=layers_lib.l2_regularizer(0.0001))
        max_c = layers_lib.fully_connected(max_c, depth, None, normalizer_fn=None,
                                           scope='share2', weights_regularizer=layers_lib.l2_regularizer(0.0001))

        avg_c = math_ops.reduce_mean(residual, axis=[1, 2], name='avg_c')
        avg_c = layers_lib.fully_connected(avg_c, int(depth / 8), nn_ops.relu, normalizer_fn=None,
                                           scope='share1', reuse=True)
        avg_c = layers_lib.fully_connected(avg_c, depth, None, normalizer_fn=None,
                                           scope='share2', reuse=True)

        Mc = math_ops.sigmoid(max_c + avg_c)
        Mc = array_ops.expand_dims(Mc, 1)
        Mc = array_ops.expand_dims(Mc, 1)
        residual = residual * Mc

        max_s = math_ops.reduce_max(residual, axis=-1, name='max_s', keep_dims=True)
        avg_s = math_ops.reduce_mean(residual, axis=-1, name='avg_s', keep_dims=True)
        Ms = array_ops.concat([avg_s, max_s], axis=-1)
        Ms = layers_lib.conv2d(Ms, 1, [1, 1], activation_fn=math_ops.sigmoid, normalizer_fn=None)
        residual = residual * Ms
    output = shortcut + residual

    return utils.collect_named_outputs(outputs_collections, sc.name, output)