(
    x,
    is_training,
    weight_decay,
    scope,
    reuse=tf.AUTO_REUSE,
    params=None,
    moments=None,
    backprop_through_moments=True,
    use_bounded_activation=False,
    blocks=(2, 2, 2, 2),
    max_stride=None,
    deeplab_alignment=True,
    keep_spatial_dims=False,
    film_selector=None
)
A ResNet network; ResNet18 by default.
A ResNet network; ResNet18 by default.
A ResNet network ; ResNet18 by default .
def _resnet(
    x,
    is_training,
    weight_decay,
    scope,
    reuse=tf.AUTO_REUSE,
    params=None,
    moments=None,
    backprop_through_moments=True,
    use_bounded_activation=False,
    blocks=(2, 2, 2, 2),
    max_stride=None,
    deeplab_alignment=True,
    keep_spatial_dims=False,
    film_selector=None
):
  """A ResNet network; ResNet18 by default."""
  x = tf.stop_gradient(x)
  params_keys, params_vars = [], []
  moments_keys, moments_vars = [], []
  assert max_stride in [None, 4, 8, 16,
                        32], 'max_stride must be 4, 8, 16, 32, or None'
  with tf.variable_scope(scope, reuse=reuse):
    # We use DeepLab feature alignment rule to determine the input size.
    # Since the image size in the meta-dataset pipeline is a multiplier of 42,
    # e.g., [42, 84, 168], we align them to the closest sizes that conform to
    # the alignment rule and at the same time are larger. They are [65, 97, 193]
    # respectively. The aligned image size for 224 used in the ResNet work is
    # 225.
    #
    # References:
    # 1. ResNet https://arxiv.org/abs/1512.03385
    # 2. DeepLab https://arxiv.org/abs/1606.00915
    if deeplab_alignment:
      size = tf.cast(tf.shape(x)[1], tf.float32)
      aligned_size = tf.cast(tf.ceil(size / 32.0), tf.int32) * 32 + 1
      x = tf.image.resize_bilinear(
          x, size=[aligned_size, aligned_size], align_corners=True)

    with tf.variable_scope('conv1'):
      x, conv_bn_params, conv_bn_moments = conv_bn(
          x,
          [7, 7],
          64,
          2,
          weight_decay,
          params=params,
          moments=moments,
          is_training=is_training,
          backprop_through_moments=backprop_through_moments,
          film_selector=film_selector
      )
      params_keys.extend(conv_bn_params.keys())
      params_vars.extend(conv_bn_params.values())
      moments_keys.extend(conv_bn_moments.keys())
      moments_vars.extend(conv_bn_moments.values())

      x = relu(x, use_bounded_activation=use_bounded_activation)

    def _bottleneck(x,
                    i,
                    depth,
                    stride,
                    params,
                    moments,
                    net_stride=1,
                    net_rate=1):
      """Wrapper for bottleneck."""
      input_rate = net_rate
      output_rate = input_rate
      if i == 0:
        if max_stride and stride * net_stride > max_stride:
          output_stride = 1
          output_rate *= stride
        else:
          output_stride = stride
      else:
        output_stride = 1
      use_project = True if i == 0 else False

      x, bottleneck_params, bottleneck_moments = bottleneck(
          x,
          (depth, depth),
          output_stride,
          weight_decay,
          params=params,
          moments=moments,
          input_rate=input_rate,
          output_rate=output_rate,
          use_project=use_project,
          is_training=is_training,
          backprop_through_moments=backprop_through_moments,
          film_selector=film_selector
      )
      net_stride *= output_stride
      return x, bottleneck_params, bottleneck_moments, net_stride, output_rate

    net_stride = 4
    net_rate = 1

    with tf.variable_scope('conv2_x'):
      x = tf.nn.max_pool(
          x, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME')
      for i in range(blocks[0]):
        with tf.variable_scope('bottleneck_%d' % i):
          x, bottleneck_params, bottleneck_moments, net_stride, net_rate = _bottleneck(
              x, i, 64, 1, params, moments, net_stride, net_rate)
          params_keys.extend(bottleneck_params.keys())
          params_vars.extend(bottleneck_params.values())
          moments_keys.extend(bottleneck_moments.keys())
          moments_vars.extend(bottleneck_moments.values())

    with tf.variable_scope('conv3_x'):
      for i in range(blocks[1]):
        with tf.variable_scope('bottleneck_%d' % i):
          x, bottleneck_params, bottleneck_moments, net_stride, net_rate = _bottleneck(
              x, i, 128, 2, params, moments, net_stride, net_rate)
          params_keys.extend(bottleneck_params.keys())
          params_vars.extend(bottleneck_params.values())
          moments_keys.extend(bottleneck_moments.keys())
          moments_vars.extend(bottleneck_moments.values())

    with tf.variable_scope('conv4_x'):
      for i in range(blocks[2]):
        with tf.variable_scope('bottleneck_%d' % i):
          x, bottleneck_params, bottleneck_moments, net_stride, net_rate = _bottleneck(
              x, i, 256, 2, params, moments, net_stride, net_rate)
          params_keys.extend(bottleneck_params.keys())
          params_vars.extend(bottleneck_params.values())
          moments_keys.extend(bottleneck_moments.keys())
          moments_vars.extend(bottleneck_moments.values())

    with tf.variable_scope('conv5_x'):
      for i in range(blocks[3]):
        with tf.variable_scope('bottleneck_%d' % i):
          x, bottleneck_params, bottleneck_moments, net_stride, net_rate = _bottleneck(
              x, i, 512, 2, params, moments, net_stride, net_rate)
          params_keys.extend(bottleneck_params.keys())
          params_vars.extend(bottleneck_params.values())
          moments_keys.extend(bottleneck_moments.keys())
          moments_vars.extend(bottleneck_moments.values())
    if not keep_spatial_dims:
      # x.shape: [?, 1, 1, 512]
      x = tf.reduce_mean(x, axis=[1, 2], keepdims=True)
      x = tf.reshape(x, [-1, 512])
    params = collections.OrderedDict(zip(params_keys, params_vars))
    moments = collections.OrderedDict(zip(moments_keys, moments_vars))

    return_dict = {'embeddings': x, 'params': params, 'moments': moments}
    return return_dict
def _resnet ( x , is_training , weight_decay , scope , reuse = tf . AUTO_REUSE , params = None , moments = None , backprop_through_moments = True , use_bounded_activation = False , blocks = ( 2 , 2 , 2 , 2 ) , max_stride = None , deeplab_alignment = True , keep_spatial_dims = False , film_selector = None ) : x = tf . stop_gradient ( x ) params_keys , params_vars = [ ] , [ ] moments_keys , moments_vars = [ ] , [ ] assert max_stride in [ None , 4 , 8 , 16 , 32 ] , 'max_stride must be 4, 8, 16, 32, or None' with tf . variable_scope ( scope , reuse = reuse ) : # We use DeepLab feature alignment rule to determine the input size. # Since the image size in the meta-dataset pipeline is a multiplier of 42, # e.g., [42, 84, 168], we align them to the closest sizes that conform to # the alignment rule and at the same time are larger. They are [65, 97, 193] # respectively. The aligned image size for 224 used in the ResNet work is # 225. # # References: # 1. ResNet https://arxiv.org/abs/1512.03385 # 2. DeepLab https://arxiv.org/abs/1606.00915 if deeplab_alignment : size = tf . cast ( tf . shape ( x ) [ 1 ] , tf . float32 ) aligned_size = tf . cast ( tf . ceil ( size / 32.0 ) , tf . int32 ) * 32 + 1 x = tf . image . resize_bilinear ( x , size = [ aligned_size , aligned_size ] , align_corners = True ) with tf . variable_scope ( 'conv1' ) : x , conv_bn_params , conv_bn_moments = conv_bn ( x , [ 7 , 7 ] , 64 , 2 , weight_decay , params = params , moments = moments , is_training = is_training , backprop_through_moments = backprop_through_moments , film_selector = film_selector ) params_keys . extend ( conv_bn_params . keys ( ) ) params_vars . extend ( conv_bn_params . values ( ) ) moments_keys . extend ( conv_bn_moments . keys ( ) ) moments_vars . extend ( conv_bn_moments . values ( ) ) x = relu ( x , use_bounded_activation = use_bounded_activation ) def _bottleneck ( x , i , depth , stride , params , moments , net_stride = 1 , net_rate = 1 ) : """Wrapper for bottleneck.""" input_rate = net_rate output_rate = input_rate if i == 0 : if max_stride and stride * net_stride > max_stride : output_stride = 1 output_rate *= stride else : output_stride = stride else : output_stride = 1 use_project = True if i == 0 else False x , bottleneck_params , bottleneck_moments = bottleneck ( x , ( depth , depth ) , output_stride , weight_decay , params = params , moments = moments , input_rate = input_rate , output_rate = output_rate , use_project = use_project , is_training = is_training , backprop_through_moments = backprop_through_moments , film_selector = film_selector ) net_stride *= output_stride return x , bottleneck_params , bottleneck_moments , net_stride , output_rate net_stride = 4 net_rate = 1 with tf . variable_scope ( 'conv2_x' ) : x = tf . nn . max_pool ( x , ksize = [ 1 , 3 , 3 , 1 ] , strides = [ 1 , 2 , 2 , 1 ] , padding = 'SAME' ) for i in range ( blocks [ 0 ] ) : with tf . variable_scope ( 'bottleneck_%d' % i ) : x , bottleneck_params , bottleneck_moments , net_stride , net_rate = _bottleneck ( x , i , 64 , 1 , params , moments , net_stride , net_rate ) params_keys . extend ( bottleneck_params . keys ( ) ) params_vars . extend ( bottleneck_params . values ( ) ) moments_keys . extend ( bottleneck_moments . keys ( ) ) moments_vars . extend ( bottleneck_moments . values ( ) ) with tf . variable_scope ( 'conv3_x' ) : for i in range ( blocks [ 1 ] ) : with tf . variable_scope ( 'bottleneck_%d' % i ) : x , bottleneck_params , bottleneck_moments , net_stride , net_rate = _bottleneck ( x , i , 128 , 2 , params , moments , net_stride , net_rate ) params_keys . extend ( bottleneck_params . keys ( ) ) params_vars . extend ( bottleneck_params . values ( ) ) moments_keys . extend ( bottleneck_moments . keys ( ) ) moments_vars . extend ( bottleneck_moments . values ( ) ) with tf . variable_scope ( 'conv4_x' ) : for i in range ( blocks [ 2 ] ) : with tf . variable_scope ( 'bottleneck_%d' % i ) : x , bottleneck_params , bottleneck_moments , net_stride , net_rate = _bottleneck ( x , i , 256 , 2 , params , moments , net_stride , net_rate ) params_keys . extend ( bottleneck_params . keys ( ) ) params_vars . extend ( bottleneck_params . values ( ) ) moments_keys . extend ( bottleneck_moments . keys ( ) ) moments_vars . extend ( bottleneck_moments . values ( ) ) with tf . variable_scope ( 'conv5_x' ) : for i in range ( blocks [ 3 ] ) : with tf . variable_scope ( 'bottleneck_%d' % i ) : x , bottleneck_params , bottleneck_moments , net_stride , net_rate = _bottleneck ( x , i , 512 , 2 , params , moments , net_stride , net_rate ) params_keys . extend ( bottleneck_params . keys ( ) ) params_vars . extend ( bottleneck_params . values ( ) ) moments_keys . extend ( bottleneck_moments . keys ( ) ) moments_vars . extend ( bottleneck_moments . values ( ) ) if not keep_spatial_dims : # x.shape: [?, 1, 1, 512] x = tf . reduce_mean ( x , axis = [ 1 , 2 ] , keepdims = True ) x = tf . reshape ( x , [ - 1 , 512 ] ) params = collections . OrderedDict ( zip ( params_keys , params_vars ) ) moments = collections . OrderedDict ( zip ( moments_keys , moments_vars ) ) return_dict = { 'embeddings' : x , 'params' : params , 'moments' : moments } return return_dict