Skip to content

Instantly share code, notes, and snippets.

@Dref360
Last active February 11, 2020 14:40
Show Gist options
  • Select an option

  • Save Dref360/b330e75cb121c03a0066d9587a7bfee5 to your computer and use it in GitHub Desktop.

Select an option

Save Dref360/b330e75cb121c03a0066d9587a7bfee5 to your computer and use it in GitHub Desktop.

Revisions

  1. Frédéric Branchaud-Charron revised this gist Feb 11, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion coordconv2d.py
    Original file line number Diff line number Diff line change
    @@ -31,7 +31,7 @@ def call(self, inputs, **kwargs):

    # If channel_first, we swap
    if K.image_data_format() == 'channel_first':
    canvas = K.swap_axes(canvas, [0, 3, 1, 2])
    canvas = K.permute_dimensions(canvas, [0, 3, 1, 2])

    # Concatenate channel-wise
    input = K.concatenate([inputs, canvas], -1)
  2. Frédéric Branchaud-Charron revised this gist Feb 11, 2020. 1 changed file with 31 additions and 20 deletions.
    51 changes: 31 additions & 20 deletions coordconv2d.py
    Original file line number Diff line number Diff line change
    @@ -1,50 +1,61 @@
    import keras.backend as K
    import tensorflow as tf
    from keras.layers import Layer
    from tensorflow.keras.layers import Layer

    """Not tested, I'll play around with GANs soon with it."""
    from tensorflow.keras.layers import Conv2D
    import numpy as np


    class CoordConv2D(Layer):
    def __init__(self, channel, kernel, padding='valid', **kwargs):
    self.layer = Conv2D(channel, kernel, padding=padding)
    self.name = 'CoordConv2D'
    super(CoordConv2D, self).__init__(**kwargs)

    def call(self, input):
    input_shape = tf.unstack(K.shape(input))
    def call(self, inputs, **kwargs):
    indices = tf.ones_like(inputs)
    if K.image_data_format() == 'channel_first':
    bs, channel, w, h = input_shape
    # bs, channel, w, h
    indices = indices[:, 0, ...]
    else:
    bs, w, h, channel = input_shape
    #bs, w, h, channel = input_shape
    indices = indices[..., 0]

    # Get indices
    indices = tf.to_float(tf.where(K.ones([bs, w, h])))
    bs, w, h = [tf.shape(indices)[k] for k in range(3)]
    indices = K.cast(tf.where(indices), tf.float32)
    canvas = K.reshape(indices, [bs, w, h, 3])[..., 1:]
    # Normalize the canvas
    canvas = canvas / tf.to_float(K.reshape([w, h], [1, 1, 1, 2]))
    canvas = canvas / tf.cast(K.reshape([w, h], [1, 1, 1, 2]), tf.float32)
    canvas = (canvas * 2) - 1

    # If channel_first, we swap
    if K.image_data_format() == 'channel_first':
    canvas = K.swap_axes(canvas, [0, 3, 1, 2])

    # Concatenate channel-wise
    input = K.concatenate([input, canvas], -1)
    input = K.concatenate([inputs, canvas], -1)
    return self.layer(input)

    def compute_output_shape(self, input_shape):
    return self.layer.compute_output_shape(input_shape)

    class CustomModel(tf.keras.Model):
    def __init__(self):
    super().__init__()
    self.l = CoordConv2D(63, 3, padding='same')

    from keras.layers import Input, Conv2D
    import numpy as np
    from keras import Model

    inp = Input([32, 32, 3])
    layer = CoordConv2D(63, 3, padding='same')
    x = layer(inp)
    mod = Model(inp, x)
    mod.compile('sgd', 'mse')
    res = mod.predict(np.ones([3, 32, 32, 3]))
    print(res.shape)
    def call(self, inputs):
    x = self.l(inputs)
    return x

    def main():
    mod = CustomModel()

    mod.compile('sgd', 'mse')
    mod.run_eagerly = True
    res = mod.predict(np.ones([3, 32, 32, 3]))
    print(res.shape)

    if __name__ == '__main__':
    main()
  3. Frédéric Branchaud-Charron revised this gist Jul 11, 2018. 1 changed file with 10 additions and 7 deletions.
    17 changes: 10 additions & 7 deletions coordconv2d.py
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,12 @@
    from keras.layers import Layer, Conv2D
    import keras.backend as K
    import tensorflow as tf
    from keras.layers import Layer

    """Not tested, I'll play around with GANs soon with it."""


    """This version doesn't do the scaling to -1, 1, but it's trivial to implement""""
    class CoordConv2D(Layer):
    def __init__(self,channel, kernel, padding='valid', **kwargs):
    def __init__(self, channel, kernel, padding='valid', **kwargs):
    self.layer = Conv2D(channel, kernel, padding=padding)
    self.name = 'CoordConv2D'
    super(CoordConv2D, self).__init__(**kwargs)
    @@ -19,6 +21,9 @@ def call(self, input):
    # Get indices
    indices = tf.to_float(tf.where(K.ones([bs, w, h])))
    canvas = K.reshape(indices, [bs, w, h, 3])[..., 1:]
    # Normalize the canvas
    canvas = canvas / tf.to_float(K.reshape([w, h], [1, 1, 1, 2]))
    canvas = (canvas * 2) - 1

    # If channel_first, we swap
    if K.image_data_format() == 'channel_first':
    @@ -31,8 +36,7 @@ def call(self, input):
    def compute_output_shape(self, input_shape):
    return self.layer.compute_output_shape(input_shape)


    # Simple test

    from keras.layers import Input, Conv2D
    import numpy as np
    from keras import Model
    @@ -42,6 +46,5 @@ def compute_output_shape(self, input_shape):
    x = layer(inp)
    mod = Model(inp, x)
    mod.compile('sgd', 'mse')
    res = mod.predict(np.ones([3, 32, 32,3]))
    res = mod.predict(np.ones([3, 32, 32, 3]))
    print(res.shape)

  4. Frédéric Branchaud-Charron revised this gist Jul 11, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion coordconv2d.py
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@
    import keras.backend as K
    import tensorflow as tf


    """This version doesn't do the scaling to -1, 1, but it's trivial to implement""""
    class CoordConv2D(Layer):
    def __init__(self,channel, kernel, padding='valid', **kwargs):
    self.layer = Conv2D(channel, kernel, padding=padding)
  5. Frédéric Branchaud-Charron created this gist Jul 11, 2018.
    47 changes: 47 additions & 0 deletions coordconv2d.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,47 @@
    from keras.layers import Layer, Conv2D
    import keras.backend as K
    import tensorflow as tf


    class CoordConv2D(Layer):
    def __init__(self,channel, kernel, padding='valid', **kwargs):
    self.layer = Conv2D(channel, kernel, padding=padding)
    self.name = 'CoordConv2D'
    super(CoordConv2D, self).__init__(**kwargs)

    def call(self, input):
    input_shape = tf.unstack(K.shape(input))
    if K.image_data_format() == 'channel_first':
    bs, channel, w, h = input_shape
    else:
    bs, w, h, channel = input_shape

    # Get indices
    indices = tf.to_float(tf.where(K.ones([bs, w, h])))
    canvas = K.reshape(indices, [bs, w, h, 3])[..., 1:]

    # If channel_first, we swap
    if K.image_data_format() == 'channel_first':
    canvas = K.swap_axes(canvas, [0, 3, 1, 2])

    # Concatenate channel-wise
    input = K.concatenate([input, canvas], -1)
    return self.layer(input)

    def compute_output_shape(self, input_shape):
    return self.layer.compute_output_shape(input_shape)


    # Simple test
    from keras.layers import Input, Conv2D
    import numpy as np
    from keras import Model

    inp = Input([32, 32, 3])
    layer = CoordConv2D(63, 3, padding='same')
    x = layer(inp)
    mod = Model(inp, x)
    mod.compile('sgd', 'mse')
    res = mod.predict(np.ones([3, 32, 32,3]))
    print(res.shape)