Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to construct a sobel filter for kernel initialization in input layer for images of size 128x128x3?

This is my code for sobel filter:

def init_f(shape, dtype=None):

    sobel_x = tf.constant([[-5, -4, 0, 4, 5], [-8, -10, 0, 10, 8], [-10, -20, 0, 20, 10], [-8, -10, 0, 10, 8], [-5, -4, 0, 4, 5]])

    ker = np.zeros(shape, dtype)
    ker_shape = tf.shape(ker)
    kernel = tf.tile(sobel_x, ker_shape)//*Is this correct?*
    return kernel

model.add(Conv2D(filters=30, kernel_size=(5,5), kernel_initializer=init_f, strides=(1,1), activation='relu'))

So far I have managed to do this. But, this gives me error:

Shape must be rank 2 but is rank 4 for 'conv2d_17/Tile' (op: 'Tile') with input shapes: [5,5], [4].

Tensorflow Version: 2.1.0

like image 573
drum_stick Avatar asked Sep 05 '25 03:09

drum_stick


1 Answers

You're close, but the args to tile don't appear to be correct. That is why you're getting the error "Shape must be rank 2 but is rank 4 for..." You're sobel_x must be a rank 4 tensor, so you need to add two more dimensions. I used reshape in this example.

from tensorflow import keras
import tensorflow as tf
import numpy

def kernelInitializer(shape, dtype=None):
    print(shape)    
    sobel_x = tf.constant(
        [
            [-5, -4, 0, 4, 5], 
            [-8, -10, 0, 10, 8], 
            [-10, -20, 0, 20, 10], 
            [-8, -10, 0, 10, 8], 
            [-5, -4, 0, 4, 5]
        ], dtype=dtype )
    #create the missing dims.
    sobel_x = tf.reshape(sobel_x, (5, 5, 1, 1))

    print(tf.shape(sobel_x))
    #tile the last 2 axis to get the expected dims.
    sobel_x = tf.tile(sobel_x, (1, 1, shape[-2],shape[-1]))

    print(tf.shape(sobel_x))
    return sobel_x

x1 = keras.layers.Input((128, 128, 3))

cvl = keras.layers.Conv2D(30, kernel_size=(5,5), kernel_initializer=kernelInitializer, strides=(2,2), activation='relu')

model = keras.Sequential();
model.add(x1)
model.add(cvl)

data = numpy.ones((1, 128, 128, 3))
data[:, 0:64, 0:64, :] = 0

pd = model.predict(data)
print(pd.shape)

d = pd[0, :, :, 0]
for row in d:
    for col in row:
        m = '0'
        if col != 0:
            m = 'X'
        print(m, end="")
    print("")

I looked at using expand_dims instead of reshape but there didn't appear any advantage. broadcast_to seems ideal, but you still have to add the dimensions, so I don't think it was better than tile.

Why 30 filters of the same filter though? Are they going to be changed afterwards?

like image 158
matt Avatar answered Sep 07 '25 23:09

matt