AttributeError: 'function' object has no attribute 'size'

AlexSwiderski: <p>Hi everyone,</p>
<p>I am training an RNN and have come across the following error</p>
<pre><code class="lang-auto">    247             input = cast(Tensor, input)
    248             batch_sizes = None
--&gt; 249             max_batch_size = input.size(0) if self.batch_first else input.size(1)
    250             sorted_indices = None
    251             unsorted_indices = None
AttributeError: 'function' object has no attribute 'size'
</code></pre>
<p>I understand what the error means, but what I do not understand is why it is happening or where it is occurring. I’d appreciate any feedback if available!</p>
<p>At the risk of not providing enough information this is my training and validation function:</p>
<pre><code class="lang-auto"># Training functioN
def train(model, device, train_loader, valid_loader, epochs, learning_rate):

  criterion = nn.CrossEntropyLoss()
  optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
  
  train_loss, validation_loss = [], []
  train_acc, validation_acc = [], []

  for epoch in range(epochs):
    #train
    model.train()
    running_loss = 0.
    correct, total = 0, 0
    steps = 0

    for idx, batch in enumerate(train_loader):
      text = batch["Sample"].to(device)
      target = batch['Class'].to(device)
      print(type(text), text.shape)
      target = torch.autograd.Variable(target).long()
      target = text.to(device), target.to(device)

      # add micro for coding training loop
      optimizer.zero_grad()
      output = model(text)

      loss = criterion(output, target)
      loss.backward()
      optimizer.step()
      steps += 1
      running_loss += loss.item()

      # get accuracy
      _, predicted = torch.max(output, 1)
      total += target.size(0)
      correct += (predicted == target).sum().item()

    train_loss.append(running_loss/len(train_loader))
    train_acc.append(correct/total)

    print(f'Epoch: {epoch + 1}, '
          f'Training Loss: {running_loss/len(train_loader):.4f}, '
          f'Training Accuracy: {100*correct/total: .2f}%')

    # evaluate on validation data
    model.eval()
    running_loss = 0.
    correct, total = 0, 0

    with torch.no_grad():
      for idx, batch in enumerate(valid_loader):
        text = batch["Sample"].to(device)
        print(type(text), text.shape)
        target = batch['Class'].to(device)
        target = torch.autograd.Variable(target).long()
        text, target = text.to(device), target.to(device)

        optimizer.zero_grad()
        output = model(text)

        loss = criterion(output, target)
        running_loss += loss.item()

        # get accuracy
        _, predicted = torch.max(output, 1)
        total += target.size(0)
        correct += (predicted == target).sum().item()

    validation_loss.append(running_loss/len(valid_loader))
    validation_acc.append(correct/total)

    print (f'Validation Loss: {running_loss/len(valid_loader):.4f}, '
           f'Validation Accuracy: {100*correct/total: .2f}%')

  return train_loss, train_acc, validation_loss, validation_acc
</code></pre>
<p><strong>Model</strong></p>
<pre><code class="lang-auto">class VanillaRNN(nn.Module):

 def __init__(self, output_size, input_size, RNN_size, fc_size,
              device):
   super(VanillaRNN, self).__init__()
   self.RNN_size = RNN_size
   self.fc_size = fc_size
   
# Define the RNN layer
   self.rnn = nn.RNN(input_size, 100, 2)
   # Define the fully connected layer
   self.fc1 = nn.Linear(100, 11)
   self.device = device

 def forward(self, inputs):
   h_0 = torch.zeros(2, input_size, self.RNN_size).to(self.device)
   output, h_n = self.rnn(input, h_0)
   h_n = h_n.permute(1, 0, 2)
   h_n = h_n.contiguous().reshape(h_n.size()[0], self.RNN_size*self.fc_size)
   logits = self.fc(h_n)
   return logits

## Uncomment to test VanillaRNN class

sampleRNN = VanillaRNN(11, 300, 100, 50, DEVICE)

print(sampleRNN)
</code></pre>
<p><strong>And this is where I call the training function</strong></p>
<pre><code class="lang-auto"># Model hyperparamters
learning_rate = 1e-3
RNN_size = 100
output_size = 11
input_size = 300

epochs = 10
embed_length = 300
fc_size  = 50

# Initialize model, training and testing
set_seed(SEED)
vanilla_rnn_model = VanillaRNN(output_size, input_size, RNN_size, fc_size, DEVICE)
vanilla_rnn_model.to(DEVICE)
vanilla_rnn_start_time = time.time()
vanilla_train_loss, vanilla_train_acc, vanilla_validation_loss, vanilla_validation_acc = train(vanilla_rnn_model,  DEVICE, train_loader, valid_loader, learning_rate = learning_rate)
</code></pre>

gphilip: <p>Change this line in <code>forward</code></p>
<pre><code class="lang-auto">   output, h_n = self.rnn(input, h_0)
</code></pre>
<p>to</p>
<pre><code class="lang-auto">   output, h_n = self.rnn(inputs, h_0)
</code></pre>

AlexSwiderski: <p>This is great, and thank you very much.  Typos <em>face palm</em>  I am now getting an error stating</p>
<pre><code class="lang-auto">IndexError                                Traceback (most recent call last)
&lt;ipython-input-43-b5a747e0c45e&gt; in &lt;module&gt;()
     19                                                                                                valid_loader,
     20                                                                                                epochs = epochs,
---&gt; 21                                                                                                learning_rate = learning_rate)
     22 print("--- Time taken to train = %s seconds ---" % (time.time() - vanilla_rnn_start_time))
     23 #test_accuracy = test(vanilla_rnn_model, DEVICE, test_iter)

4 frames
/usr/local/lib/python3.7/dist-packages/torch/nn/modules/rnn.py in forward(self, input, hx)
    247             input = cast(Tensor, input)
    248             batch_sizes = None
--&gt; 249             max_batch_size = input.size(0) if self.batch_first else input.size(1)
    250             sorted_indices = None
    251             unsorted_indices = None

IndexError: Dimension out of range (expected to be in range of [-1, 0], but got 1)
</code></pre>
<p>Based on <a href="https://stackoverflow.com/questions/61893786/getting-an-error-in-pytorch-indexerror-dimension-out-of-range-expected-to-be" rel="noopener nofollow ugc">this post</a> I think it is coming from the way i am creating either my output or predicted objects.  I tried changing predictived variable from:</p>
<pre><code class="lang-auto">_, predicted = torch.max(output, 1)
</code></pre>
<p>to both</p>
<pre><code class="lang-auto">predicted = torch.round(output.squeeze())
#AND
_, predicted = torch.round(output.squeeze())
</code></pre>
<p>But get the same error.  Any thoughts? Thanks for your continued support!!</p>