DeepLabV3 generates only zero class

34 Views Asked by At

I have working on a binary segmentation problem. 0 is for background and 1 is for my building class. When I trained my model loss get updated but accuracy and intersection over union does not change at all.

Epoch [1/10] 

Train PxAcc: 0.9783, Train Loss: 0.0840, Train IoU: 0.4891, 

Val PxAcc: 0.9391, Val Loss: 11.2002, Val IoU: 0.4695, 

Epoch [2/10] 

Train PxAcc: 0.9783, Train Loss: 0.0827, Train IoU: 0.4891, 

Val PxAcc: 0.9391, Val Loss: 757.0062, Val IoU: 0.4695, 

Epoch [3/10] 

Train PxAcc: 0.9783, Train Loss: 0.3455, Train IoU: 0.4891, 

Val PxAcc: 0.9391, Val Loss: 2.0062, Val IoU: 0.4695,

Here is my train and validate functions:

import torch
import numpy as np
from tqdm import tqdm
from metrics import px_acc, calc_mean_iou


def train(model, train_loader, criterion, optimizer, device):
        model.train()
        running_loss = 0.0
    accuracy = 0.0
    mean_iou = 0.0
    all_preds = []
    all_labels = []

    for inputs, labels in tqdm(train_loader, desc="Training"):
        inputs, labels = inputs.to(device), labels.to(device)
        optimizer.zero_grad()

        outputs = model(inputs)
        output = outputs['out']
        loss = criterion(output, labels)
        loss.backward()
        optimizer.step()

        preds = torch.argmax(output, dim=1)
        all_preds.extend(preds.cpu().numpy())  # Move to CPU before conversion to numpy
        all_labels.extend(labels.cpu().numpy())  # Move to CPU before conversion to numpy
        running_loss += loss.item()
    # Calculate pixel accuracy
    accuracy = px_acc(all_labels, all_preds)
    mean_iou, iou_per_class = calc_mean_iou(all_labels, all_preds, num_classes= 2)
    return accuracy, loss, mean_iou

def validate(model, val_loader, criterion, device):
    model.eval()
    running_loss = 0.0
    accuracy = 0.0
    mean_iou = 0.0
    all_preds = []
    all_labels = []

    with torch.no_grad():
        for inputs, labels in tqdm(val_loader, desc="Validation"):
            inputs, labels = inputs.to(device), labels.to(device)

            outputs = model(inputs)
            output = outputs['out']
            loss = criterion(output, labels)
            running_loss += loss.item()

            preds = torch.argmax(output, dim=1)
            all_preds.extend(preds.cpu().numpy())  # Move to CPU before conversion to numpy
            all_labels.extend(labels.cpu().numpy())  # Move to CPU before conversion to numpy

        loss = running_loss / len(val_loader)
        accuracy = px_acc(all_labels, all_preds)
        mean_iou, iou_per_class = calc_mean_iou(all_labels, all_preds, num_classes= 2)
    return accuracy, loss, mean_iou

Here is my metrics.py that includes intersection over union and pixel accuracy functions.

import numpy as np

def px_acc(y_true_list, y_pred_list):
    # Initialize total correct predictions and total pixels
    total_correct = 0
    total_pixels = 0

    # Iterate over the corresponding pairs of arrays in the lists
    for y_true, y_pred in zip(y_true_list, y_pred_list):
        total_correct += (y_true == y_pred).sum()
        total_pixels += y_true.size

    # Calculate pixel accuracy
    acc = total_correct / total_pixels
    return acc

def calc_mean_iou(y_true_list, y_pred_list, num_classes):
    # Initialize confusion matrix
    conf_matrix = np.zeros((num_classes, num_classes), dtype=np.float32)

    # Populate the confusion matrix
    for y_true, y_pred in zip(y_true_list, y_pred_list):
        for i in range(num_classes):
            for j in range(num_classes):
                conf_matrix[i, j] += np.sum((y_true == i) & (y_pred == j))

    # Calculate IoU per class
    iou_per_class = []
    for i in range(num_classes):
        true_positives = conf_matrix[i, i]
        false_positives = conf_matrix[:, i].sum() - true_positives
        false_negatives = conf_matrix[i, :].sum() - true_positives
        denom = true_positives + false_positives + false_negatives
        iou = true_positives / denom if denom > 0 else 0
        iou_per_class.append(iou)

    # Calculate mean IoU
    mean_iou = np.mean(iou_per_class)

    return mean_iou, iou_per_class
0

There are 0 best solutions below