Search code examples
pythondeep-learningpytorchdatasetloading

How to fix "TypeError: 'list' object is not callable" when loading data for training


I am trying to load data into training loop, however, "TypeError: 'list' object is not callable" keeps occuring.

Here is the function used for loading data:

def data_loader(data, transform, batch_size, cache=False):
    # this function uses the monai framework
    if cache:
        data_ds = CacheDataset(data=data, transform=transform,cache_rate=1.0)
        data_loader = DataLoader(data_ds, batch_size=batch_size)

    else:
        data_ds = Dataset(data=data, transform=transform)
        data_loader = DataLoader(data_ds, batch_size=batch_size)
        
    return data_loader

In the main script of code, the data is loaded using the function above:

train_loader = data_loader(train, transform(train=True), batch_size, cache=True)

where the variable train is a list of python dictionaries of images and masks.

Then the train_loader is passed into the train() function:

for epoch in range(num_epochs):
        
        trainLoss = train(model, train_loader, optimizer, loss_fn)

the train function returns epoch loss value. However, when the variable train_loader is passed to train(), the error occurs.

Here is the code for train function:

def train (model, loader, optimizer, dice_loss, device=torch.device('cuda')):
    
    epoch_loss = 0.0 
    
    model.train()
    for data in loader:
        
        # split data to image and mask
        image = data['image']
        mask = data['mask']
        
        # send data to gpu for accelerated process
        image = image.to(device)
        mask = mask.to(device)
        
        # zero the gradients before backpropagation
        optimizer.zero_grad()
        
        # feed data to model and get predicted mask
        pred_mask = model(image)
        
        # calculate loss value by comparing predicted and original mask
        # perform backpropagation, update parameters and calculate epoch loss
        loss = dice_loss(pred_mask, mask)
        loss.backward()
        optimizer.step()
        epoch_loss += loss.item()
        
    epoch_loss = epoch_loss/len(loader) 
    
    return epoch_loss

The code seems to work if I don't use a function:

for epoch in range(num_epochs):
        
        epoch_loss = 0.0 
        
        model.train()
        for data in train_loader:
            
            # split data to image and mask
            image = data['image']
            mask = data['mask']
            
            # send data to gpu for accelerated process
            image = image.to(device)
            mask = mask.to(device)
            
            # zero the gradients before backpropagation
            optimizer.zero_grad()
            
            # feed data to model and get predicted mask
            pred_mask = model(image)
            
            # calculate loss value by comparing predicted and original mask
            # perform backpropagation, update parameters and calculate epoch loss
            loss = loss_fn(pred_mask, mask)
            loss.backward()
            optimizer.step()
            epoch_loss += loss.item()
            
        trainLoss = epoch_loss/len(train_loader) 

Is there a way to fix the error whilst still using the function or should I just not use the function?


Solution

  • In Python functions and variables can override each other. Therefore when you define the function train() you are overwriting the train dictionary of data. Python: function and variable with the same name

    >>> a = 5
    >>> a
    5
    >>> def a():
    ...   return 3
    >>> a
    <function a at 0x103697160>
    

    I would suggest just renaming the train dictionary to train_data.

    I would also watch out for naming variables "input" or "list" as this will cause issues since you are overwriting Python's default classes.