首页 > 解决方案 > 如何在 Keras 中为 Sequential 模型实现损失函数(Intersection over Union)?

问题描述

IoU 是一个损失函数,需要最大化而不是最小化。这是我尝试过的,但我无法访问 max 函数中的参数值:

def bb_intersection_over_union(boxA, boxB):

    # determine the (x, y)-coordinates of the intersection rectangle
    xA = max(boxA[0], boxB[0])       #error in THESE lines
    yA = max(boxA[1], boxB[1])
    xB = min(boxA[2], boxB[2])
    yB = min(boxA[3], boxB[3])

    # compute the area of intersection rectangle
    interArea = max(0, xB - xA + 1) * max(0, yB - yA + 1)

    # compute the area of both the prediction and ground-truth
    # rectangles
    boxAArea = (boxA[2] - boxA[0] + 1) * (boxA[3] - boxA[1] + 1)    
    boxBArea = (boxB[2] - boxB[0] + 1) * (boxB[3] - boxB[1] + 1)

    # compute the intersection over union by taking the intersection
    # area and dividing it by the sum of prediction + ground-truth
    # areas - the interesection area
    iou = interArea / float(boxAArea + boxBArea - interArea)

    # return the intersection over union value
    return iou

这是我在 Internet 上找到的代码:(这行得通吗?看起来不像 IoU。

import numpy as np
def computeIoU(y_pred_batch, y_true_batch):
    return np.mean(np.asarray([pixelAccuracy(y_pred_batch[i], y_true_batch[i]) 
for i in range(len(y_true_batch))])) 

def pixelAccuracy(y_pred, y_true):
    y_pred = np.argmax(np.reshape(y_pred, 
    [N_CLASSES_PASCAL,img_rows,img_cols]),axis=0)
    y_true = np.argmax(np.reshape(y_true, 
   [N_CLASSES_PASCAL,img_rows,img_cols]),axis=0)
        y_pred = y_pred * (y_true>0)

        return 1.0 * np.sum((y_pred==y_true)*(y_true>0)) /  np.sum(y_true>0)

标签: neural-networkkerasdeep-learningconv-neural-network

解决方案


如果您有像素(不是框)的预测,以及 0 到 1 之间的值。(对于单类,存在/不存在)

def iou(true, pred):

    intersection = true * pred

    notTrue = 1 - true
    union = true + (notTrue * pred)

    return K.sum(intersection)/K.sum(union)

您的函数已调整(我不知道它是否正常工作,存在风险或由于交叉点 = 常数 0 而没有梯度)

def iou(boxA,boxB):

    xA = K.stack([boxA[:,0], boxB[:,0]], axis=-1)
    yA = K.stack([boxA[:,1], boxB[:,1]], axis=-1)
    xB = K.stack([boxA[:,2], boxB[:,2]], axis=-1)
    yB = K.stack([boxA[:,3], boxB[:,3]], axis=-1)

    xA = K.max(xA, axis=-1)
    yA = K.max(yA, axis=-1)
    xB = K.min(xB, axis=-1)
    yB = K.min(yB, axis=-1)

    interX = K.zeros_like(xB)
    interY = K.zeros_like(yB)

    interX = K.stack([interX, xB-xA + 1], axis=-1)
    interY = K.stack([interY, yB-yA + 1], axis=-1)

    #because of these "max", interArea may be constant 0, without gradients, and you may have problems with no gradients. 
    interX = K.max(interX, axis=-1)
    interY = K.max(interY, axis=-1)
    interArea = interX * interY

    boxAArea = (boxA[:,2] - boxA[:,0] + 1) * (boxA[:,3] - boxA[:,1] + 1)    
    boxBArea = (boxB[:,2] - boxB[:,0] + 1) * (boxB[:,3] - boxB[:,1] + 1) 

    iou = interArea / (boxAArea + boxBArea - interArea)

    return iou

推荐阅读