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

tavishjain: <p>I was creating a regression model using simple neural network and built my model as follows:<br>
The shape of input variable X_train is (1086, 76), which is a DataFrame</p>
<pre><code class="lang-auto">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)
</code></pre>
<p>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:</p>
<pre><code class="lang-auto">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
</code></pre>
<p>Where it has been giving me an error:</p>
<pre><code class="lang-auto">---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
&lt;ipython-input-165-69744667c9a4&gt; in &lt;module&gt;
      8 for i,e in enumerate(range(epochs)):
      9     optimizer.zero_grad() # Reset the grads
---&gt; 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

&lt;ipython-input-164-caccab51ac99&gt; in forward(self, x)
      9 #         self.relu = nn.ReLU()
     10     def forward(self, x):
---&gt; 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:
--&gt; 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):
---&gt; 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)
-&gt; 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'
</code></pre>
<p>Can some one help me resolving it ?</p>

Chirath_Pansilu: <p>This is caused because you have tried to input a raw DataFrame into the pytorch NN</p>
<p>First of all,  you can’t pass a raw DataFrame as input to a DataLoader class.<br>
DataLoader expects a  <code>dataset object</code> to load data from.  <a href="https://pytorch.org/docs/stable/data.html#module-torch.utils.data" rel="nofollow noopener">See DataLoader Document </a></p>
<p>So you have to make a <code>dataset object</code> . In order to do this you need to first convert the dataframe into a pytorch tensor. You can do this by ,</p>
<pre><code class="lang-auto">X_train_tensor = torch.from_numpy(X_train.values)
</code></pre>
<p>I assume that you also have a Y_train DataFrame , so make a tensor from it too</p>
<pre><code class="lang-auto">Y_train_tensor = torch.from_numpy(Y_train.values)
</code></pre>
<p>Then as needed we then create a <code>dataset</code> <a href="https://pytorch.org/docs/stable/data.html#torch.utils.data.TensorDataset" rel="nofollow noopener">using this</a></p>
<pre><code class="lang-auto">train_dataset = torch.utils.data.TensorDataset(X_train_tensor, 
                                                Y_train_tensor)
</code></pre>
<p>Now we can create a DataLoader out of this. Refer <a href="https://pytorch.org/docs/stable/data.html#module-torch.utils.data" rel="nofollow noopener">documentation</a> for **kwargs</p>
<pre><code class="lang-auto">train_loader = torch.utils.data.DataLoader(train_dataset, batch_size, 
                                             shuffle=True)
</code></pre>
<p>And this train_loader is kind of a python generator, so you can’t just  input this directly into the <code>model.forward</code> . (You have to iterate this train_loader)</p>
<p>I have implemented  a example of a training loop using these below</p>
<pre><code class="lang-auto">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()
</code></pre>
<p>Hope this helps.</p>