def border_(p, y, intervals=30, max_dur=None):
    # True borders = 
    p_labels = utils.segment_labels(p)
    y_labels = utils.segment_labels(y)
    
    p_starts = np.array([s[0] for s in utils.segment_intervals(p)])
    y_starts = np.array([s[0] for s in utils.segment_intervals(y)])

    dists = []
    n_true = len(y_labels)
    for i in range(n_true):
        start = y_starts[i]
        label = y_labels[i]
        idxs_same_labels = np.nonzero(p_labels==label)[0]
        if len(idxs_same_labels)>0:
            closest_correst = np.abs(p_starts[idxs_same_labels] - start).min()
        else:
            closest_correst = np.inf
        dists += [closest_correst]
    dists = np.array(dists)

    if max_dur is None:
        max_dur = np.max(dists)

    n_bins = int(np.ceil(max_dur / float(intervals)))
    scores = np.array([np.mean(dists<=i*intervals) for i in range(1, n_bins+1)])*100

    return scores
    def overlap_(p, y, bg_class):
        true_intervals = np.array(utils.segment_intervals(y))
        true_labels = utils.segment_labels(y)
        pred_intervals = np.array(utils.segment_intervals(p))
        pred_labels = utils.segment_labels(p)

        if bg_class is not None:
            true_intervals = np.array([
                t for t, l in zip(true_intervals, true_labels) if l != bg_class
            ])
            true_labels = np.array([l for l in true_labels if l != bg_class])
            pred_intervals = np.array([
                t for t, l in zip(pred_intervals, pred_labels) if l != bg_class
            ])
            pred_labels = np.array([l for l in pred_labels if l != bg_class])

        n_true_segs = true_labels.shape[0]
        n_pred_segs = pred_labels.shape[0]
        seg_scores = np.zeros(n_true_segs, np.float)

        for i in range(n_true_segs):
            for j in range(n_pred_segs):
                if true_labels[i] == pred_labels[j]:
                    intersection = min(
                        pred_intervals[j][1], true_intervals[i][1]) - max(
                            pred_intervals[j][0], true_intervals[i][0])
                    union = max(pred_intervals[j][1],
                                true_intervals[i][1]) - min(
                                    pred_intervals[j][0], true_intervals[i][0])
                    score_ = float(intersection) / union
                    seg_scores[i] = max(seg_scores[i], score_)

        return seg_scores.mean() * 100
    def overlap_(p, y, n_classes, bg_class, overlap):

        true_intervals = np.array(utils.segment_intervals(y))
        true_labels = utils.segment_labels(y)
        pred_intervals = np.array(utils.segment_intervals(p))
        pred_labels = utils.segment_labels(p)

        # Remove background labels
        if bg_class is not None:
            true_intervals = true_intervals[true_labels != bg_class]
            true_labels = true_labels[true_labels != bg_class]
            pred_intervals = pred_intervals[pred_labels != bg_class]
            pred_labels = pred_labels[pred_labels != bg_class]

        n_true = true_labels.shape[0]
        n_pred = pred_labels.shape[0]

        # We keep track of the per-class TPs, and FPs.
        # In the end we just sum over them though.
        TP = np.zeros(n_classes, np.float)
        FP = np.zeros(n_classes, np.float)
        true_used = np.zeros(n_true, np.float)

        for j in range(n_pred):
            # Compute IoU against all others
            intersection = np.minimum(
                pred_intervals[j, 1], true_intervals[:, 1]) - np.maximum(
                    pred_intervals[j, 0], true_intervals[:, 0])
            union = np.maximum(pred_intervals[j, 1],
                               true_intervals[:, 1]) - np.minimum(
                                   pred_intervals[j, 0], true_intervals[:, 0])
            IoU = (intersection / union) * (pred_labels[j] == true_labels)

            # Get the best scoring segment
            idx = IoU.argmax()

            # If the IoU is high enough and the true segment isn't already used
            # Then it is a true positive. Otherwise is it a false positive.
            if IoU[idx] >= overlap and not true_used[idx]:
                TP[pred_labels[j]] += 1
                true_used[idx] = 1
            else:
                FP[pred_labels[j]] += 1

        TP = TP.sum()
        FP = FP.sum()
        # False negatives are any unused true segment (i.e. "miss")
        FN = n_true - true_used.sum()

        precision = TP / (TP + FP)
        recall = TP / (TP + FN)
        F1 = 2 * (precision * recall) / (precision + recall)

        # If the prec+recall=0, it is a NaN. Set these to 0.
        F1 = np.nan_to_num(F1)

        return F1 * 100
