What is difference between tf.layers.conv2d and tf.layers.Conv2D?

Viewed 1200

What is difference between tf.layers.conv2d and tf.layers.Conv2D?

Why tf.layers.Conv2D used in example code in this paper?

Here is a full code snippet:

class AddCoords(base.Layer):
    """Add coords to a tensor"""
    def __init__(self, x_dim=64, y_dim=64, with_r=False):
        super(AddCoords, self).__init__()
        self.x_dim = x_dim
        self.y_dim = y_dim
        self.with_r = with_r

    def call(self, input_tensor):
        """
        input_tensor: (batch, x_dim, y_dim, c)
        """
        batch_size_tensor = tf.shape(input_tensor)[0]
        xx_ones = tf.ones([batch_size_tensor, self.x_dim], dtype=tf.int32)
        xx_ones = tf.expand_dims(xx_ones, -1)
        xx_range = tf.tile(tf.expand_dims(tf.range(self.x_dim), 0), [batch_size_tensor, 1])
        xx_range = tf.expand_dims(xx_range, 1)
        xx_channel = tf.matmul(xx_ones, xx_range)
        xx_channel = tf.expand_dims(xx_channel, -1)
        yy_ones = tf.ones([batch_size_tensor, self.y_dim], dtype=tf.int32)
        yy_ones = tf.expand_dims(yy_ones, 1)
        yy_range = tf.tile(tf.expand_dims(tf.range(self.y_dim), 0), [batch_size_tensor, 1])
        yy_range = tf.expand_dims(yy_range, -1)
        yy_channel = tf.matmul(yy_range, yy_ones)
        yy_channel = tf.expand_dims(yy_channel, -1)
        xx_channel = tf.cast(xx_channel, 'float32') / (self.x_dim - 1)
        yy_channel = tf.cast(yy_channel, 'float32') / (self.y_dim - 1)
        xx_channel = xx_channel*2 - 1
        yy_channel = yy_channel*2 - 1
        ret = tf.concat([input_tensor, xx_channel, yy_channel], axis=-1)
        if self.with_r:
            rr = tf.sqrt(tf.square(xx_channel-0.5) + tf.square(yy_channel-0.5))
            ret = tf.concat([ret, rr], axis=-1)
        return ret

class CoordConv(base.Layer):
    """CoordConv layer as in the paper."""
    def __init__(self, x_dim, y_dim, with_r, *args, **kwargs):
        super(CoordConv, self).__init__()
        self.addcoords = AddCoords(x_dim=x_dim, y_dim=y_dim, with_r=with_r)
        self.conv = tf.layers.Conv2D(*args, **kwargs)
        def call(self, input_tensor):
            ret = self.addcoords(input_tensor)
            ret = self.conv(ret)
            return ret
2 Answers

tf.layers.conv2d is a simple function/method to compute its input's convolution, so it needs input feature maps and kernel or filter to run this method. One user just call this method to computing convolution.
But tf.layers.Conv2d is a Class (an OOP concept), you should instantiate it with certain filter before you can use it. Once instantiated, you can input different inputs to it and get outputs. One using this Class to design and program a new Class or a new type of operation for other users to use.

Calling

y = tf.layers.conv2d(inputs, **kwargs)

is now exactly the same as

y = tf.layers.Conv2D(**kwargs).apply(inputs)

So tf.layers.conv2d can be seen as a shortcut whenever you do not intend to reuse the object created by Conv2D other than calling its apply method.

Related