Kernel size can't greater than actual input size

Hi,
I’m getting the following error.

RuntimeError: Calculated padded input size per channel: (1017 x 1). 
Kernel size: (3 x 3). 
Kernel size can't greater than actual input size at /opt/conda/conda-bld/pytorch_1524584710464/work/aten/src/THNN/generic/SpatialConvolutionMM.c:48

My input tensor has size [1,1,1025,15]
Following is my Network:

MeeAutoEncoder(
  (encoder): MeeEncoder(
    (en_layer1): Conv2d(1, 12, kernel_size=(3, 3), stride=(1, 1))
    (en_layer2): MaxPool2d(kernel_size=(3, 5), stride=1, padding=0, dilation=1, ceil_mode=False)
    (en_layer3): Conv2d(12, 20, kernel_size=(3, 3), stride=(1, 1))
    (en_layer4): MaxPool2d(kernel_size=(1, 5), stride=1, padding=0, dilation=1, ceil_mode=False)
    (en_layer5): Conv2d(20, 30, kernel_size=(3, 3), stride=(1, 1))
    (en_layer6): Conv2d(30, 40, kernel_size=(3, 3), stride=(1, 1))
    (en_layerReLU): ReLU()
    (encoder): Sequential(
      (0): Conv2d(1, 12, kernel_size=(3, 3), stride=(1, 1))
      (1): ReLU()
      (2): MaxPool2d(kernel_size=(3, 5), stride=1, padding=0, dilation=1, ceil_mode=False)
      (3): Conv2d(12, 20, kernel_size=(3, 3), stride=(1, 1))
      (4): ReLU()
      (5): MaxPool2d(kernel_size=(1, 5), stride=1, padding=0, dilation=1, ceil_mode=False)
      (6): Conv2d(20, 30, kernel_size=(3, 3), stride=(1, 1))
      (7): ReLU()
      (8): Conv2d(30, 40, kernel_size=(3, 3), stride=(1, 1))
    )
  )
  (decoder): MeeDecoder(
    (de_layer1): Conv2d(40, 30, kernel_size=(3, 3), stride=(1, 1))
    (de_layer2): Conv2d(30, 20, kernel_size=(3, 3), stride=(1, 1))
    (de_layer3): Upsample(size=(5, 205), mode=bilinear)
    (de_layer4): Conv2d(20, 12, kernel_size=(3, 3), stride=(1, 1))
    (de_layer5): Upsample(size=(15, 1025), mode=bilinear)
    (de_layer6): Conv2d(12, 1, kernel_size=(3, 3), stride=(1, 1))
    (de_layerReLU): ReLU()
    (decoder): Sequential(
      (0): Conv2d(40, 30, kernel_size=(3, 3), stride=(1, 1))
      (1): ReLU()
      (2): Conv2d(30, 20, kernel_size=(3, 3), stride=(1, 1))
      (3): ReLU()
      (4): Upsample(size=(5, 205), mode=bilinear)
      (5): Conv2d(20, 12, kernel_size=(3, 3), stride=(1, 1))
      (6): ReLU()
      (7): Upsample(size=(15, 1025), mode=bilinear)
      (8): Conv2d(12, 1, kernel_size=(3, 3), stride=(1, 1))
      (9): ReLU()
    )
  )
)
1 Like

Your last conv layer in your encoder throws this error, since it receives an input of [1, 30, 1017, 1] and tries to use kernel_size=3.
You have to lower the kernel size to 1 or modify your model somewhere before this layer.

7 Likes

Thanks @ptrblck. It solved the issue.

I got a similar error as below

“Calculated padded input size per channel: (3 x 3). Kernel size: (5 x 5). Kernel size can’t greater than actual input size at /pytorch/aten/src/THNN/generic/SpatialConvolutionMM.c:48”

I was try to load pretrained inception model and test a image
‘’
net = models.inception_v3(pretrained=False)
net.fc = nn.Linear(2048, 2)
net_dict = torch.load(‘model_inception.pt’)

print net

net.load_state_dict(net_dict[‘state_dict’])
#checkpoint = torch.load(Path(‘model_resnet.pt’))
#model.load_state_dict(checkpoint)
trans = transforms.Compose([
transforms.RandomHorizontalFlip(),
transforms.Resize((229,229)),

transforms.ToTensor(),
#transforms.Normalize((0.5, 0.5, 0.5),(0.5, 0.5, 0.5))
])