def edit_score(P, Y, norm=True, bg_class=None, **kwargs):
    if type(P) == list:
        tmp = [edit_score(P[i], Y[i], norm, bg_class) for i in range(len(P))]
        return np.mean(tmp)
    else:
        P_ = utils.segment_labels(P)
        Y_ = utils.segment_labels(Y)
        if bg_class is not None:
            P_ = [c for c in P_ if c != bg_class]
            Y_ = [c for c in Y_ if c != bg_class]
        return levenstein_(P_, Y_, norm)
def lcs_score(P, Y):
    if type(P) == list:
        tmp = []
        for i in range(len(P)):
            P_ = utils.segment_labels(P[i])
            Y_ = utils.segment_labels(Y[i])            
            tmp += [lcs_(P_,Y_)]
        return np.mean(tmp)
    else:
        P_ = utils.segment_labels(P)
        Y_ = utils.segment_labels(Y)
        return lcs_(P_, Y_)
def edit_score(P, Y, norm=True):
    if type(P) == list:
        tmp = []
        for i in range(len(P)):
            P_ = utils.segment_labels(P[i])
            Y_ = utils.segment_labels(Y[i])            
            tmp += [levenstein_(P_,Y_,norm)]
        return np.mean(tmp)
    else:
        P_ = utils.segment_labels(P)
        Y_ = utils.segment_labels(Y)
        return levenstein_(P_, Y_, norm)
    def overlap_(p,y):
        true_intervals = np.array(utils.segment_intervals(y))
        true_labels = utils.segment_labels(y)
        pred_intervals = np.array(utils.segment_intervals(p))
        pred_labels = utils.segment_labels(p)

        n_true_segs = true_labels.shape[0]
        n_pred_segs = pred_labels.shape[0]
        seg_scores = np.zeros(n_true_segs, np.float)

        for i in range(n_true_segs):
            for j in range(n_pred_segs):
                if true_labels[i]==pred_labels[j]:
                    intersection = min(pred_intervals[j][1], true_intervals[i][1]) - max(pred_intervals[j][0], true_intervals[i][0])
                    union        = max(pred_intervals[j][1], true_intervals[i][1]) - min(pred_intervals[j][0], true_intervals[i][0])
                    score_ = float(intersection)/union
                    seg_scores[i] = max(seg_scores[i], score_)

        return seg_scores.mean()*100
def midpoint_(p,y):
    """
    As suggested in Rohrbach et al (IJCV15) for action detection
    """
    segs_p = utils.segment_intervals(p)
    segs_y = utils.segment_intervals(y)
    class_p = utils.segment_labels(p).tolist()
    class_y = utils.segment_labels(y).tolist()
    unused = np.ones(len(class_y), np.bool)
    n_true = len(segs_y)

    TP, FP, FN = 0, 0, 0
    # Go through each segment and check if it's correct.
    for i in range(len(segs_p)):
        midpoint = np.mean(segs_p[i])
        # Check each corresponding true segment
        for j in range(n_true):
            # If the midpoint is in this true segment
            if segs_y[j][0] <= midpoint <= segs_y[j][1]:
                # If yes and it's correct
                if (class_p[i] == class_y[j]):
                    # Only a TP if it's the first occurance. Otherwise FP
                    if unused[j]:
                        TP += 1
                        unused[j] = 0
                    else:
                        FP += 1
                # FN if it's wrong class
                else:
                    FN += 1
            elif midpoint < segs_y[j][0]:
                break


    prec = float(TP) / (TP+FP) * 100
    recall = float(TP) / (TP+FN) * 100

    return prec, recall
    def clf_(p, y, bg_class):
        sums = 0.
        n_segs = 0.

        S_true = utils.segment_labels(y)
        I_true = np.array(utils.segment_intervals(y))

        for i in range(len(S_true)):
            if S_true[i] == bg_class:
                continue

            # If p is 1d, compute the most likely label, otherwise take the max over the score
            if p.ndim == 1:
                pred_label = scipy.stats.mode(
                    p[I_true[i][0]:I_true[i][1]])[0][0]
            else:
                pred_label = p[I_true[i][0]:I_true[i][1]].mean(1).argmax()
            sums += pred_label == S_true[i]
            n_segs += 1

        return sums / n_segs * 100
def segmental_pw_cost(Yi, n_classes, skip=1):
    Yi_ = utils.segment_labels(Yi)
    return pw_cost(Yi_, n_classes, skip)
Example #11
0
def segmental_pw_cost(Yi, n_classes, skip=1):
    Yi_ = utils.segment_labels(Yi)
    return pw_cost(Yi_, n_classes, skip)