user14924
user14924

Reputation: 157

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

When I try to train the model I get the following error:

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

The code I'm using is:

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 6, kernel_size=5)
        self.conv2 = nn.Conv2d(6, 16, kernel_size=5)
        self.dropout = nn.Dropout2d()
        self.fc1 = nn.Linear(256, 64)
        self.fc2 = nn.Linear(64, 1)
        self.hybrid = Hybrid(qiskit.Aer.get_backend('qasm_simulator'), 100, np.pi / 2)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = F.max_pool2d(x, 2)
        x = F.relu(self.conv2(x))
        x = F.max_pool2d(x, 2)
        x = self.dropout(x)
        x = x.view(1, -1)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        x = self.hybrid(x)
        return torch.cat((x, 1 - x), -1)

model = Net()
optimizer = optim.Adam(model.parameters(), lr=0.001)
loss_func = nn.NLLLoss()

epochs = 20
loss_list = []

model.train()

for epoch in range(epochs):
    total_loss = []

    for i, data in enumerate(train_ldr, 0):
        # get the inputs; data is a list of [inputs, labels]
        X_train, Y_train = data
        print(data)
        optimizer.zero_grad()
         
        # Forward pass
        output = model(X_train)
        # Calculating loss
        loss = loss_func(output, Y_train)
        # Backward pass
        loss.backward()
        # Optimize the weights
        optimizer.step()
        
        total_loss.append(loss.item())
    loss_list.append(sum(total_loss)/len(total_loss))
    print('Training [{:.0f}%]\tLoss: {:.4f}'.format(
        100. * (epoch + 1) / epochs, loss_list[-1]))

The full traceback is:

{'data': tensor([[715.9147, 679.4994, 131.4772,   9.4777,   9.4777,  13.8722,  85.8577,
           2.5333]]), 'Target': tensor([0])}

TypeError                                 Traceback (most recent call last)
<ipython-input-52-7c8c9f3a38b7> in <module>
     20 
     21         # Forward pass
---> 22         output = model(X_train)
     23         # Calculating loss
     24         loss = loss_func(output, Y_train)

~\anaconda3\lib\site-packages\torch\nn\modules\module.py in _call_impl(self, *input, **kwargs)
    887             result = self._slow_forward(*input, **kwargs)
    888         else:
--> 889             result = self.forward(*input, **kwargs)
    890         for hook in itertools.chain(
    891                 _global_forward_hooks.values(),

<ipython-input-39-6b9a402c220d> in forward(self, x)
     10 
     11     def forward(self, x):
---> 12         x = F.relu(self.conv1(x))
     13         x = F.max_pool2d(x, 2)
     14         x = F.relu(self.conv2(x))

~\anaconda3\lib\site-packages\torch\nn\modules\module.py in _call_impl(self, *input, **kwargs)
    887             result = self._slow_forward(*input, **kwargs)
    888         else:
--> 889             result = self.forward(*input, **kwargs)
    890         for hook in itertools.chain(
    891                 _global_forward_hooks.values(),

~\anaconda3\lib\site-packages\torch\nn\modules\conv.py in forward(self, input)
    397 
    398     def forward(self, input: Tensor) -> Tensor:
--> 399         return self._conv_forward(input, self.weight, self.bias)
    400 
    401 class Conv3d(_ConvNd):

~\anaconda3\lib\site-packages\torch\nn\modules\conv.py in _conv_forward(self, input, weight, bias)
    393                             weight, bias, self.stride,
    394                             _pair(0), self.dilation, self.groups)
--> 395         return F.conv2d(input, weight, bias, self.stride,
    396                         self.padding, self.dilation, self.groups)
    397 

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

When I try to debug the code, the X_train and Y_train hold 'Data' & 'Target'. I don't understand why the tensor values are not being taken by the enumerate (dataloader) in the for loop.

As otherwise, values are present in the dataloader. If each tensor row in the dataset has 'Data' and 'Target' prefixed before it, how do I remove that. Please suggest any solution.

Upvotes: 2

Views: 6662

Answers (1)

David
David

Reputation: 8298

The problem is that data is a dictionary and when you unpack it the way you did (X_train, Y_train = data) you unpack the keys while you are interested in the values.

refer to this simple example:

d = {'a': [1,2], 'b': [3,4]}
x, y = d
print(x,y) # a b

So you should change this:

X_train, Y_train = data

into this:

X_train, Y_train = data.values()

Upvotes: 2

Related Questions