Calculate train accuracy of the model in segmentation task

You are currently summing all correctly predicted pixels and divide it by the batch size. To get a valid accuracy between 0 and 100% you should divide correct_train by the number of pixels in your batch.
Try to calculate total_train as total_train += mask.nelement().

3 Likes

@ptrblck yes it works. Thanks a lot

1 Like

I this piece of code of yours

# accuracy
            _, predicted = torch.max(outputs.data, 1)
            total_train += mask.size(0)
            correct_train += predicted.eq(mask.data).sum().item()`

what are you trying to do in first line with torch.max especially why 1 and not 0. In 3rd line with predicted.eq()

1 Like

@singhvishal0209 sorry for late reply.

first line: return the indices of max values along rows in softmax probability output (torch.max returns a tuple containing the maximum value and the index of the maximum value within the tensor. Since the index in our case represents the classified category itself, we will only take that ignoring the actual probability).

second line: number of pixel in the batch

third line: By summing the output of the .eq() function, we get a count of the number of times the neural network has produced a correct output, and we take an accumulating sum of these correct predictions so that we can determine the accuracy of the network.

1 Like

I am getting 100% accuracy. I don’t know how to correct it. I am using the code of following link on my own dataset. The dataset set 400 training images and 120 validation images. Please help me.

dataloader code





Are you concerned about possible errors in the calculation of the accuracy or are you concerned you might have another error in the code, e.g. data leakage?

Yes i’m concerned about possible errors in the calculation of the accuracy. On each model i’m getting 100% accuracy after some epochs i think there some over fitting or some issue with accuracy calculation but i don’t know how to correct.

Could you post your code to calculate the accuracy by wrapping it in three backticks ``` so that we could have a look?

I’m using the same code as in the link.

// Code To Calculate Accuarcy.

import numpy as np

class runningScore(object):
def init(self, n_classes):
self.n_classes = n_classes
self.confusion_matrix = np.zeros((n_classes, n_classes))

def _fast_hist(self, label_true, label_pred, n_class):
    mask = (label_true >= 0) & (label_true < n_class)
    hist = np.bincount(
        n_class * label_true[mask].astype(int) + label_pred[mask], minlength=n_class ** 2
    ).reshape(n_class, n_class)
    return hist

def update(self, label_trues, label_preds):
    for lt, lp in zip(label_trues, label_preds):
        self.confusion_matrix += self._fast_hist(lt.flatten(), lp.flatten(), self.n_classes)

def get_scores(self):
    """Returns accuracy score evaluation result.
        - overall accuracy
        - mean accuracy
        - mean IU
        - fwavacc
    """
    hist = self.confusion_matrix
    acc = np.diag(hist).sum() / hist.sum()
    acc_cls = np.diag(hist) / hist.sum(axis=1)
    acc_cls = np.nanmean(acc_cls)
    iu = np.diag(hist) / (hist.sum(axis=1) + hist.sum(axis=0) - np.diag(hist))
    mean_iu = np.nanmean(iu)
    freq = hist.sum(axis=1) / hist.sum()
    fwavacc = (freq[freq > 0] * iu[freq > 0]).sum()
    cls_iu = dict(zip(range(self.n_classes), iu))

    return (
        {
            "Overall Acc: \t": acc,
            "Mean Acc : \t": acc_cls,
            "FreqW Acc : \t": fwavacc,
            "Mean IoU : \t": mean_iu,
        },
        cls_iu,
    )

def reset(self):
    self.confusion_matrix = np.zeros((self.n_classes, self.n_classes))

class averageMeter(object):
“”“Computes and stores the average and current value”""

def __init__(self):
    self.reset()

def reset(self):
    self.val = 0
    self.avg = 0
    self.sum = 0
    self.count = 0

def update(self, val, n=1):
    self.val = val
    self.sum += val * n
    self.count += n
    self.avg = self.sum / self.count

Hello can you tell me how should i calculate accuracy against MSELoss function ?

