Unable to train RNN

class RNN_Single(nn.Module):

  def __init__(self, input_dim, embed_size, hidden_state_size, classes):
    super(RNN_Single, self).__init__()
    self.embed = nn.Embedding(input_dim, embed_size)
    self.rnn = nn.RNN(embed_size, hidden_state_size)
    self.fc = nn.Linear(hidden_state_size, classes)

  def forward(self, input_batch):

    embedding_batch = self.embed(input_batch)
    output, hidden = self.rnn(embedding_batch)
    hidden = hidden.squeeze(0)
    assert torch.equal(output[-1,:,:], hidden) # Comparing the last time step output vector to the hidden vector and this should be equal
    return self.fc(hidden)

INPUT_DIM = len(NEWS.vocab) 
EMBED_DIM = 128
HIDDEN_UNITS = 512
CLASSES = 4

model = RNN_Single(INPUT_DIM, EMBED_DIM, HIDDEN_UNITS, CLASSES)
def accuracy(preds, true):

  _, index = torch.max(preds, dim = 1)

  return (index == true).sum().float() / len(preds)

def train(model, iterator, optimizer, criterion):

  e_loss = 0

  e_acc = 0

  model.train()

  for batch in iterator:

    optimizer.zero_grad()

    preds = model(batch.title)# Call using the column name

    acc = accuracy(preds,  batch.cat)

    loss = criterion(preds.squeeze(1), batch.cat)

    acc = accuracy(preds,  batch.cat)

    loss.backward()

    optimizer.step()

    e_loss += loss.item()

    e_acc += acc.item()

  return e_loss/len(iterator), e_acc/len(iterator)

def eval(model, iterator):

  e_loss = 0

  e_acc = 0

  model.eval()

  for batch in iterator:

    preds = models(batch.title)

    loss = criterion(preds.squeeze(1), batch.cat)

    acc = accuracy(preds,  batch.cat)

    e_loss += loss.item()

    e_acc += acc.item()

  return e_loss/len(iterator), e_acc/len(iterator)
N_EPOCHS = 5

best_valid_loss = float('inf')

for epoch in range(N_EPOCHS):

    start_time = time.time()
    
    train_loss, train_acc = train(model, train_iterator, optimizer, criterion)
    valid_loss, valid_acc = evaluate(model, test_iterator, criterion)
    
    end_time = time.time()

    epoch_mins, epoch_secs = epoch_time(start_time, end_time)
    
    if valid_loss < best_valid_loss:
        best_valid_loss = valid_loss
        torch.save(model.state_dict(), 'tut1-model.pt')
    
    print(f'Epoch: {epoch+1:02} / {N_EPOCHS} | Epoch Time: {epoch_mins}m {epoch_secs}s')
    print(f'\tTrain Loss: {train_loss:.3f} | Train Acc: {train_acc*100:.2f}%')
    print(f'\t Val. Loss: {valid_loss:.3f} |  Val. Acc: {valid_acc*100:.2f}%')

The error is:

TypeError Traceback (most recent call last)
in ()
** 7 start_time = time.time()**
** 8 **
----> 9 train_loss, train_acc = train(model, train_iterator, optimizer, criterion)
** 10 valid_loss, valid_acc = evaluate(model, test_iterator, criterion)**
** 11 **

1 frames
in train(model, iterator, optimizer, criterion)
** 12 preds = model(batch.title)# Call using the column name**
** 13 acc = accuracy(preds, batch.cat)**
—> 14 loss = criterion(preds.squeeze(1), batch.cat)
** 15 acc = accuracy(preds, batch.cat)**
** 16 loss.backward()**

*/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py in _call_impl(self, input, kwargs)
** 725 result = self._slow_forward(input, kwargs)
** 726 else:

–> 727 result = self.forward(input, kwargs)
** 728 for hook in itertools.chain(

** 729 _global_forward_hooks.values(),

TypeError: forward() takes 2 positional arguments but 3 were given

What kind of criterion are you using? Based on the stack trace it seems you might be using a custom nn.Module? If so, could you check its expected arguments and make sure that both tensors are accepted?

Criterion is CrossEntropyLoss.This is a multi class problem with 4 classes. I am inheriting the default nn.Module.

Are you using some old function definitions, where the passed criterion can be mapped to another argument?
In your code snippets you are e.g. using evaluate, while the definition seems to be eval().

Sorry, @ptrblck that was a blunder I made. I corrected and still the same error. I am new to PyTorch and DL please bear with me.

import torch.optim as optim
optimizer = optim.SGD(model.parameters(), lr = 1e-3)
criterion = nn.CrossEntropyLoss()
model = model.to(device)
criterion = model.to(device)

Something might still be overwriting the definition of criterion, so could you post an executable code snippet to reproduce this issue, please?

hi @ptrblck. You can find my code here https://colab.research.google.com/drive/1stzMYrUPDXjWwPRZvJJsKAxtQ6P1ydUr?usp=sharing

Thanks for the code.
You are overwriting the criterion after its definition:

criterion = nn.CrossEntropyLoss()
model = model.to(device)
criterion = model.to(device)
1 Like