#for file in glob(’.png’):
for file in glob.glob("/home/CN/
.png"):
#print (file)
img_pil= Image.open(file)
input = trans(img_pil)

input = input.view(1, 3, 229,229)

output = net(input)

prediction = int(torch.max(output.data, 1)[1].numpy())
#print(prediction)

if (prediction == 0):
    print ('AD')
if (prediction == 1):
    print ('CN')
    
print((file,prediction))

    
    
    
prob = F.softmax(output, dim=1)
print prob

‘’

Hello,
I am trying to convert the 2d R2AttentionUNET to 3D architeecture.The code is below.The error is given below .I think I need to change padding size also as I just changed the Con2d to conv3d and batch2d to batch3d.But I don’t have much idea. Can anybody see the code and reply?
RuntimeError: Calculated padded input size per channel: (2 x 2 x 2). Kernel size: (3 x 3 x 3). Kernel size can’t be greater than actual input size.

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.nn import init
from torchsummary import summary

def init_weights(net, init_type=‘normal’, gain=0.02):
def init_func(m):
classname = m.class.name
if hasattr(m, ‘weight’) and (classname.find(‘Conv’) != -1 or classname.find(‘Linear’) != -1):
if init_type == ‘normal’:
init.normal_(m.weight.data, 0.0, gain)
elif init_type == ‘xavier’:
init.xavier_normal_(m.weight.data, gain=gain)
elif init_type == ‘kaiming’:
init.kaiming_normal_(m.weight.data, a=0, mode=‘fan_in’)
elif init_type == ‘orthogonal’:
init.orthogonal_(m.weight.data, gain=gain)
else:
raise NotImplementedError(‘initialization method [%s] is not implemented’ % init_type)
if hasattr(m, ‘bias’) and m.bias is not None:
init.constant_(m.bias.data, 0.0)
elif classname.find(‘BatchNorm3d’) != -1:
init.normal_(m.weight.data, 1.0, gain)
init.constant_(m.bias.data, 0.0)

print('initialize network with %s' % init_type)
net.apply(init_func)

class conv_block(nn.Module):
def init(self, ch_in, ch_out):
super(conv_block, self).init()
self.conv = nn.Sequential(
nn.Conv3d(ch_in, ch_out, kernel_size=3, stride=1, padding=1, bias=True),
nn.BatchNorm3d(ch_out),
nn.ReLU(inplace=True),
nn.Conv3d(ch_out, ch_out,kernel_size=3, stride=1, padding=1, bias=True),
nn.BatchNorm3d(ch_out),
nn.ReLU(inplace=True)
)

def forward(self, x):
    x = self.conv(x)
    return x

class up_conv(nn.Module):
def init(self, ch_in, ch_out):
super(up_conv, self).init()
self.up = nn.Sequential(
nn.Upsample(scale_factor=2),
nn.Conv3d(ch_in, ch_out, kernel_size=3, stride=1, padding=1, bias=True),
nn.BatchNorm3d(ch_out),
nn.ReLU(inplace=True)
)

def forward(self, x):
    x = self.up(x)
    return x

class Recurrent_block(nn.Module):
def init(self, ch_out, t=2):
super(Recurrent_block, self).init()
self.t = t
self.ch_out = ch_out
self.conv = nn.Sequential(
nn.Conv3d(ch_out, ch_out, kernel_size=3, stride=1, padding=1, bias=True),
nn.BatchNorm3d(ch_out),
nn.ReLU(inplace=True)
)

def forward(self, x):
    for i in range(self.t):

        if i == 0:
            x1 = self.conv(x)

        x1 = self.conv(x + x1)
    return x1

class RRCNN_block(nn.Module):
def init(self, ch_in, ch_out, t=2):
super(RRCNN_block, self).init()
self.RCNN = nn.Sequential(
Recurrent_block(ch_out, t=t),
Recurrent_block(ch_out, t=t)
)
self.Conv_1x1 = nn.Conv3d(ch_in, ch_out, kernel_size=3, stride=1)

def forward(self, x):
    x = self.Conv_1x1(x)
    x1 = self.RCNN(x)
    return x + x1

class single_conv(nn.Module):
def init(self, ch_in, ch_out):
super(single_conv, self).init()
self.conv = nn.Sequential(
nn.Conv3d(ch_in, ch_out, kernel_size=3, stride=1, padding=1, bias=True),
nn.BatchNorm3d(ch_out),
nn.ReLU(inplace=True)
)

def forward(self, x):
    x = self.conv(x)
    return x

class Attention_block(nn.Module):
def init(self, F_g, F_l, F_int):
super(Attention_block, self).init()
self.W_g = nn.Sequential(
nn.Conv3d(F_g, F_int, kernel_size=3, stride=1, padding=0, bias=True),
nn.BatchNorm3d(F_int)
)

    self.W_x = nn.Sequential(
        nn.Conv3d(F_l, F_int, kernel_size=3, stride=1, padding=0, bias=True),
        nn.BatchNorm3d(F_int)
    )

    self.psi = nn.Sequential(
        nn.Conv3d(F_int, 1, kernel_size=3, stride=1, padding=0, bias=True),
        nn.BatchNorm3d(1),
        nn.Sigmoid()
    )

    self.relu = nn.ReLU(inplace=True)

def forward(self, g, x):
    g1 = self.W_g(g)
   # print(g1.shape)
    x1 = self.W_x(x)
   # print(x1.shape)
    psi = self.relu(g1 + x1)
   # print(psi.shape)
    psi = self.psi(psi)
    print(psi.shape)
    print(x.shape)

    return x * psi

class R2AttU_Net(nn.Module):
def init(self, img_ch=1, output_ch=1, t=2):
super(R2AttU_Net, self).init()

    self.Maxpool = nn.MaxPool3d(kernel_size=2, stride=2)
    self.Upsample = nn.Upsample(scale_factor=2)

    self.RRCNN1 = RRCNN_block(ch_in=img_ch, ch_out=64, t=t)

    self.RRCNN2 = RRCNN_block(ch_in=64, ch_out=128, t=t)

    self.RRCNN3 = RRCNN_block(ch_in=128, ch_out=256, t=t)

    self.RRCNN4 = RRCNN_block(ch_in=256, ch_out=512, t=t)

    self.RRCNN5 = RRCNN_block(ch_in=512, ch_out=1024, t=t)

    self.Up5 = up_conv(ch_in=1024, ch_out=512)
    self.Att5 = Attention_block(F_g=512, F_l=512, F_int=256)
    self.Up_RRCNN5 = RRCNN_block(ch_in=1024, ch_out=512, t=t)

    self.Up4 = up_conv(ch_in=512, ch_out=256)
    self.Att4 = Attention_block(F_g=256, F_l=256, F_int=128)
    self.Up_RRCNN4 = RRCNN_block(ch_in=512, ch_out=256, t=t)

    self.Up3 = up_conv(ch_in=256, ch_out=128)
    self.Att3 = Attention_block(F_g=128, F_l=128, F_int=64)
    self.Up_RRCNN3 = RRCNN_block(ch_in=256, ch_out=128, t=t)

    self.Up2 = up_conv(ch_in=128, ch_out=64)
    self.Att2 = Attention_block(F_g=64, F_l=64, F_int=32)
    self.Up_RRCNN2 = RRCNN_block(ch_in=128, ch_out=64, t=t)

    self.Conv_1x1 = nn.Conv3d(64, output_ch, kernel_size=1, stride=1, padding=0)

def forward(self, x):
    # encoding path
    x1 = self.RRCNN1(x)

    x2 = self.Maxpool(x1)
    x2 = self.RRCNN2(x2)

    x3 = self.Maxpool(x2)
    x3 = self.RRCNN3(x3)

    x4 = self.Maxpool(x3)
    x4 = self.RRCNN4(x4)

    x5 = self.Maxpool(x4)
    x5 = self.RRCNN5(x5)

    # decoding + concat path
    d5 = self.Up5(x5)
    x4 = self.Att5(g=d5, x=x4)
    d5 = torch.cat((x4, d5), dim=1)
    d5 = self.Up_RRCNN5(d5)

    d4 = self.Up4(d5)
    x3 = self.Att4(g=d4, x=x3)
    d4 = torch.cat((x3, d4), dim=1)
    d4 = self.Up_RRCNN4(d4)

    d3 = self.Up3(d4)
    x2 = self.Att3(g=d3, x=x2)
    d3 = torch.cat((x2, d3), dim=1)
    d3 = self.Up_RRCNN3(d3)

    d2 = self.Up2(d3)
    x1 = self.Att2(g=d2, x=x1)
    d2 = torch.cat((x1, d2), dim=1)
    d2 = self.Up_RRCNN2(d2)

    d1 = self.Conv_1x1(d2)

    return d1

if name == “main”:
inputs = torch.randn(1, 1, 64, 64, 64)
print("The shape of inputs: ", inputs.shape)
data_folder = “…/processed”
model = R2AttU_Net()
inputs = inputs.cuda()
model.cuda()
x = model(inputs)
print(model)
summary(model, x)

Hi, can a support for automatic padding be done to stop this behavior, perhaps just a warning. I’ve to perform NAS over a model space which might give this, but its’ very hard to detect or control when this can happen. I am going to use a custom Conv2d for time being, I guess.

I think a custom module sounds reasonable, as you could check the shape of the incoming tensor and pad it as needed using F.pad. I don’t think there is a built-in module to do it now.

how did you solve this issue ?