The error is IndexError: Target 2 is out of bounds. I need guidance please

class DeBERTadataset:
def init(self, texts, target):
self.tokenizer = config.TOKENIZER
self.max_len = config.max_len
self.texts = texts
self.target = target

def __len__(self):
    return len(self.texts)

def __getitem__(self, index):
    texts = str(self.texts[index])
    texts = ''.join(texts.split())
    target = self.target[index]


    inputs = self.tokenizer.encode_plus(
        texts,
        None,
        add_special_tokens = True,
        max_length = self.max_len,
        padding = 'max_length',
        truncation = True
    )


    resp = {
        'ids': torch.tensor(inputs['input_ids'], dtype=torch.long), 
        'mask': torch.tensor(inputs['attention_mask'], dtype=torch.long),
        'token_type_ids': torch.tensor(inputs['token_type_ids'], dtype=torch.long),
        'target': torch.tensor(self.target[index], dtype=torch.long)
    
    }

    return resp

class BERTModel(nn.Module):
def init(self):
super(BERTModel, self).init()
self.bert = BertModel.from_pretrained(‘bert-base-uncased’, return_dict=False)
self.dropout = nn.Dropout(0.3)
self.classified = nn.Linear(768, 2)

def forward(self, ids, mask, token_type_ids):
    _, pooled_output = self.bert(
        input_ids = ids,
        attention_mask = mask,
        token_type_ids = token_type_ids
    )

    pooled_output = self.dropout(pooled_output)
    outputs = self.classified(pooled_output)
    return outputs

import torch.nn as nn
from tqdm import tqdm
import torch

def loss_fn(outputs, target):
return nn.CrossEntropyLoss()(outputs, target)

def train_fx(data_loader, model, optimizer, scheduler, device):
model.train()

train_loss = 0
for bi, d in tqdm(enumerate(data_loader)):
    ids = d['ids']
    mask = d['mask']
    token_type_ids = d['token_type_ids']
    target = d['target']
# putting them into the device

    ids = ids.to(device, dtype=torch.long)
    mask = mask.to(device, dtype=torch.long)
    token_type_ids = token_type_ids.to(device, dtype=torch.long)
    target = target.to(device, dtype=torch.long)
        
    optimizer.zero_grad()
    outputs = model(
        ids = ids,
        mask = mask,
        token_type_ids = token_type_ids
    )
    
    loss = loss_fn(outputs, target)
    loss.backward()
    optimizer.step()
    scheduler.step()
    train_loss += loss.item()
train_loss = train_loss / len(data_loader)

print(f'Train loss: {train_loss:.3f}')

def eval_fx(data_loader, model, device):
model.eval()
valid_loss = 0

#final_target = []
#final_outputs = []
with torch.no_grad():
    for bi, d in tqdm(enumerate(data_loader)):
        ids = d['ids']
        mask = d['mask']
        token_type_ids = d['token_type_ids']
        target = d['target']
    # putting them into the device

        ids = ids.to(device, dtype=torch.long)
        mask = mask.to(device, dtype=torch.long)
        token_type_ids = token_type_ids.to(device, dtype=torch.long)
        target = target.to(device, dtype=torch.long)
            
        outputs = model(
            ids = ids,
            mask = mask,
            token_type_ids = token_type_ids
        )
        loss = loss_fn(outputs, target)

        valid_loss += loss.item()
    valid_loss = valid_loss / len(data_loader)

print(f'valid loss: {valid_loss:.3f}')

def accuracy_metrics(self, outputs, target):
outputs = torch.argmax(outputs).cpu().detach().numpy() # Due to the linear layer in our feedforward function
target = target.cpu().detach().numpy()
return {‘Accuracy’: metrics.accuracy_score(outputs, target)}

