如何用keras/tf/pytorch实现TP/TN/FP/FN和accuracy/sensiivity/precision/specificity/f1-score等评价指标(python)

0. Metrics introduction

点击进入

1. Keras version

def cal_base(y_true, y_pred):
    y_pred_positive = K.round(K.clip(y_pred, 0, 1))
    y_pred_negative = 1 - y_pred_positive

    y_positive = K.round(K.clip(y_true, 0, 1))
    y_negative = 1 - y_positive

    TP = K.sum(y_positive * y_pred_positive)
    TN = K.sum(y_negative * y_pred_negative)

    FP = K.sum(y_negative * y_pred_positive)
    FN = K.sum(y_positive * y_pred_negative)

    return TP, TN, FP, FN


def acc(y_true, y_pred):
    TP, TN, FP, FN = cal_base(y_true, y_pred)
    ACC = (TP + TN) / (TP + FP + FN + TN + K.epsilon())
    return ACC


def sensitivity(y_true, y_pred):
    """ recall """
    TP, TN, FP, FN = cal_base(y_true, y_pred)
    SE = TP/(TP + FN + K.epsilon())
    return SE


def precision(y_true, y_pred):
    TP, TN, FP, FN = cal_base(y_true, y_pred)
    PC = TP/(TP + FP + K.epsilon())
    return PC


def specificity(y_true, y_pred):
    TP, TN, FP, FN = cal_base(y_true, y_pred)
    SP = TN / (TN + FP + K.epsilon())
    return SP


def f1_socre(y_true, y_pred):
    SE = sensitivity(y_true, y_pred)
    PC = precision(y_true, y_pred)
    F1 = 2 * SE * PC / (SE + PC + K.epsilon())
    return F1

2. Pytorch version

"""
reference from: https://github.com/LeeJunHyun/Image_Segmentation/blob/master/evaluation.py
"""

import torch

# SR : Segmentation Result
# GT : Ground Truth

def get_accuracy(SR,GT,threshold=0.5):
    SR = SR > threshold
    GT = GT == torch.max(GT)
    corr = torch.sum(SR==GT)
    tensor_size = SR.size(0)*SR.size(1)*SR.size(2)*SR.size(3)
    acc = float(corr)/float(tensor_size)

    return acc

def get_sensitivity(SR,GT,threshold=0.5):
    # Sensitivity == Recall
    SR = SR > threshold
    GT = GT == torch.max(GT)

    # TP : True Positive
    # FN : False Negative
    TP = ((SR==1)+(GT==1))==2
    FN = ((SR==0)+(GT==1))==2

    SE = float(torch.sum(TP))/(float(torch.sum(TP+FN)) + 1e-6)     
    
    return SE

def get_specificity(SR,GT,threshold=0.5):
    SR = SR > threshold
    GT = GT == torch.max(GT)

    # TN : True Negative
    # FP : False Positive
    TN = ((SR==0)+(GT==0))==2
    FP = ((SR==1)+(GT==0))==2

    SP = float(torch.sum(TN))/(float(torch.sum(TN+FP)) + 1e-6)
    
    return SP

def get_precision(SR,GT,threshold=0.5):
    SR = SR > threshold
    GT = GT == torch.max(GT)

    # TP : True Positive
    # FP : False Positive
    TP = ((SR==1)+(GT==1))==2
    FP = ((SR==1)+(GT==0))==2

    PC = float(torch.sum(TP))/(float(torch.sum(TP+FP)) + 1e-6)

    return PC

def get_F1(SR,GT,threshold=0.5):
    # Sensitivity == Recall
    SE = get_sensitivity(SR,GT,threshold=threshold)
    PC = get_precision(SR,GT,threshold=threshold)

    F1 = 2*SE*PC/(SE+PC + 1e-6)

    return F1

def get_JS(SR,GT,threshold=0.5):
    # JS : Jaccard similarity
    SR = SR > threshold
    GT = GT == torch.max(GT)
    
    Inter = torch.sum((SR+GT)==2)
    Union = torch.sum((SR+GT)>=1)
    
    JS = float(Inter)/(float(Union) + 1e-6)
    
    return JS

def get_DC(SR,GT,threshold=0.5):
    # DC : Dice Coefficient
    SR = SR > threshold
    GT = GT == torch.max(GT)

    Inter = torch.sum((SR+GT)==2)
    DC = float(2*Inter)/(float(torch.sum(SR)+torch.sum(GT)) + 1e-6)

    return DC

3- Tensorflow version

import tensorflow as tf


class Metrics(object):
    def __init__(self, gt, predict):
        self.gt = gt
        self.pd = predict
        self.epsilon = tf.keras.backend.epsilon()
        self.tp, self.tn, self.fp, self.fn = self.calc_base()

    def get_iou(self):
        """ intersection over union """
        iou = self.tp / (self.tp + self.fp + self.fn + self.epsilon)

        return iou

    def get_dice(self):
        """ dice coefficient """
        dice = (2 * self.tp) / (2 * self.tp + self.fp + self.fn + self.epsilon)

        return dice

    def get_info(self):
        print("ground truth: ", self.gt)
        print("predict: ", self.pd)

    def calc_base(self):
        gt = tf.convert_to_tensor(self.gt)
        pd = tf.convert_to_tensor(self.pd)

        gt_positive = tf.round(tf.clip_by_value(gt, 0, 1))
        gt_negative = 1 - gt_positive

        pd_positive = tf.round(tf.clip_by_value(pd, 0, 1))
        pd_negative = 1 - pd_positive

        tp = tf.reduce_sum(gt_positive * pd_positive)
        tn = tf.reduce_sum(gt_negative * pd_negative)
        fp = tf.reduce_sum(gt_negative * pd_positive)
        fn = tf.reduce_sum(gt_positive * pd_negative)

        return tp, tn, fp, fn

    def get_recall(self):
        """ sensitivity or recall """
        recall = self.tp / (self.tp + self.fn + self.epsilon)

        return recall

    def get_f1_score(self):
        """ f1-score """
        recall = self.get_recall()
        precision = self.get_precision()
        f1_score = 2 * recall * precision / (recall + precision + self.epsilon)

        return f1_score

    def get_accuracy(self):
        """ accuracy """
        accuracy = (self.tp + self.tn) / (self.tp + self.tn + self.fp + self.fn + self.epsilon)

        return accuracy

    def get_precision(self):
        """ precision """
        precision = self.tp / (self.tp + self.fp + self.epsilon)

        return precision

    def get_specificity(self):
        """ specificity """
        specificity = self.tn / (self.tn + self.fp + self.epsilon)

        return specificity

有问题欢迎添加微信号:cv_huber或扫描关注以下二维码,备注“CSDN”,了解每日AI最新资讯。
如何用keras/tf/pytorch实现TP/TN/FP/FN和accuracy/sensiivity/precision/specificity/f1-score等评价指标(python)_第1张图片

你可能感兴趣的:(机器学习,metrics,keras,pytorch,python,tensorflow)