deeplabv3+源码之慢慢解析10 第三章metrics文件夹stream_metrics.py--StreamSegMetrics类和AverageMeter类

系列文章目录(共五章33节已完结)

第一章deeplabv3+源码之慢慢解析 根目录(1)main.py–get_argparser函数
第一章deeplabv3+源码之慢慢解析 根目录(2)main.py–get_dataset函数
第一章deeplabv3+源码之慢慢解析 根目录(3)main.py–validate函数
第一章deeplabv3+源码之慢慢解析 根目录(4)main.py–main函数
第一章deeplabv3+源码之慢慢解析 根目录(5)predict.py–get_argparser函数和main函数

第二章deeplabv3+源码之慢慢解析 datasets文件夹(1)voc.py–voc_cmap函数和download_extract函数
第二章deeplabv3+源码之慢慢解析 datasets文件夹(2)voc.py–VOCSegmentation类
第二章deeplabv3+源码之慢慢解析 datasets文件夹(3)cityscapes.py–Cityscapes类
第二章deeplabv3+源码之慢慢解析 datasets文件夹(4)utils.py–6个小函数

第三章deeplabv3+源码之慢慢解析 metrics文件夹stream_metrics.py–StreamSegMetrics类和AverageMeter类

第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(a1)hrnetv2.py–4个函数和可执行代码
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(a2)hrnetv2.py–Bottleneck类和BasicBlock类
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(a3)hrnetv2.py–StageModule类
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(a4)hrnetv2.py–HRNet类
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(b1)mobilenetv2.py–2个类和2个函数
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(b2)mobilenetv2.py–MobileNetV2类和mobilenet_v2函数
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(c1)resnet.py–2个基础函数,BasicBlock类和Bottleneck类
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(c2)resnet.py–ResNet类和10个不同结构的调用函数
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(d1)xception.py–SeparableConv2d类和Block类
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(d2)xception.py–Xception类和xception函数
第四章deeplabv3+源码之慢慢解析 network文件夹(2)_deeplab.py–ASPP相关的4个类和1个函数
第四章deeplabv3+源码之慢慢解析 network文件夹(3)_deeplab.py–DeepLabV3类,DeepLabHeadV3Plus类和DeepLabHead类
第四章deeplabv3+源码之慢慢解析 network文件夹(4)modeling.py–5个私有函数(4个骨干网,1个模型载入)
第四章deeplabv3+源码之慢慢解析 network文件夹(5)modeling.py–12个调用函数
第四章deeplabv3+源码之慢慢解析 network文件夹(6)utils.py–_SimpleSegmentationModel类和IntermediateLayerGetter类

第五章deeplabv3+源码之慢慢解析 utils文件夹(1)ext_transforms.py.py–2个翻转类和ExtCompose类
第五章deeplabv3+源码之慢慢解析 utils文件夹(2)ext_transforms.py.py–2个裁剪类和2个缩放类
第五章deeplabv3+源码之慢慢解析 utils文件夹(3)ext_transforms.py.py–旋转类,填充类,张量转化类和标准化类
第五章deeplabv3+源码之慢慢解析 utils文件夹(4)ext_transforms.py.py–ExtResize类,ExtColorJitter类,Lambda类和Compose类
第五章deeplabv3+源码之慢慢解析 utils文件夹(5)loss.py–FocalLoss类
第五章deeplabv3+源码之慢慢解析 utils文件夹(6)scheduler.py–PolyLR类
第五章deeplabv3+源码之慢慢解析 utils文件夹(7)utils.py–去标准化,momentum设定,标准化层锁定和路径创建
第五章deeplabv3+源码之慢慢解析 utils文件夹(8)visualizer.py–Visualizer类(完结)


前期准备和说明

提示:源码众多,此次选这个版本pytorch版

  1. 已经理解了前2章的代码。
  2. metrics度量,指标的意思,本文件夹的代码顾名思义。需要理解基本的度量指标理论知识。

总体目录

提示:metrics文件夹的总体结构如下,只有stream_metrics.py需要详解。
在这里插入图片描述

__init__.py

#一句话,简单明了。
from .stream_metrics import StreamSegMetrics, AverageMeter

stream_metrics.py导入

import numpy as np
from sklearn.metrics import confusion_matrix  #导入了混淆矩阵confusion_matrix,各种度量必用。

_StreamMetrics类

提示:此内部类偏重设计,所有功能需要子类重写实现。详见下面StreamMetrics类。

class _StreamMetrics(object):
    def __init__(self):
        """ Overridden by subclasses """
        raise NotImplementedError()  #raise抛出异常,此内部类各个函数需要子类重写。

    def update(self, gt, pred):
        """ Overridden by subclasses """
        raise NotImplementedError()

    def get_results(self):
        """ Overridden by subclasses """
        raise NotImplementedError()

    def to_str(self, metrics):
        """ Overridden by subclasses """
        raise NotImplementedError()

    def reset(self):
        """ Overridden by subclasses """
        raise NotImplementedError()     

StreamMetrics类

提示:这个类是_StreamMetrics类的子类,实现具体功能。

