Very simple conv2d model

16 views
Skip to first unread message

Rupert Young

unread,
Aug 3, 2020, 3:15:36 PM8/3/20
to Discuss
To understand what conv2d is doing I am trying to create a really basic model so that the output is activation of a 3x3 kernal centred over a 3x3 image. 

Will this do it?

def create_model():
    sub_image = keras.layers.Input(shape=INPUT_SHAPE, name="image")
    c2d=keras.layers.Conv2D(1, (CONV_SIZE, CONV_SIZE), strides=(2, 2), use_bias=False, name="C2D")(sub_image)
    output = keras.layers.Dense(1, name="action",use_bias=False,trainable=False)(c2d)
    model = keras.models.Model(inputs=sub_image, outputs=output, name=model_name)   
    return model

Model: "SingleC2D"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
image (InputLayer)           [(None, 3, 3, 1)]         0         
_________________________________________________________________
C2D (Conv2D)                 (None, 1, 1, 1)           9         
_________________________________________________________________
action (Dense)               (None, 1, 1, 1)           1         
=================================================================
Total params: 10
Trainable params: 9
Non-trainable params: 1

I do not want the kernel to move across the image, so have set strides to 2, assuming that this will mean that it wil start 2 pixels across and 2 down; the centre. Is that right?

However, if my image is,

[[1. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]]

and my initial weights are,

[[ 0.09251362  0.00528854  0.48690206]
 [ 0.22370386  0.02439701  0.16458619]
 [-0.53264564 -0.04675359 -0.1529859 ]]

I am expecting output of the model would be the sum of the weights (as the image points are 1) which is 0.26500615.

However, the output of the model,

out = model(inputs).numpy()[0][0][0][0]
print(out)

gives -0.21157242.

Am I misunderstanding something here?

Sambath S

unread,
Aug 3, 2020, 3:38:16 PM8/3/20
to Discuss
Did you try this without the Dense layer ?
If you are adding a dense layer, then essentially you are adding one more parameter(weights), So that will also be used while computing the output.
Setting the trainable=False will make sure that this initialized weight is not updated when you do the optimization.(its still there).

Rupert Young

unread,
Aug 3, 2020, 4:07:35 PM8/3/20
to dis...@tensorflow.org

Hi,

Thanks for your reply.

> Did you try this without the Dense layer ?

I didn't, though it is set as trainable=False.

Is the output of conv2d a single value, in this case?

--
You received this message because you are subscribed to the Google Groups "Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to discuss+u...@tensorflow.org.
To view this discussion on the web visit https://groups.google.com/a/tensorflow.org/d/msgid/discuss/3909fc17-3445-492f-835a-5ce63f181eeco%40tensorflow.org.

Sambath S

unread,
Aug 3, 2020, 4:13:49 PM8/3/20
to Discuss
Yes it is, you could refer the model.summary() to see the shape.
Intuitively, When you do a convolution, it reduces the 3x3 image to just a single value.
Convolution GIFs - Get the best GIF on GIPHY
Since in this case, the kernel can move over the entire image in one operation(due to size of the input image == kernel_size and strides set in this case)

To unsubscribe from this group and stop receiving emails from it, send an email to dis...@tensorflow.org.

Sambath S

unread,
Aug 3, 2020, 4:17:16 PM8/3/20
to Discuss
Setting trainable=False just makes sure that the weights of that layer is not updated during optimization.
That weight(which was initialized when the model was created) will be there and that would used while computing the output.

You can see that with model.weights

You can try to compute the output considering that weight too and see if it matches the output.

Robert Lugg

unread,
Aug 3, 2020, 4:24:15 PM8/3/20
to Discuss, rupert...@googlemail.com
Get the weight of that dense layer and multiply it by the sum of your Conv2d Layer.
Here is an example based on your code:
from tensorflow import keras
import numpy as np
from IPython import embed


INPUT_SHAPE = (3, 3, 1)
CONV_SIZE = 3
model_name = 'test_model'


def create_model():
    sub_image = keras.layers.Input(shape=INPUT_SHAPE, name="image")
    c2d=keras.layers.Conv2D(1, (CONV_SIZE, CONV_SIZE), use_bias=False, name="C2D")(sub_image)

    output = keras.layers.Dense(1, name="action",use_bias=False,trainable=False)(c2d)
    model = keras.models.Model(inputs=sub_image, outputs=output, name=model_name)  
    return model

input = np.ones((1, 3, 3, 1), dtype=np.float)

embed()

model = create_model()
result = model(input)

hl1_weights = model.layers[1].get_weights()
print(np.sum(hl1_weights))

hl2_weights = model.layers[2].get_weights()
print(np.sum(hl2_weights))

print(np.sum(hl1_weights) * np.sum(hl2_weights))

print(f'tf run sum={result}')

Rupert Young

unread,
Aug 4, 2020, 4:18:58 AM8/4/20
to Robert Lugg, Discuss

Ah, yes, that does it, thanks!

I guess I was assuming that as the dense layer was non-trainable that there wouldn't be a weight (or would be 1).

I'll try by making the adjustment, or remove the dense layer as Sambath suggests.

Then I'll try training, as I am assuming the weights will then adjust to the image contents.

Reply all
Reply to author
Forward
0 new messages