小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

深度學習100問-17:圖語義分割有哪些常用的評價指標?

 LibraryPKU 2020-02-15

深度學習100問

Author:louwill

Machine Learning Lab

     語義分割作為經典的圖像分割問題,其本質上還是一種圖像像素分類。既然是分類,我們就可以使用常見的分類評價指標來評估模型好壞。語義分割常見的評價指標包括像素準確率(Pixel Accuracy)、平均像素準確率(Mean Pixel Accuracy)、平均交并比(Mean IoU)、頻權交并比(FWIoU)和Dice系數(Dice Coeffcient)等。

     這些指標看似跟常見的分類指標不太一樣,但本質上都是基于分類混淆矩陣進行計算的。像素準確率也就是分類評價指標中的準確率(Accuracy)、平均準確率就是分類中的平均精確率(Mean Precision)、Dice系數則是F1-Score,只有平均交并比(MIoU)和頻權交并比(FWIoU)在分類指標中找不對對應,但也可以基于混淆矩陣進行計算。

     假設圖像中有n個目標類,那么加上背景類則是n+1,其中p_ii表示原本為i類同時也預測為i類,對應到混淆矩陣中則是TP(真陽)+TN(真陰),p_ij表示為原本為i類預測為j類,可以表示為FP(假陽),p_ji則為FN(假陰)。根據像素分類混淆矩陣,我們就可以計算如下指標。

像素準確率(PA)

     像素準確率跟分類中的準確率含義一樣,即所有分類正確的像素數占全部像素的比例。PA的計算公式如下:


     對應到混淆矩陣中,則可以計算為:


平均像素準確率(MPA)

     平均像素準確率其實更應該叫平均像素精確率,是指分別計算每個類別分類正確的像素數占所有預測為該類別像素數比例的平均值。所以,從定義上看,這是精確率(Precision)的定義,MPA的計算公式如下:


     對應到混淆矩陣中,Precison可計算為:


平均交并比(MIoU)

     交并比(Intersection over Union)的定義很簡單,將標簽圖像和預測圖像看成是兩個集合,計算兩個集合的交集和并集的比值。而平均交并比則是將所有類的IoU取平均。MIoU的計算公式如下:

     這里注意公式中的分母,p_ii在前兩項中都被計算了一次,所以還需要單獨減掉一次。
     對應到混淆矩陣中,IoU可以計算為:

     具體如下圖所示。交集為TP,并集為TP+FP+FN。

     以一張具體圖像為例感受下IoU,下圖是Ground Truth和預測圖像,可以看到預測和真值還是有些差距的。

     兩張圖像的交集和并集對應到圖像中,計算兩張圖像的比值即可。

頻權交并比(FWIoU)

     頻權交并比顧名思義,就是以每一類別的頻率為權重和其IoU加權計算出來的結果。FWIoU的設計思想很明確,語義分割很多時候會面臨圖像中各目標類別不平衡的情況,對各類別IoU直接求平均不是很合理,所以考慮各類別的權重就非常重要了。FWIoU的計算公式如下:


     對應到混淆矩陣中可以計算為:


     其中每個類別的真實像素量為TP+FN,除以總像素量即可得到每個類別像素權重。

Dice系數

     Dice系數是一種度量兩個集合相似性的函數,是語義分割中最常用的評價指標之一。Dice系數定義為兩倍的交集除以像素和,跟IoU有點類似,其計算公式如下:


     Dice系數對應到分類指標中則是F1得分,其計算公式為精確率和召回率的調和平均數。對應到混淆矩陣中,用precision和recall的公式可以推導Dice的計算公式為:


     可以看到Dice系數對應于IoU,分子分母中的TP都取了兩倍。通常1-Dice可作為語義分割的損失函數。Dice作為筆者常用的語義分割評價指標,這里給出Dice在Keras和PyTorch中的實現方式。

     Keras實現方式:
from keras import backend as K
def dice_coef(y_true, y_pred, smooth=1):    ''' Dice = (2*|X & Y|)/ (|X|+ |Y|)
         =  2*sum(|A*B|)/(sum(A^2)+sum(B^2))    '''    y_true = K.flatten(y_true)    y_pred = K.flatten(y_pred)    intersection = K.sum(K.abs(y_true * y_pred))    dice = (2. * intersection + smooth) / (K.sum(K.square(y_true)) + K.sum(K.square(y_pred)) + smooth) return dice
     PyTorch實現方式:
import torch
def dice_coef(pred, target):    '''    Dice = (2*|X & Y|)/ (|X|+ |Y|)         =  2*sum(|A*B|)/(sum(A^2)+sum(B^2))    '''    smooth = 1.    m1 = pred.view(-1).float()    m2 = target.view(-1).float()    intersection = (m1 * m2).sum().float()    dice = (2. * intersection + smooth) / (torch.pow(m1, 2).sum() + torch.pow(m2,2).sum() + smooth) return dice
     最后基于numpy實現一個包含全部分割指標的類:
import numpy as np
class SegMetrics(object):    def __init__(self, num_class):        self.num_class = num_class self.confusion_matrix = np.zeros((self.num_class,)*2)
    # 像素準確率    def Pixel_Accuracy(self):        Acc = np.diag(self.confusion_matrix).sum() / self.confusion_matrix.sum() return Acc
    # 平均像素準確率    def Mean_Pixel_Accuracy(self):        # Precision=TP/(TP+FP)        Acc = np.diag(self.confusion_matrix) / self.confusion_matrix.sum(axis=1)        Acc = np.nanmean(Acc) return Acc
    # 平均IoU    def Mean_IoU(self):        MIoU = np.diag(self.confusion_matrix) / (                    np.sum(self.confusion_matrix, axis=1) + np.sum(self.confusion_matrix, axis=0) -                    np.diag(self.confusion_matrix))        MIoU = np.nanmean(MIoU) return MIoU
    # 頻權IoU    def Freq_Weighted_IoU(self):        freq = np.sum(self.confusion_matrix, axis=1) / np.sum(self.confusion_matrix)        iu = np.diag(self.confusion_matrix) / (np.sum(self.confusion_matrix, axis=1) + np.sum(self.confusion_matrix, axis=0) -                    np.diag(self.confusion_matrix))        FWIoU = (freq[freq > 0] * iu[freq > 0]).sum()        return FWIoU  
    # Dice系數    def dice(self):        dice_coef = 2*np.diag(self.confusion_matrix) / (            np.sum(self.confusion_matrix, axis=1) + np.sum(self.confusion_matrix, axis=0)) return dice_coef
    # 生成混淆矩陣    def _generate_matrix(self, gt_image, pre_image):        mask = (gt_image >= 0) & (gt_image < self.num_class)        label = self.num_class * gt_image[mask] + pre_image[mask]        count = np.bincount(label, minlength=self.num_class**2)        confusion_matrix = count.reshape(self.num_class, self.num_class) return confusion_matrix
    # 為真值和預測值生成混淆矩陣    def add_batch(self, gt_image, pre_image):        assert gt_image.shape == pre_image.shape self.confusion_matrix += self._generate_matrix(gt_image, pre_image)
# 重置混淆矩陣    def reset(self): self.confusion_matrix = np.zeros((self.num_class,) * 2)
     以上就是本節(jié)內容。

參考資料:

https://www./evaluating-image-segmentation-models/

https://github.com/xtudbxk/semantic-segmentation-metrics

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多