class StreamSegMetrics(_StreamMetrics):
    """
    Stream Metrics for Semantic Segmentation Task
    """
    def __init__(self, n_classes):
        self.n_classes = n_classes    #n_classes参数传入分类数目。
        self.confusion_matrix = np.zeros((n_classes, n_classes))   #构造初始化混淆矩阵。

    def update(self, label_trues, label_preds):
        for lt, lp in zip(label_trues, label_preds): #zip()函数,将对应的标签和预测值打包成对(元组)。
            self.confusion_matrix += self._fast_hist( lt.flatten(), lp.flatten() ) #详见下文_fast_hist函数。
    
    @staticmethod   #静态方法,和类方法不同,面向对象要学好!!!(注java中静态方法和类方法是同一个东西,python中不是一个东西,有区别,建议新手好好学习一些基本概念。后补小链接。)
    def to_str(results):  #将结果转为字符串(以便显示)。
        string = "\n"
        for k, v in results.items():   #从结果中取值。
            if k!="Class IoU":
                string += "%s: %f\n"%(k, v)   #以字符串形式显示结果中非IoU的k,v值。
        
        #string+='Class IoU:\n'
        #for k, v in results['Class IoU'].items():
        #    string += "\tclass %d: %f\n"%(k, v)
        return string

    def _fast_hist(self, label_true, label_pred):    #此函数详细例子后补链接。
        mask = (label_true >= 0) & (label_true < self.n_classes) #即label_true在训练分类的数目之内,则mask=True。不在训练分类id里(未标注数据)的常被设置成-1或255,详见datasets第二章的讲解。
        hist = np.bincount( #np.bincount是统计从0到array数组中最大数字出现的个数的函数,并同样以array数组输出显示。后补链接。
            self.n_classes * label_true[mask].astype(int) + label_pred[mask],    #n_classes*n_classes的矩阵,获得label_true[mask]行,label_pred[mask]列的完整矩阵值。对角线上的都是真值==预测值的数量,其他位置不为0的,就是不相等的。如第i项为ai*n+bi,若ai==bi,则结果是n的整数倍,即统计时在对角线上。
            minlength=self.n_classes ** 2,  #结果大小最小为n_classes*n_classes,不能小于原矩阵,不足的补零。结果是个长向量。
        ).reshape(self.n_classes, self.n_classes)   #将结果转为矩阵n_classes*n_classes。
        return hist  #返回统计图。

    def get_results(self):  #后补详细公式对应代码链接。
        """Returns accuracy score evaluation result.  #计算以下四项。
            - overall accuracy
            - mean accuracy
            - mean IU
            - fwavacc
        """
        hist = self.confusion_matrix
        acc = np.diag(hist).sum() / hist.sum()   #ACC准确率(PA像素准确率)=对角线之和(正确的)/全部的和(总)
        acc_cls = np.diag(hist) / hist.sum(axis=1)  #MPA平均像素准确率(step1)计算每个类内被正确分类像素数的比例。
        acc_cls = np.nanmean(acc_cls)               #MPA(step2)再求所有类的平均。
        iu = np.diag(hist) / (hist.sum(axis=1) + hist.sum(axis=0) - np.diag(hist))  #IoU真实集和预测集交并比,交集就是对角线,并集就是(行和 + 列和 - 对角线)。
        mean_iu = np.nanmean(iu)   #MIoU平均交并比。
        freq = hist.sum(axis=1) / hist.sum()  #FWIoU频权交并比,以每类出现频率为权重,与IoU进行加权计算。
        fwavacc = (freq[freq > 0] * iu[freq > 0]).sum()
        cls_iu = dict(zip(range(self.n_classes), iu))   #每个类对应的交并比。

        return {
                "Overall Acc": acc,
                "Mean Acc": acc_cls,
                "FreqW Acc": fwavacc,
                "Mean IoU": mean_iu,
                "Class IoU": cls_iu,
            }
        
    def reset(self):      #重置混淆矩阵,即初始化为0.
        self.confusion_matrix = np.zeros((self.n_classes, self.n_classes)) 

AverageMeter类

提示:计算均值。

class AverageMeter(object):
    """Computes average values"""
    def __init__(self):
        self.book = dict()   #初始化字典

    def reset_all(self):
        self.book.clear()   #清空。
    
    def reset(self, id):
        item = self.book.get(id, None)   #按id重置对应的条目为(0,0)。
        if item is not None:
            item[0] = 0
            item[1] = 0

    def update(self, id, val):
        record = self.book.get(id, None)   #按id赋值条目为(val,1)
        if record is None:
            self.book[id] = [val, 1]
        else:
            record[0]+=val
            record[1]+=1

    def get_results(self, id):
        record = self.book.get(id, None)  #按id计算条目record[0] / record[1]
        assert record is not None
        return record[0] / record[1]     

Tips

  1. 补充Python3中静态方法和类方法,实例方法,这个比较短小,方便快速理解,详细理解建议系统学习Python。

  2. 补充np.bincount详解

  3. 补充_fast_hist函数详解

  4. 补充语义分割衡量指标详解1语义分割衡量指标详解2

  5. 下一章进入network文件夹,主要是网络模型的代码。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值