Conv2d(): argument 'input' (position 1) must be Tensor, not module


(Vali Calinescu) #1

Hello,
I am trying to make an encoder-decoder network, but I can’t seem to be able to start the training.
Here is the code for the network:

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, 9, 1)
        self.pool1 = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(32, 64, 3, 2)
        self.conv3 = nn.Conv2d(64, 128, 3, 2)
        self.pool2 = nn.MaxPool2d(2, 1/2)
        self.conv4 = nn.Conv2d(128, 64, 3, 1/2)
        self.conv5 = nn.Conv2d(64, 32, 3, 1/2)
        self.conv6 = nn.Conv2d(32, 3, 3, 1)

    def forward(self, x):
        x = self.pool1(F.relu(self.conv1(x)))
        x = self.pool1(F.relu(self.conv2(x)))
        x = self.pool1(F.relu(self.conv3(x)))
        x = self.pool2(F.relu(self.conv4(x)))
        x = self.pool2(F.relu(self.conv5(x)))
        x = self.pool2(F.relu(self.conv6(x)))
        return x

def train(args, model, device, train_loader, optimizer, epoch):
  model.train()
  for batch_idx, image in enumerate(train_loader):
      optimizer.zero_grad()
      output = model(data)
      loss = F.mse_loss(output, image.convert('L'))
      loss.backward()
      optimizer.step()
      if batch_idx % args.log_interval == 0:
          print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
              epoch, batch_idx * len(data), len(train_loader.dataset),
              100. * batch_idx / len(train_loader), loss.item()))

def test(args, model, device, test_loader):
    model.eval()
    test_loss = 0
    correct = 0
    with torch.no_grad():
        for data in test_loader:
            output = model(data)
            test_loss += F.mse_loss(output, data.convert('L'), reduction='sum').item() # sum up batch loss
            correct += output.eq(image.convert('L')).sum().item()

    test_loss /= len(test_loader.dataset)

    print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        100. * correct / len(test_loader.dataset)))

However, when I am trying to run the training I get this error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-48-0270fa135195> in <module>()
      4 
      5 for epoch in range(1, args.epochs):
----> 6     train(args, model, device, train_loader, optimizer, epoch)
      7     test(args, model, device, test_loader)

<ipython-input-47-a057de3dfe5e> in train(args, model, device, train_loader, optimizer, epoch)
     24   for batch_idx, image in enumerate(train_loader):
     25       optimizer.zero_grad()
---> 26       output = model(data)
     27       loss = F.mse_loss(output, image.convert('L'))
     28       loss.backward()

/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    487             result = self._slow_forward(*input, **kwargs)
    488         else:
--> 489             result = self.forward(*input, **kwargs)
    490         for hook in self._forward_hooks.values():
    491             hook_result = hook(self, input, result)

<ipython-input-47-a057de3dfe5e> in forward(self, x)
     12 
     13     def forward(self, x):
---> 14         x = self.pool1(F.relu(self.conv1(x)))
     15         x = self.pool1(F.relu(self.conv2(x)))
     16         x = self.pool1(F.relu(self.conv3(x)))

/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    487             result = self._slow_forward(*input, **kwargs)
    488         else:
--> 489             result = self.forward(*input, **kwargs)
    490         for hook in self._forward_hooks.values():
    491             hook_result = hook(self, input, result)

/usr/local/lib/python3.6/dist-packages/torch/nn/modules/conv.py in forward(self, input)
    318     def forward(self, input):
    319         return F.conv2d(input, self.weight, self.bias, self.stride,
--> 320                         self.padding, self.dilation, self.groups)
    321 
    322 

TypeError: conv2d(): argument 'input' (position 1) must be Tensor, not module

I am trying to run the training with:

model = CNN().to(device)

optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum)

for epoch in range(1, args.epochs):
    train(args, model, device, train_loader, optimizer, epoch)

#2

Could you check the type of data?
Also, once this is fixed, it looks like you are trying to pass a PIL.Image as the target to F.mse_loss. This will throw the next error, since a tensor is expected.


(Vali Calinescu) #3

Thanks, I figured out that I should have done some preprocessing. However, I would like to ask you something else. Is there a way to use a max_pool or a conv2d with stride 1/2? If I try to use 1/2 as an argument I get an error saying that I can only use int. I am trying to increase the image size for the decoding part of the network.


(Lalu Erfandi Maula Yusnu) #4

max_pool only use integer as stride. If you mean you want to make the shape of the picture more smaller than use 2, because with stride 2 you tell to max pool to do shape/2.


(Vali Calinescu) #5

I would like to make it bigger. Is there any way to do that?


#6

Have you tried transposed_conv2d or binlinear_upsampling?


(Lalu Erfandi Maula Yusnu) #7

You can use this to make shape of your picture bigger, scale_factor=2 mean you scale it twice.

 nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)