from tqdm import tqdm
best_accuracy = 0
for epoch in range(config.epochs):
train_fx(train_data_loader, model, optimizer,scheduler, device)
outputs, target = eval_fx(valid_data_loader, model, device)
accuracy = accuracy_metrics(outputs, target)
print(f’Accuracy score ----- {accuracy}')
if accuracy > best_accuracy:
torch.save(model.state_dict(), config.model_path)
best_accuracy = accuracy_metrics

The error is raised in the loss calculation since your target contains values, which are out-of-bounds.
Based on your code, it seems you are working on a binary classification and treat it as a 2-class multi-class classification using nn.CrossEntropyLoss. In this case the target should be a LongTensor and contain class indices in the range [0, nb_classes-1], so [0, 1] in your case.
A target value of 2 is thus invalid and you would have to check why it’s there (and remove it).

I’m working on a multi class classification problem, where the target has 3 classes(effective, ineffective, adequate). I changed the num_classes from 2 to 3. Where it’ll have 0,1,2, and the problem was solved.
class BERTModel(nn.Module):
def init(self):
super(BERTModel, self).init()
self.bert = BertModel.from_pretrained(‘bert-base-uncased’, return_dict=False)
self.dropout = nn.Dropout(0.3)
self.classified = nn.Linear(768, 2)
I changed the 2 in the self.classified to a 3 and it worked. :grinning:

I’m having an issue: cannot unpack non-iterable float object. This is my code at the top of this comment. I’ve checked the shape of my outputs and target for both training and validation loops and it gave me this…….
Training:
Outputs - torch.size([4, 3])
Target - torch.size([4])

Validation:
Outputs - torch.size([1, 3])
Target - torch.size([1])

So I don’t know why it’s showing me errors in my validation loop.

Which line of code is raising this issue?
Could you post the complete stacktrace, please?

def eval_fx(data_loader, model, device):
model.eval()
valid_loss = 0

#final_target = []
#final_outputs = []
with torch.no_grad():
    for bi, d in tqdm(enumerate(data_loader)):
        ids = d['ids']
        mask = d['mask']
        token_type_ids = d['token_type_ids']
        target = d['target']
    # putting them into the device

        ids = ids.to(device, dtype=torch.long)
        mask = mask.to(device, dtype=torch.long)
        token_type_ids = token_type_ids.to(device, dtype=torch.long)
        target = target.to(device, dtype=torch.long)
            
        outputs = model(
            ids = ids,
            mask = mask,
            token_type_ids = token_type_ids
        )
           final_target.extend(target.cpu().detach.numpy.tolist())
final_outputs.extend(torch.argmax(outputs).cpu().detach().numpy().tolist())

return final_target, final_outputs

best_accuracy = 0
for epoch in range(config.epochs):
train_fx(train_data_loader, model, optimizer,scheduler, device)
outputs, target = eval_fx(valid_data_loader, model, device)
accuracy = accuracy_metrics(outputs, target)
print(f’Accuracy score ----- {accuracy}')
if accuracy > best_accuracy:
torch.save(model.state_dict(), config.model_path)
best_accuracy = accuracy_metrics

The problem lies here : outputs, target = eval_fx(valid_data_loader, model, device)

Based on the stacktrace I guess eval_fx is returning a single float value, while you are expecting two returned objects:

def eval_fx():
    return 1.

outputs, target = eval_fx()
# TypeError: cannot unpack non-iterable float object

Yes, I am expecting a double value instead of single

How do I go about it. And what is the remedy for this error?

Check the method definition and return two objects instead of one.

Hi,
From what I can understand, you are trying to store targets (final_target) and final outputs (final_outputs) corresponding to each batch of your dataset in the corresponding lists.

Now, according to this, these lines aren’t indented properly in the code you’ve shown here -

final_target.extend(target.cpu().detach.numpy.tolist())
final_outputs.extend(torch.argmax(outputs).cpu().detach().numpy().tolist())
return final_target, final_outputs

Can you try this:

def eval_fx(data_loader, model, device):
  model.eval()
  valid_loss = 0

  final_target = []
  final_outputs = []
  with torch.no_grad():
    for bi, d in tqdm(enumerate(data_loader)):
      ids = d['ids']
      mask = d['mask']
      token_type_ids = d['token_type_ids']
      target = d['target']
    

      ids = ids.to(device, dtype=torch.long)
      mask = mask.to(device, dtype=torch.long)
      token_type_ids = token_type_ids.to(device, dtype=torch.long)
      target = target.to(device, dtype=torch.long)
            
      outputs = model(ids = ids,
                      mask = mask,
                      token_type_ids = token_type_ids
                      )
      final_target.extend(target.cpu().detach.numpy.tolist())
      final_outputs.extend(torch.argmax(outputs).cpu().detach().numpy().tolist())

  return final_target, final_outputs