如何在Keras中为序列模型实现损失函数(联合上的交集)?

时间:2018-08-14 15:31:35

标签: neural-network keras deep-learning conv-neural-network

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)

1 个答案:

答案 0 :(得分:2)

如果您对像素(不是方框)有预测,并且值在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