Enumerate(dataloader) - unsolvable error

username: Adam_Prihoda
cooked: <p>Hi,<br>
I’ve been working on a CT scan classfication model with custom dataset from images and while training the model in the line " for batch, (X_train,y_train) in enumerate(train_data): "<br>
I got an error:<br>
“ValueError: too many values to unpack (expected 3)”<br>
The thing is I previous 18 or so batches went without any problems. I also checked if the shape of the loaded data is different and used *data to try to find what doesnt fit, adding more or less variables to unpack the data to didn’t work either.</p>
<p>I’ve been trying to resolve this issue for like 3 hours, your help would be greatly appreciated. <img src="https://discuss.pytorch.org/images/emoji/apple/smile.png?v=12" title=":smile:" class="emoji" alt=":smile:" loading="lazy" width="20" height="20"></p>
<p>PS: If you find ways to improve my code even further then please let me know.</p>
<pre><code class="lang-auto">class ScansDS(Dataset):
    def __init__(self, annotations, root_dir, transform = None):
        self.annotations = annotations
        self.root_dir = root_dir
        self.transform = transform
    
    def __len__(self):
        return len(self.annotations)
    
    def __getitem__(self, index):
        img_path = os.path.join(self.root_dir, self.annotations.iloc[index,0])
        image = torch.tensor(read_image(img_path), dtype=float)
        y_label = torch.tensor(int(self.annotations.iloc[index,1]))

        if self.transform:
            image = self.transform(image)

        return (image, y_label)
    
transforms = v2.Compose([
    v2.Grayscale(num_output_channels=1),
    v2.Resize((244,244)),
    v2.ToTensor(),
    v2.Normalize(mean=[0.49], std=[0.225]),
])

train_dataset = ScansDS(annotations=train_df, root_dir="Data/mix_train", transform=transforms)

train_data = DataLoader(dataset=train_dataset, batch_size=8, shuffle=True, num_workers=0,)

class ScanModel(nn.Module):
    def __init__(self,):
        super().__init__()
        self.conv1 = nn.Conv2d(1,64,stride=1,kernel_size=3, bias=False)
        self.conv2 = nn.Conv2d(64,64,stride=1,kernel_size=3, bias=False)
        self.conv3 = nn.Conv2d(64,128,stride=1,kernel_size=3, bias=False)
        self.conv4 = nn.Conv2d(128,256,stride=1,kernel_size=3, bias=False)
        self.conv5 = nn.Conv2d(256,512, stride=1,kernel_size=3, bias=False)

        self.dropout = nn.Dropout(0.22)
       
        self.bn1 = nn.BatchNorm2d(64)
        self.bn2 = nn.BatchNorm2d(64)
        self.bn3 = nn.BatchNorm2d(128)
        self.bn4 = nn.BatchNorm2d(256)
        self.bn5 = nn.BatchNorm2d(512)
        self.bn6 = nn.BatchNorm2d(512)
         
        self.fc1 = nn.Linear(512*5*5, 128)
        self.fc2 = nn.Linear(128, 256)
        self.fc3 = nn.Linear(256,3)

    def forward(self, x):     
        x = F.relu(self.conv1(x))
        x = self.bn1(x)
        x = self.dropout(x)
        x = F.max_pool2d(x,2,2)

        x = F.relu(self.conv2(x))
        x = self.bn2(x)
        x = self.dropout(x)
        x = F.max_pool2d(x,2,2)

        x = F.relu(self.conv3(x))
        x = self.bn3(x)
        x = self.dropout(x)
        x = F.max_pool2d(x,2,2)

        x = F.relu(self.conv4(x))
        x = self.bn4(x)
        x = self.dropout(x)
        x = F.max_pool2d(x,2,2)


        x = F.relu(self.conv5(x))
        x = self.bn5(x)
        x = self.dropout(x)
        x = F.max_pool2d(x,2,2)
        
        x = x.view(-1,512*5*5)
        
        x = F.relu(self.fc1(x))
        x=self.dropout(x)
        x = F.relu(self.fc2(x))
        x= self.dropout(x)
        x = F.log_softmax(self.fc3(x), dim=1)
                   
        return x

torch.manual_seed(41)
torch.cuda.manual_seed(41)

model = ScanModel()
model = model.cuda()

print(torch.cuda.current_device())
print(torch.cuda.device_count())
print(torch.cuda.get_device_name(0))

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

optimizer = torch.optim.Adam(lr=0.001, params= model.parameters())
criterion = nn.CrossEntropyLoss()

EPOCHS = 5

train_losses = []
train_correct = []

start_time = time.time()

for epoch in range(EPOCHS):

    epoch_train_correct = 0
    model.train()

    for batch, (X_train,y_train) in enumerate(train_data):
      X_train,y_train = X_train.to(device).float(), y_train.to(device)
      print(batch)
      y_pred = model.forward(X_train)
      loss = criterion(y_pred,y_train)

      predicted = torch.max(y_pred.detach(),1)[1]   # .data oddelí gradient atd od samostatných dat a dá nám jen data, ta jednice v tom maxu znamena dimenze na ktere hleda max(cols nebo rows asi)
      batch_correct = (predicted == y_train).sum()
      epoch_train_correct += batch_correct

      optimizer.zero_grad()
      loss.backward() #vypocita gradient pro nase weights atd
      optimizer.step() #updatne weights s gradientem

      if batch%10 == 0:
        print(f"Epoch: {epoch+1}   Batch: {batch+1}   Loss: {loss.item()}")




    train_losses.append((f"Trl{epoch+1}",loss))
    train_correct.append((f"Trc{epoch+1}",epoch_train_correct))


current_time = time.time()
total_time = current_time - start_time
print(f"Training took {total_time/60} minutes.")

</code></pre>