How would you like to define your accuracy?
If you are dealing with a multi-class classification use case, you could compare the predictions to the targets via:

output = torch.randn(10, 10)
target = torch.randint(0, 10, (10,))
preds = torch.argmax(output, 1)
acc = preds.eq(target).float().mean()

Usually you wouldn’t use nn.MSELoss for a classification use case, so we would need some information about your use case.

1 Like

I have a dataset of wheat Crop n which i have two clases Ear and Spikelet. when i use crossEntropyLoss function i will get the following error.

when i change
target_var = Variable(target.float())
to
target_var = Variable(target.long())

i will get the following error

when i tried to use your code. i will get the following error.

hello can you mention your input size if you are having the problem right now.it is a like an 6 months after completing this thread

Hey, I am computing the accuracy in a same way. As

 for epoch in range(epochs):
        net.train()

        epoch_loss = 0
        total_train = 0
        correct_train = 0
     
        with tqdm(total=n_train, desc=f'Epoch {epoch + 1}/{epochs}', unit='img') as pbar:
            for batch in train_loader:
                #continue
                imgs = batch['image']
                true_masks = batch['mask']
                n_batch = np.ceil(n_train/batch_size)
                assert imgs.shape[1] == net.n_channels, \
                    f'Network has been defined with {net.n_channels} input channels, ' \
                    f'but loaded images have {imgs.shape[1]} channels. Please check that ' \
                    'the images are loaded correctly.'

                imgs = imgs.to(device=device, dtype=torch.float32)
                mask_type = torch.float32 if net.n_classes == 1 else torch.long
                true_masks = true_masks.to(device=device, dtype=mask_type)

                logits,probs,masks_pred = net(imgs) #logits, probas, preds
                loss = criterion(logits, true_masks)
                epoch_loss += loss.item()
                #writer.add_scalar('Loss/train', loss.item(), global_step)

                pbar.set_postfix(**{'loss (batch)': loss.item()})

                optimizer.zero_grad()
                loss.backward()
                nn.utils.clip_grad_value_(net.parameters(), 0.1)
                #! nvidia-smi
                optimizer.step()
                torch.cuda.empty_cache()
                #! nvidia-smi
                total_train += true_masks.nelement()
                
                print('total_train',total_train)
                #print('masks_pred.eq(true_masks).sum()',masks_pred.eq(true_masks).sum())
                correct_train += masks_pred.eq(true_masks).sum().item()
                print('correct_train',correct_train)
                train_accuracy = 100*correct_train/total_train
                print('train_accuracy',train_accuracy)

The weird thing is that, when my batch_size=1, the accuracy is a value between 0-100%. But, when the batch_size => 2, the accuracy isn’t in a range of 100% any more. I tried to compute the

 train_accuracy = 
100*correct_train/total_train

outside of the

for batch in train_loader:

but, still didn’t get a reasonable value. I didn’t get why it doesn’t work properly, when the batch_size = > 2. Could you please explain it? Thank u.
@ptrblck @Neda

Some operations such as this one:

masks_pred.eq(true_masks).sum().item()

might use broadcasting, if you don’t use tensors in the right shape.
I would recommend to print the shapes of all tensors, which are used to compute the accuracy and make sure they have matching shapes.

Many thanks for putting me into right direction. Yes, when the batch_size=1, my true_masks.shape =[1,1,640,959], when the batch_size=2, my true_masks.shape=[2,1,640,959]. Using torch.squeeze(true_masks,1) solved my problem. @ptrblck

what is your batch size for training?

Is this formula for MIT App inventor or Personal Image Classifier???

Can somebody help me I don’t know how can I calculate accuracy? For loss I just return loss_value from train_one_epoch() inside engine.py.
I’m following this turotial: TorchVision Object Detection Finetuning Tutorial — PyTorch Tutorials 1.12.1+cu102 documentation

This is my code for training:

