# How to define the kernel size for conv2d

if I wanna do simple convolution i can use conv2d.
I want to simply compute the edge of my input (the input has the size of `BxCxDxD`), and my edge kernel has the size of `3x3`, how should i expand my edge kernel so when i do `conv2d(Input, Kernel)` the output has the same size of `BxCxDxD`

e.g.

``````
import torch
import torch.nn.functional as F
K =  torch.Tensor([[1 ,0, -1],[2, 0 ,-2], [1, 0 ,-1]])
Input = torch.rand(4,3,10,10)

output.size() # expected to be 4x3x10x10
``````

Say your input is ( Batch, input_channel, 64, 64)
Conv2D( input_channel, output_channel, 3, 1, 1) give you back the same size as the image.

output would be:

`(Batch, output_channel, 64, 64)`

Setting k_size, stride, padding, to 4, 2, 1 instead of 3, 1, 1 will give you `( Batch output_channel, 32, 32 )` instead.

In order to get the same output shape BxCxDxD you have to do two things:

to keep DxD: use padding, in your case padding=(1,1). This adds a â€śborderâ€ť of zeros around your input, so the center of a 3x3 kernel can visit every point on your DxD grid (looking at your CxDxD stack â€śtop-downâ€ť so to say).

to keep the number of channels C the same: use C kernels, the number of channels of the output of conv2d will always be the number of kernels used.

adding such a layer to a model in pytorch would look like this:
`self.conv = nn.Conv2d(in_channels=C, out_channels=C, kernel_size=(3, 3), padding=(1, 1))`

Thanks for your answer, but that is not how i want to use the conv2d.
I want to use conv2d like this:

``````import torch
import torch.nn.functional as F
K =  torch.Tensor([[1 ,0, -1],[2, 0 ,-2], [1, 0 ,-1]])
Input = torch.rand(4,3,10,10)

output.size() # expected to be 4x3x10x10
``````

I think you are confusing your self, kernels in conv2d are already randomly defined for you.
You can check this by doing this:

``````X = nn.Conv2D( 1, 1, 3, 1, 1) #  ( input_c, output_c, k_size, stride, padding ), k_size can be (3,3) or 3
X.weight # a single 3 x 3 kernel, if you want to output more kernels you can try and change "output_c" to see what happens
``````
``````Parameter containing:
tensor([[[[-0.2303, -0.0186, -0.2070],
[ 0.3190, -0.2940, -0.1227],
[ 0.1014,  0.0417, -0.3254]]]])
``````

I am guessing you want to use predefined weights as values for the kernel in conv2D correct?
If so you can do the following.

``````X = torch.Tensor([[1 ,0, -1],[2, 0 ,-2], [1, 0 ,-1]])
X = torch.nn.Parameter( X ) # calling this turns tensor into "weight" parameter
print( "X's size", X.size() )
print("X's tensor values as weight: ", X)
Z = nn.Conv2d( 1, 1, 3, 1, 1) # creates a test convolution
print("Z's pre-initalized weight from Conv2D: ", Z.weight, "its size is: ", Z.weight.size())
Z.weight = X # simply copying over the new weight
print("Z's new weight ", Z.weight)
``````

Xâ€™s size torch.Size([3, 3])
Xâ€™s tensor values as weight: Parameter containing:

tensor([
[ 1., 0., -1.],
[ 2., 0., -2.],
[ 1., 0., -1.]])

Zâ€™s pre-initalized weight from Conv2D: Parameter containing:

tensor([[[
[-0.1911, 0.0187, 0.0254],
[-0.0727, -0.1672, 0.0862],
[ 0.2888, 0.2479, 0.3203]]]])

Its size is: torch.Size([1, 1, 3, 3])

Zâ€™s new weight Parameter containing:

tensor([
[ 1., 0., -1.],
[ 2., 0., -2.],
[ 1., 0., -1.]])

Edited Finally if you want to make sure the output size is correct the above 2 post has the answers. You can also google the output convolution formula and the documentations for Conv2D also has it. Good Luck!

1 Like

Hi,

I want to apply Conv2d to [64, 49,49,512] to reduce it to [64, 25,25,512].
I need to consider kernel_size=23, right?

I think your dimensions might be wrong.
`nn.Conv2d` expects inputs of `[batch_size, channels, height, width]`.
Based on your example, it seems you are using `512` channels, while the spatial size is `49x49`.
If thatâ€™s the case, a kernel_size of `25` with `stride=1` and no padding might work:

``````conv = nn.Conv2d(512, 512, 25)
output = conv(torch.randn(1, 512, 49, 49))
print(output.size())
> torch.Size([1, 512, 25, 25])
``````

Hi @ptrblck
Thanks. Actually the feature map is in size [64, 512, 49, 49]. And by applying those values it doesnâ€™t work/

conv= nn.Conv2d(512,512,kernel_size=25)
SO_fmaps_extend = conv(fmaps)

*** RuntimeError: Input type (CUDAFloatTensor) and weight type (CPUFloatTensor) should be the same

Since `fmaps` is stored in your GPU, you should also push the conv layer to your device using `conv.to('cuda')`.