Type check error on conv2d_transpose

Hi guys I am trying to use conv2d_transpose as upscaling op (with nearest interpolation), although there’s a special op for that.

In my case, trying to upscale 2x2 so in order to keep the number of input/output channels the same, I’m using groups=num of channels.

For example: input: 1x2x2x2 output: 1x2x4x4

I believe the weights should be ones with shape 2x1x2x2

But I get an error with type checker:

def @main(%input: Tensor[(1, 2, 2, 2), float32] /* ty=Tensor[(1, 2, 2, 2), float32] */) -> Tensor[(1, 2, 4, 4), float32] {
  nn.conv2d_transpose(%input, meta[relay.Constant][0], strides=[2, 2], padding=[0, 0, 0, 0], groups=2)
}

The weights: weight.data.shape (2, 1, 2, 2)

The error:

The Relay type checker is unable to show the following types match:

Tensor[(1, 1, 4, 4), float32] Tensor[(1, 2, 4, 4), float32] In particular: dimension 1 conflicts: 1 does not match 2. The Relay type checker is unable to show the following types match. In particular Tensor[(1, 2, 4, 4), float32] does not match Tensor[(1, 1, 4, 4), float32]

Am I doing something wrong? Is this a bug?

Can you try using channels with groups?

input_shape = (1, 2, 2, 2)
weight_shape = (2, 1, 2, 2)
input_tensor = relay.var("input", shape=input_shape, dtype="float32")
weights = relay.const(np.ones(weight_shape, dtype="float32"), dtype="float32")
output_tensor = relay.nn.conv2d_transpose(input_tensor, weights, strides=(2, 2), padding=(0, 0, 0, 0), groups=2, channels=2)

This should work.

Hi @AQSingh, thanks for your comment. When I try using groups and channels together I get this error trying to build the relay function:

The Relay type checker is unable to show the following types match: Tensor[(1, 1, 26, 26), float32] Tensor[(1, 256, 26, 26), float32] In particular: dimension 1 conflicts: 1 does not match 256. The Relay type checker is unable to show the following types match. In particular Tensor[(1, 256, 26, 26), float32] does not match Tensor[(1, 1, 26, 26), float32]

The input tensor in this case is (1,256,13,13) and I’m trying to upscale it by 2 (for all 256 channels).

The code:

scale_h = int(2)
scale_w = int(2)
weight = relay.const(np.ones((int(input.checked_type.shape[1]), 1, int(scale_h), int(scale_w))), dtype="float32")
conv2d_transpose = relay.op.nn.conv2d_transpose(input, weight, strides=(int(scale_h), int(scale_w)),  padding=(0,0,0,0), groups=int(input.checked_type.shape[1]), channels=int(input.checked_type.shape[1]))

Though out of frustration I tried many combinations of parameters and it worked for the following combination:

    conv2d_transpose = relay.op.nn.conv2d_transpose(input, weight, strides=(int(scale_h), int(scale_w)), padding=(0,0), dilation=(1,1), groups=int(input.checked_type.shape[1]), channels=int(input.checked_type.shape[1]), kernel_size=(2,2), data_layout="NCHW", kernel_layout="IOHW") 

I guess it has something to do with the data_layout and kernel_layout stated explicitly. What do you think? Looking at the conv2d_transpose implementation I feel like it misses some cases…