I'm looking to apply a mask to the kernel of a Conv2D layer in Keras. I'm having a bit of difficulty understanding kernel shape.
For kernel_size = 3, and filters = 1, the shape of the kernel is (3, 3, 4, 1) => (kernel_size, kernel_size, ???, filters)
What does the 3rd dimension in the kernel represent?
How can I take an NxN mask and multiply it to each of the kernel filters?
This is the code I have so far. I am not sure if it will work as I expect it to because I don't fully understand the kernel shape.
class MaskedConv2D(tf.keras.layers.Layer):
def __init__(self, *args, **kwargs):
super(MaskedConv2D, self).__init__()
self.conv2d = Conv2D(*args, **kwargs)
def build(self, input_shape):
self.conv2d.build(input_shape[0])
self._convolution_op = self.conv2d._convolution_op
def masked_convolution_op(self, filters, kernel, mask):
m = K.expand_dims(K.expand_dims(mask[0, ...], axis=2), axis=3) # (3, 3) => (3, 3, 1, 1)
m = K.tile(m, (1, 1, kernel.shape[2], kernel.shape[3])) # (3, 3, 1, 1) => (3, 3, 4, 1)
return self._convolution_op(filters, tf.math.multiply(kernel, m))
def call(self, inputs):
x, mask = inputs
self.conv2d._convolution_op = functools.partial(self.masked_convolution_op, mask=mask)
return self.conv2d.call(x)