用于二进制语义分割的自定义加权 IoU 损失

问题描述 投票:0回答:1

我想问一下我的加权IoU损失的实现是否正确。给定卫星图像,我正在尝试分割道路和前景像素。

    def compute_loss(self, y_true, y_pred):
        
        '''Implementation code to calculate weighted IoU loss for U-Net model. 
        
        Args:
            y_true: tensor of shape (batch_size, 400, 400, 1), containing pixel values of groundtruth image
            y_pred: tensor of shape (batch_size, 400, 400, 1), containing pixel values of prediction from model

        Returns:
            loss
        '''        
        
        scores = []
        class_weights = [self.foreground_weight, self.road_weight]
        
        for i in range(y_true.shape[0]):
            
            y_true_sample = tf.reshape(y_true[i], [-1])
            y_pred_sample = tf.reshape(y_pred[i], [-1])
            
            intersection = tf.reduce_sum(tf.cast(y_true_sample, tf.float32)*tf.cast(y_pred_sample, tf.float32))
            smoothing = 1
            iou = (intersection + smoothing)/ (tf.reduce_sum(tf.cast(y_true_sample, tf.float32)) + tf.reduce_sum(tf.cast(y_pred_sample, tf.float32)) - intersection + smoothing)
            
            weighted_iou = tf.reduce_sum((1. - iou)*class_weights)
            scores.append(weighted_iou)
            
        scores = tf.convert_to_tensor(scores, dtype = tf.float32)
        return tf.reduce_mean(scores)

在这里,我传递的批量大小为 8。我的 U-Net 模型的最后一层是 1x1 卷积层,然后通过 sigmoid 激活。这会产生 (batch_size, height, width, 1) 的输出形状,其中每个像素值表示像素属于标记为 1 的类的概率。

但是,当我训练模型时,训练损失似乎在几个时期后停滞不前。

我尝试尝试不同的学习率,但损失要么卡在某个值,要么当学习率太慢时模型无法学习。

注意:添加类权重是因为前景像素与道路像素的比例为 9:1。

我的实现正确吗?

谢谢!

python tensorflow image-segmentation loss-function
1个回答
0
投票

将张量流导入为 tf 从tensorflow.keras.losses导入损失

类WeightedIoULLoss(损失): def init(自身,weight_background=1.0,weight_foreground=1.0,epsilon=1e-7,**kwargs): 超级(WeightedIoULoss,自我)。init(**kwargs) self.weight_background = 权重背景 self.weight_foreground = 权重前景 self.epsilon = epsilon

def call(self, y_true, y_pred):
    intersection = tf.reduce_sum(y_true * y_pred)
    union = tf.reduce_sum(y_true + y_pred - y_true * y_pred)

    iou = (intersection + self.epsilon) / (union + self.epsilon)

    # Calculate the weighted IoU loss
    weighted_loss = -tf.math.log(iou) * (self.weight_background * (1 - y_true) + self.weight_foreground * y_true)

    return weighted_loss

使用示例

损失=WeightedIoULoss(weight_background=0.5,weight_foreground=1.5)

© www.soinside.com 2019 - 2024. All rights reserved.