1

I been trying to figure out how to create Conv3D layers with a custom kernel in Keras. The solution that I found is to pass the kernel as an initializer (reference) Could any one show an other a solution or help me fix this one below or show an example on how to manually create a custom Conv3D layer with a custom kernel?

I wrote this code:

my_kernel = [[[0.88121283, 0.91759044, 0.5578005 ],
              [0.91488576, 0.9526534 , 0.5791151 ],
              [0.88121283, 0.91759044, 0.5578005 ]],

             [[0.88369477, 0.9201748 , 0.5593715 ],
              [0.91746247, 0.9553365 , 0.5807462 ],
              [0.88369477, 0.9201748 , 0.5593715 ]],

             [[0.88121283, 0.91759044, 0.5578005 ],
              [0.91488576, 0.9526534 , 0.5791151 ],
              [0.88121283, 0.91759044, 0.5578005 ]]]
def my_init(shape, dtype=None):
  kernel = my_kernel
  assert kernel.shape == shape
  return K.variable(kernel, dtype='float32')

inputs = Input((240, 240, 155, 4))
conv1 = Conv3D(64, (3,3,3), activation='relu', kernel_initializer=my_init((3,3,3)), padding='same')(inputs)

I got this error:

ValueError: Could not interpret initializer identifier: <tf.Variable 'Variable:0' shape=(3, 3, 3) dtype=float32, numpy=
array([[[0.88121283, 0.91759044, 0.5578005 ],
        [0.91488576, 0.9526534 , 0.5791151 ],
        [0.88121283, 0.91759044, 0.5578005 ]],

       [[0.88369477, 0.9201748 , 0.5593715 ],
        [0.91746247, 0.9553365 , 0.5807462 ],
        [0.88369477, 0.9201748 , 0.5593715 ]],

       [[0.88121283, 0.91759044, 0.5578005 ],
        [0.91488576, 0.9526534 , 0.5791151 ],
        [0.88121283, 0.91759044, 0.5578005 ]]], dtype=float32)>
Defne
  • 11
  • 2
  • I'd imagine you need to pass a callable, the example you've linked is passing RandomNormal which is a class that implements has a __call__ method that accepts the shape (https://github.com/keras-team/keras/blob/v2.12.0/keras/initializers/initializers.py#L354) – David Waterworth Apr 20 '23 at 23:58
  • So try `,kernel_initializer=my_init,` instead of `,kernel_initializer=my_init((3,3,3)),` – David Waterworth Apr 20 '23 at 23:59
  • I changed to kernel_initialize = my_init I got this error: ValueError: In this `tf.Variable` creation, the initial value's shape ((3, 3, 3)) is not compatible with the explicitly supplied `shape` argument ((3, 3, 3, 4, 64)). – Defne Apr 21 '23 at 16:34
  • I don't use keras, I use torch so I can only guide you in the right direction. But conv1 has 64 filters. Your initialiser needs to be consistent with the shape Conv1D is expecting at it's cleary not (3,3,3) - I'm pretty sure that error means it's asking for a tensor of shape (3, 3, 3, 4, 64). I'm assuming the 2nd last dim aligns with the last dim of the input – David Waterworth Apr 23 '23 at 01:05
  • Try set `my_kernel = random_uniform(shape= (3, 3, 3, 4, 64))` and see if that works. Then you'll at least have the shapes correct and the next step is to get your head around what each dimension means. It may also be easier to start with `filters=1` – David Waterworth Apr 23 '23 at 01:09

0 Answers0