AttributeError: 'DataLoader' object has no attribute 'dim'

I was creating a regression model using simple neural network and built my model as follows:
The shape of input variable X_train is (1086, 76), which is a DataFrame

from torch import nn
from torch.nn import functional as F
class NeuralNet(nn.Module):
    def __init__(self):
        super(NeuralNet, self).__init__()
        self.linear1 = nn.Linear(76, 30)
        self.linear2 = nn.Linear(30, 10);
        self.linear3 = nn.Linear(10, 1)
#         self.relu = nn.ReLU()
    def forward(self, x):
        x = F.relu(self.linear1(x))
        x = F.relu(self.linear2(x))
        x = F.relu(self.linear3(x))
        return x
model = NeuralNet()
print(model)

Here I have used a DataLoader, but when I try to run it without the DatLoader, it gives me the same error with a DataFrame. I started writing the training code:

import torch.optim as optim
import torch
from torch.utils.data import DataLoader

train_loader = DataLoader(X_train)

epochs = 10
for i,e in enumerate(range(epochs)):
    optimizer.zero_grad() # Reset the grads
    output = model.forward(train_loader) # Forward pass
    loss = criterion(output.view(output.shape[0]),y) # Calculate loss
    print(f"Epoch - {i+1}, Loss - {round(loss.item(),3)}")  # Print loss
    loss.backward() # Backpropagation
    optimizer.step() # Optimizer one step

Where it has been giving me an error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-165-69744667c9a4> in <module>
      8 for i,e in enumerate(range(epochs)):
      9     optimizer.zero_grad() # Reset the grads
---> 10     output = model.forward(train_loader) # Forward pass
     11     loss = criterion(output.view(output.shape[0]),y) # Calculate loss
     12     print(f"Epoch - {i+1}, Loss - {round(loss.item(),3)}")  # Print loss

<ipython-input-164-caccab51ac99> in forward(self, x)
      9 #         self.relu = nn.ReLU()
     10     def forward(self, x):
---> 11         x = F.relu(self.linear1(x))
     12         x = F.relu(self.linear2(x))
     13         x = F.relu(self.linear3(x))

/opt/conda/lib/python3.7/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    548             result = self._slow_forward(*input, **kwargs)
    549         else:
--> 550             result = self.forward(*input, **kwargs)
    551         for hook in self._forward_hooks.values():
    552             hook_result = hook(self, input, result)

/opt/conda/lib/python3.7/site-packages/torch/nn/modules/linear.py in forward(self, input)
     85 
     86     def forward(self, input):
---> 87         return F.linear(input, self.weight, self.bias)
     88 
     89     def extra_repr(self):

/opt/conda/lib/python3.7/site-packages/torch/nn/functional.py in linear(input, weight, bias)
   1606         if any([type(t) is not Tensor for t in tens_ops]) and has_torch_function(tens_ops):
   1607             return handle_torch_function(linear, tens_ops, input, weight, bias=bias)
-> 1608     if input.dim() == 2 and bias is not None:
   1609         # fused op is marginally faster
   1610         ret = torch.addmm(bias, input, weight.t())

AttributeError: 'DataLoader' object has no attribute 'dim'

Can some one help me resolving it ?

This is caused because you have tried to input a raw DataFrame into the pytorch NN

First of all, you can’t pass a raw DataFrame as input to a DataLoader class.
DataLoader expects a dataset object to load data from. See DataLoader Document

So you have to make a dataset object . In order to do this you need to first convert the dataframe into a pytorch tensor. You can do this by ,

X_train_tensor = torch.from_numpy(X_train.values)

I assume that you also have a Y_train DataFrame , so make a tensor from it too

Y_train_tensor = torch.from_numpy(Y_train.values)

Then as needed we then create a dataset using this

train_dataset = torch.utils.data.TensorDataset(X_train_tensor, 
                                                Y_train_tensor)

Now we can create a DataLoader out of this. Refer documentation for **kwargs

train_loader = torch.utils.data.DataLoader(train_dataset, batch_size, 
                                             shuffle=True)

And this train_loader is kind of a python generator, so you can’t just input this directly into the model.forward . (You have to iterate this train_loader)

I have implemented a example of a training loop using these below

for e in range(epochs):
        for  i, (data, labels) in enumerate(train_loader):  #iterate through each batch
                  optimizer.zero_grad()
                  output = model.forward(data)
                  loss = criterion(output.squeeze(), labels)
                  print (f'Epoch - {i+1}, Loss - {round(loss.item(),3)}')
                  loss.backward()
                  optimizer.step()

Hope this helps.