3D CNN - RuntimeError: Expected object of backend CPU but got backend CUDA for argument #2 'weight'

I am a beginner in Machine Learning and I want to use GPU to run my code.
it works with the CPU (without model.cuda ()), but it doesn’t work with the GPU.
Can anyone help me please?

Code :

class CNNModel(nn.Module):
    def __init__(self):
        super(CNNModel, self).__init__()
        
        self.conv_layer1 = self._conv_layer_set(3, 32) #The first dimension of Pytorch Convolution should always be
                                                        #the the number of channels (3)
        self.conv_layer2 = self._conv_layer_set(32, 64)
        self.fc1 = nn.Linear(64*28*28*28, 2)
        self.fc2 = nn.Linear(1404928, num_classes) ###### take care 
        self.relu = nn.LeakyReLU()
        self.batch=nn.BatchNorm1d(2)
        self.drop=nn.Dropout(p=0.15, inplace = True)   
        
    def _conv_layer_set(self, in_c, out_c):
        conv_layer = nn.Sequential(
        nn.Conv3d(in_c, out_c, kernel_size=(3, 3, 3), padding=0),
        nn.LeakyReLU(),
        nn.MaxPool3d((2, 2, 2)),
        )
        return conv_layer
    

    def forward(self, x):
        # Set 1
        out = self.conv_layer1(x)
        out = self.conv_layer2(out)
        out = out.view(out.size(0), -1)
        out = self.fc1(out)
        out = self.relu(out)
        out = self.batch(out)
        out = self.drop(out)
        out = F.softmax(out, dim=1)
        return out

#Definition of hyperparameters
n_iters = 2
num_epochs = 2
# Create CNN
model = CNNModel()
model.cuda()
print(model)
# Cross Entropy Loss 
for param in model.parameters():
    param.requires_grad = True
error = nn.CrossEntropyLoss()
# SGD Optimizer
learning_rate = 0.001
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

                       .....

for epoch in range(num_epochs): 
    outputs = []
    outputs= torch.tensor(outputs)
    for fold in range(0, len(training_data), 4):
        xtrain = training_data[fold : fold+4]
        xtrain = torch.Tensor(xtrain)  
        xtrain = Variable(xtrain.view(4,3,120,120,120))
        # Clear gradients
        optimizer.zero_grad()
        # Forward propagation
        v = model(xtrain)
        outputs = torch.cat((outputs,v.detach()),dim=0)
        # Calculate softmax and ross entropy loss
    targets = torch.Tensor(targets)
    labels = targets
    outputs = torch.tensor(outputs,  requires_grad=True) 
    _, predicted = torch.max(outputs, 1)
    accuracy = accuracyCalc(predicted, targets)
    labels = labels.long() 
    labels=labels.view(-1)
    loss = nn.CrossEntropyLoss()
    loss = loss(outputs, labels)    
    # Calculating gradients
    loss.backward()
    # Update parameters
    optimizer.step()
    loss_list_train.append(loss.data)
    accuracy_list_train.append(accuracy/100)

Result :

-----------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-1-927d13183a0f> in <module>
    173         optimizer.zero_grad()
    174         # Forward propagation
--> 175         v = model(xtrain)
    176         outputs = torch.cat((outputs,v.detach()),dim=0)
    177         # Calculate softmax and ross entropy loss

/opt/tljh/user/envs/fethi_env/lib/python3.6/site-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-1-927d13183a0f> in forward(self, x)
    108     def forward(self, x):
    109         # Set 1
--> 110         out = self.conv_layer1(x)
    111         out = self.conv_layer2(out)
    112         out = out.view(out.size(0), -1)

/opt/tljh/user/envs/fethi_env/lib/python3.6/site-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)

/opt/tljh/user/envs/fethi_env/lib/python3.6/site-packages/torch/nn/modules/container.py in forward(self, input)
     90     def forward(self, input):
     91         for module in self._modules.values():
---> 92             input = module(input)
     93         return input
     94 

/opt/tljh/user/envs/fethi_env/lib/python3.6/site-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)

/opt/tljh/user/envs/fethi_env/lib/python3.6/site-packages/torch/nn/modules/conv.py in forward(self, input)
    446     def forward(self, input):
    447         return F.conv3d(input, self.weight, self.bias, self.stride,
--> 448                         self.padding, self.dilation, self.groups)
    449 
    450 

RuntimeError: Expected object of backend CPU but got backend CUDA for argument #2 'weight'

thank you in advance

As the error suggests, both your model and your input to the model should lie on the same device either the CPU or the GPU. Therefore once you shift the model to gpu, shift your input tensors too. Also, I suggest to not use the Variable API as it’s an old API. Not using the Variable would do too.

xtrain = torch.tensor(xtrain).cuda()
xtrain = xtrain.view(4, 3, 120, 120, 120) # Do not use the Variable.... 

Thank you for answering @a_d
I tried this but it gives another error message

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-6-629bcd318457> in <module>
    174         # Forward propagation
    175         v = model(xtrain)
--> 176         outputs = torch.cat((outputs,v.detach()),dim=0)
    177         # Calculate softmax and ross entropy loss
    178     targets = torch.Tensor(targets)

RuntimeError: Expected object of backend CPU but got backend CUDA for sequence element 1 in sequence argument at position #1 'tensors'

This arises because the two tensors you want to cat are not on the same device, shift them either to the CPU or the GPU.

Also here you are concatenating an empty tensor to your model output, I do not know what exactly is the overall model and objective, but this statement seems to have no effect.

Here you do not need to create the tensor all over again, you could just do outputs.require_grad=True

the dataset is very large so i split it into batches of 4 items, then i concatenate the result of each batch with the other results. In this way i can use all the images in the dataset in each epoch.

I used outputs= torch.tensor(outputs).cuda() and it works ! Thank you very much @a_d