Pytorch error : ValueError: too many values to unpack (expected 4)

# Calculate the number of batches to update the progress bar every 20%
num_batches = len(valid_dataloader)
update_interval = max(num_batches // 5, 1)  # Update every 20% or at least once

with tqdm(total=num_batches, desc=f"Evaluation", unit="batch") as pbar_eval:
  for step, batch in enumerate(valid_dataloader):
    batch = tuple(t.to(device) for t in batch)
    **cat,num,b_labels, _ ,*remaining = batch[2]**

    real_batch_size = val_dataloader.batch_size

    with torch.no_grad():
        #transformer
        model_outputs = transformer(cat, num)
        #transformer loss
        t_loss = tran_loss_fn(model_outputs, b_labels)

this is the code , which is giving error
ValueError: too many values to unpack (expected 4)
I am fairly new to coding,so please i will be grateful if anyone can help me on this

Hi @Maasooma,

Can you share the full stacktrace? (Rather than just the last line)

It seems you have a function, which is meant to return 4 variables, but you wrote fewer variables when calling the function, so the interpreter doesn’t know how to unpack them.

If I had to guess, it might be this line,

but seeing the full stacktrace would resolve the issue.

I made few changes since yesterday but still havent been able to resolve the issue .

Complete error report :


ValueError Traceback (most recent call last)
in <cell line: 13>()
13 for epoch in range(num_epochs):
14 train_loss_t,train_loss_g,train_loss_d,epoch_accuracy=train_model(transformer, discriminator, generator, train_dataloader, noise_size, tran_optimizer,gen_optimizer, dis_optimizer, label_list)
—> 15 val_loss_t, val_loss_g, val_loss_d, accuracy, f1=validate_model(transformer, discriminator, generator, valid_dataloader, noise_size, label_list)
16
17 if val_loss_t < best_eval_loss_tran:

in validate_model(transformer, discriminator, generator, val_dataloader, noise_size, label_list)
21 for step, batch in enumerate(valid_dataloader):
22 batch = tuple(t.to(device) for t in batch)
—> 23 cat,num,b_labels = batch[2]
24
25 real_batch_size = val_dataloader.batch_size

ValueError: too many values to unpack (expected 3)

my Validate Code is this :
def validate_model(transformer, discriminator, generator, val_dataloader, noise_size, label_list):
print(f"Validation Epoch {epoch + 1}/{num_epochs}")

transformer.eval()
generator.eval()
discriminator.eval()

val_t_loss = 0
val_g_loss = 0
val_d_loss = 0

true_labels = []
pred_labels = []
batch_losses = []

# Calculate the number of batches to update the progress bar every 20%
num_batches = len(valid_dataloader)
update_interval = max(num_batches // 5, 1)  # Update every 20% or at least once

with tqdm(total=num_batches, desc=f"Evaluation", unit="batch") as pbar_eval:
  for step, batch in enumerate(valid_dataloader):
    batch = tuple(t.to(device) for t in batch)
    cat,num,b_labels = batch[2]

    real_batch_size = val_dataloader.batch_size

    with torch.no_grad():
        #transformer
        model_outputs = transformer(cat, num)
        print(cat.shape)
        #transformer loss
        t_loss = tran_loss_fn(model_outputs, b_labels)

        #generator
        noise = torch.zeros(real_batch_size, noise_size).uniform_(0, 1)
        gen_rep = generator(noise)

        #discriminator
        discriminator_input = torch.cat([model_outputs, gen_rep], dim=0)
        features, logits, probs = discriminator(discriminator_input)

        features_list = torch.split(features, real_batch_size)
        D_real_features = features_list[0]
        D_fake_features = features_list[1]

        logits_list = torch.split(logits, real_batch_size)
        D_real_logits = logits_list[0]
        D_fake_logits = logits_list[1]

        probs_list = torch.split(probs, real_batch_size)
        D_real_probs = probs_list[0]
        D_fake_probs = probs_list[1]

        #generator_loss
        g_loss_d = -1 * torch.mean(torch.log(1 - D_fake_probs[:, -1] + epsilon))
        g_feat_reg = torch.mean(torch.pow(torch.mean(D_real_features, dim=0) - torch.mean(D_fake_features, dim=0), 2))
        g_loss = g_loss_d + g_feat_reg

        #discriminator_loss
        logits = D_real_logits[:, 0:-1]
        log_probs = F.log_softmax(logits, dim=-1)
        d_loss = d_loss_fn(logits, b_labels)

        val_t_loss += t_loss.item() * cat.size(0)
        val_g_loss += g_loss.item()
        val_d_loss += d_loss.item()

        # discriminator accuracy
        predicted_labels = torch.argmax(logits, dim=-1)
        correct += (predicted_labels == b_labels).sum().item()
        total += b_labels.size(0)

        # Calculate percentage progress for each batch
        batch_progress = (step + 1) / num_batches * 100
        batch_progress = min(int(batch_progress), 100)  # Ensure progress does not exceed 100%

        # Update progress bar
        pbar_epoch.set_postfix(tran_loss=val_t_loss / (step + 1),
                           gen_loss=val_g_loss / (step + 1),
                           disc_loss=val_d_loss / (step + 1),
                           epoch_accuracy=correct / total,
                           progress=f"{batch_progress}% done")

        pbar_eval.update(1)

    true_labels.extend(b_labels.tolist())
    pred_labels.extend(torch.argmax(log_probs, dim=1).tolist())
    batch_losses.append((t_loss.item(), g_loss.item(), d_loss.item()))

# Calculate metrics
accuracy = accuracy_score(true_labels, pred_labels)
f1 = f1_score(true_labels, pred_labels, average='weighted')

avg_val_loss_t = val_t_loss / len(val_dataloader)
avg_val_loss_g = val_g_loss / len(val_dataloader)
avg_val_loss_d = val_d_loss / len(val_dataloader)

print('Validation Loss Transformer:', avg_val_loss_t,
      'Validation Loss Generator:', avg_val_loss_g,
      'Validation Loss Discriminator:', avg_val_loss_d,
      'Validation Accuracy:', accuracy,
      'Validation F1 Score:', f1
      )

return avg_val_loss_t, avg_val_loss_g, avg_val_loss_d, accuracy, f1, batch_losses

my train function also has the same lines :

with tqdm(total=num_batches, desc=f"Epoch {epoch + 1}/{num_epochs}", unit="batch") as pbar_epoch:
  for step, batch in enumerate(train_dataloader):
    batch = tuple(t.to(device) for t in batch)
    cat,num,b_labels = batch
    print(cat.shape)
    #print('label_len:',b_labels.shape)
    real_batch_size = train_dataloader.batch_size

while training it gives output like this

Epoch 1/1: 100%|█████████▉| 5323/5325 [1:02:11<00:01, 1.54batch/s, disc_loss=0.24, epoch_accuracy=0.928, gen_loss=0.0607, progress=99% done, tran_loss=13.6]torch.Size([64, 21])
Epoch 1/1: 100%|█████████▉| 5324/5325 [1:02:12<00:00, 1.54batch/s, disc_loss=0.24, epoch_accuracy=0.928, gen_loss=0.0607, progress=99% done, tran_loss=13.6]torch.Size([64, 21])
Epoch 1/1: 100%|██████████| 5325/5325 [1:02:12<00:00, 1.43batch/s, disc_loss=0.24, epoch_accuracy=0.928, gen_loss=0.0607, progress=100% done, tran_loss=13.6]
Epoch Accuracy: 92.82%
Training Loss Transformer: 13.605765486009803 Training Loss generator: 0.06067998356505039 Training Loss discriminator 0.24025467120670657
Validation Epoch 1/1
Evaluation: 0%| | 0/9585 [00:00<?, ?batch/s]

The error is occurring on this line, you’re telling the interpreter there should be 3 variables to un-pack from batch[2], however, there are more than 3 within batch[2]