一、mAP精度計算
這里首先介紹幾個常見的模型評價術語,現在假設我們的分類目標只有兩類,計為正例(positive)和負例(negtive)分別是:
1)True positives(TP): 被正確地划分為正例的個數,即實際為正例且被分類器划分為正例的實例數(樣本數);
2)False positives(FP): 被錯誤地划分為正例的個數,即實際為負例但被分類器划分為正例的實例數;
3)False negatives(FN):被錯誤地划分為負例的個數,即實際為正例但被分類器划分為負例的實例數;
4)True negatives(TN): 被正確地划分為負例的個數,即實際為負例且被分類器划分為負例的實例數。
P
代表precision即准確率,計算公式為預測樣本中實際正樣本數 / 所有的正樣本數 即 precision=TP/(TP+FP);
R
代表recall即召回率,計算公式為 預測樣本中實際正樣本數 / 預測的樣本數即 Recall=TP/(TP+FN)=TP/P
一般來說,precision和recall是魚與熊掌的關系,往往召回率越高,准確率越低
AP
AP 即 Average Precision即平均精確度
mAP
mAP 即 Mean Average Precision即平均AP值,是對多個驗證集個體求平均AP值,作為 object dection中衡量檢測精度的指標。
F
度量(F-measure),F度量涵蓋了准確率和召回率這兩個指標。其計算公式如下:F = 2 * P * R / (P + R)
P-R曲線
P-R曲線即 以 precision 和 recall 作為 縱、橫軸坐標 的二維曲線。通過選取不同閾值時對應的精度和召回率畫出
總體趨勢,精度越高,召回越低,當召回達到1時,對應概率分數最低的正樣本,這個時候正樣本數量除以所有大於等於該閾值的樣本數量就是最低的精度值。
另外,P-R曲線圍起來的面積就是AP值,通常來說一個越好的分類器,AP值越高。
總結一下,在目標檢測中,每一類都可以根據 recall 和 precision繪制P-R曲線,AP就是該曲線下的面積,mAP就是所有類AP的平均值。
二.評測代碼
import tensorflow as tf
#精確率評價指標
def metric_precision(y_true,y_pred):
TP=tf.reduce_sum(y_true*tf.round(y_pred))
TN=tf.reduce_sum((1-y_true)*(1-tf.round(y_pred)))
FP=tf.reduce_sum((1-y_true)*tf.round(y_pred))
FN=tf.reduce_sum(y_true*(1-tf.round(y_pred)))
precision=TP/(TP+FP)
return precision
#召回率評價指標
def metric_recall(y_true,y_pred):
TP=tf.reduce_sum(y_true*tf.round(y_pred))
TN=tf.reduce_sum((1-y_true)*(1-tf.round(y_pred)))
FP=tf.reduce_sum((1-y_true)*tf.round(y_pred))
FN=tf.reduce_sum(y_true*(1-tf.round(y_pred)))
recall=TP/(TP+FN)
return recall
#F1-score評價指標
def metric_F1score(y_true,y_pred):
TP=tf.reduce_sum(y_true*tf.round(y_pred))
TN=tf.reduce_sum((1-y_true)*(1-tf.round(y_pred)))
FP=tf.reduce_sum((1-y_true)*tf.round(y_pred))
FN=tf.reduce_sum(y_true*(1-tf.round(y_pred)))
precision=TP/(TP+FP)
recall=TP/(TP+FN)
F1score=2*precision*recall/(precision+recall)
return F1score<br><br>
#編譯階段引用自定義評價指標示例
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy',
metric_precision,
metric_recall,
metric_F1score])
# AUC for a binary classifier
def auc(y_true, y_pred):
ptas = tf.stack([binary_PTA(y_true,y_pred,k) for k in np.linspace(0, 1, 1000)],axis=0)
pfas = tf.stack([binary_PFA(y_true,y_pred,k) for k in np.linspace(0, 1, 1000)],axis=0)
pfas = tf.concat([tf.ones((1,)) ,pfas],axis=0)
binSizes = -(pfas[1:]-pfas[:-1])
s = ptas*binSizes
return K.sum(s, axis=0)
#-----------------------------------------------------------------------------------------------------------------------------------------------------
# PFA, prob false alert for binary classifier
def binary_PFA(y_true, y_pred, threshold=K.variable(value=0.5)):
y_pred = K.cast(y_pred >= threshold, 'float32')
# N = total number of negative labels
N = K.sum(1 - y_true)
# FP = total number of false alerts, alerts from the negative class labels
FP = K.sum(y_pred - y_pred * y_true)
return FP/N
#-----------------------------------------------------------------------------------------------------------------------------------------------------
# P_TA prob true alerts for binary classifier
def binary_PTA(y_true, y_pred, threshold=K.variable(value=0.5)):
y_pred = K.cast(y_pred >= threshold, 'float32')
# P = total number of positive labels
P = K.sum(y_true)
# TP = total number of correct alerts, alerts from the positive class labels
TP = K.sum(y_pred * y_true)
return TP/P
#接着在模型的compile中設置metrics
# False Discovery Rate(FDR)
from sklearn.metrics import confusion_matrix
y_true = [0,0,0,0,0,0,,1,1,1,1,1]
y_pred = [0,0,0,0,0,0,,1,1,1,1,1]
tn, fp , fn, tp = confusion_matrix(y_true, y_pred).ravel()
fdr = fp / (fp + tp)
print(fdr)