Home > OS >  Unexpected result with Conv2D layer in Keras
Unexpected result with Conv2D layer in Keras

Time:12-04

I am running some tests on Conv2D layers in Keras and I don't understand one of the result I am getting.

I am running a simple example to understand what is happening. I take a test array and create a Conv2D layer with 2 filters output. I use simple 3*3 kernel of 1's. I am expecting to have the 2 filters with the same output.

Here is my minimal code sample :

    import tensorflow.keras as keras
    import functools
    from keras import layers


    import tensorflow as tf
    import tensorflow.keras as keras
    import keras.layers as layers
    import numpy as np

    ###define a simple test array
    test_array = np.array([[2,2,2,1],[2,1,2,2],[2,2,2,2],[2,2,1,2]],dtype=np.float32)

    ###reshape to simulate a filter entry of a one channel conv2D layer
    test_array = test_array.reshape((1,4,4,1))

    ###Create conv2Dlayer and initialize
    standardConv = layers.Conv2D(filters=2,kernel_size=[3,3])
    standardConv(np.ones([1,4,4,1],dtype=np.float32))

    ###set simple weights for testing
    standardConv.set_weights([ np.ones([3,3,1,2]) , np.zeros([2]) ])

    ###apply convolution layer to test_array
    standardConv(test_array)

The result I get is the following :

Out[46]: 
    <tf.Tensor: shape=(1, 2, 2, 2), dtype=float32, numpy=
    array([[[[17., 17.],
             [16., 16.]],

            [[16., 16.],
             [16., 16.]]]], dtype=float32)>

I don't understand the second filter result [[16., 16.], [16., 16.]] What I was expecting was to see the two filters with the same result [[17,17],[16,16]] which corresponds to the convolution of my test_array with a 3x3 kernel of 1's.

The convolution weights are the same for the two filters, just ones (np.ones([3,3,1,2])) and they should be applied to the same input array as far as I understood so I am probably missing something.

Can somebody explain me how we get the second filter result and why it is not the same as the first in this case ?

CodePudding user response:

The layout is a bit misleading; both filters give the same correct result.

First filter:

print(standardConv(test_array)[:, :, :, 0])

Output:

tf.Tensor(
[[[17. 16.]
  [16. 16.]]], shape=(1, 2, 2), dtype=float32)

Second filter:

print(standardConv(test_array)[:, :, :, 1])

Output:

tf.Tensor(
[[[17. 16.]
  [16. 16.]]], shape=(1, 2, 2), dtype=float32)

When you use more filters, for example 5, you will get this output:

tf.Tensor(
[[[[17. 17. 17. 17. 17.]
   [16. 16. 16. 16. 16.]]

  [[16. 16. 16. 16. 16.]
   [16. 16. 16. 16. 16.]]]], shape=(1, 2, 2, 5), dtype=float32)
  • Related