def get_transform(train):
        transforms = []
        transforms.append(T.ToTensor())
        #if train:
            #transforms.append(T.RandomHorizontalFlip(0.5))
        return T.Compose(transforms)
    
    def draw_loss(ml):
        plt.figure(figsize=(10,5))
        plt.title("Training Loss")
        #plt.plot(val_losses,label="val")
        plt.plot(ml,label="train")
        plt.xlabel("Epochs")
        plt.ylabel("Loss")
        plt.legend()
        plt.xlim([0,30])
        plt.ylim([0, 1])
        plt.show()
    
    def main():
        # train on the GPU or on the CPU, if a GPU is not available
        device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
    
        # our dataset has two classes only - background and person
        num_classes = 2
        # use our dataset and defined transformations
        dataset = Moj_Dataset_ArT('Train/ArT', get_transform(train=True))
        dataset_test = Moj_Dataset_ArT('Train/ArT', get_transform(train=False))
    
        # split the dataset in train and test set
        indices = torch.randperm(len(dataset)).tolist()
        dataset = torch.utils.data.Subset(dataset, indices[:-500])
        dataset_test = torch.utils.data.Subset(dataset_test, indices[-500:])
    
        # define training and validation data loaders
        data_loader = torch.utils.data.DataLoader(
            dataset, batch_size=4, shuffle=True, num_workers=4,
            collate_fn=utils.collate_fn)
    
        data_loader_test = torch.utils.data.DataLoader(
            dataset_test, batch_size=1, shuffle=False, num_workers=4,
            collate_fn=utils.collate_fn)
    
        # get the model using our helper function
        model = get_model_instance_segmentation(num_classes)
    
        # move model to the right device
        model.to(device)
    
        # construct an optimizer
        params = [p for p in model.parameters() if p.requires_grad]
        optimizer = torch.optim.SGD(params, lr=0.001,
                                    momentum=0.9, weight_decay=0.0005)
        # and a learning rate scheduler
        lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer,
                                                       step_size=75,
                                                       gamma=0.5)
    
        # let's train it for 10 epochs
        num_epochs = 15
    
        ml =[] 
        for epoch in range(num_epochs):
            # train for one epoch, printing every 10 iterations
            loss_value = train_one_epoch(model, optimizer, data_loader, device, epoch, print_freq=10)
            ml.append(loss_value)
            
            # update the learning rate
            lr_scheduler.step()
            # evaluate on the test dataset
            #evaluate(model, data_loader_test, device=device)
        print(ml)
        draw_loss(ml)

engine.py

  def train_one_epoch(model, optimizer, data_loader, device, epoch, print_freq):
            model.train()
            metric_logger = utils.MetricLogger(delimiter="  ")
            metric_logger.add_meter('lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))
            header = 'Epoch: [{}]'.format(epoch)
        
            lr_scheduler = None
            if epoch == 0:
                warmup_factor = 1. / 1000
                warmup_iters = min(1000, len(data_loader) - 1)
        
                lr_scheduler = utils.warmup_lr_scheduler(optimizer, warmup_iters, warmup_factor)
        
            for images, targets in metric_logger.log_every(data_loader, print_freq, header):
                images = list(image.to(device) for image in images)
                targets = [{k: v.to(device) for k, v in t.items()} for t in targets]
        
                loss_dict = model(images, targets)
        
                losses = sum(loss for loss in loss_dict.values())
        
                # reduce losses over all GPUs for logging purposes
                loss_dict_reduced = utils.reduce_dict(loss_dict)
                losses_reduced = sum(loss for loss in loss_dict_reduced.values())
        
                loss_value = losses_reduced.item() # loss u rezultatima
        
                if not math.isfinite(loss_value):
                    print("Loss is {}, stopping training".format(loss_value))
                    print(loss_dict_reduced)
                    sys.exit(1)
        
                optimizer.zero_grad()
                losses.backward()
                optimizer.step()
        
                if lr_scheduler is not None:
                    lr_scheduler.step()
        
                metric_logger.update(loss=losses_reduced, **loss_dict_reduced)
                metric_logger.update(lr=optimizer.param_groups[0]["lr"])
        
            return loss_value
            #return metric_logger