Dice 系数的介绍及实现

Dice系数原理

Dice是医学图像比赛中使用频率最高的度量指标,它是一种集合相似度度量指标,通常用于计算两个样本的相似度,值阈为[0, 1]。在医学图像中经常用于图像分割,分割的最好结果是1,最差时候结果为0.

Dice系数计算公式如下:

当然Dice也有另一个表达方式,是利用混淆矩阵中的TP,FP,FN来表达:

该公式原理如下图:

MindSpore代码实现

先简单介绍一下MindSpore——新一代AI开源计算框架。创新编程范式,AI科学家和工程师更易使用,便于开放式创新;该计算框架可满足终端边缘计算云全场景需求,能更好保护数据隐私;可开源,形成广阔应用生态

2020年3月28日,华为在开发者大会2020上宣布,全场景AI计算框架MindSpore在码云正式开源。MindSpore着重提升易用性并降低AI开发者的开发门槛,MindSpore原生适应每个场景包括端、边缘和云,并能够在按需协同的基础上,通过实现AI算法即代码,使开发态变得更加友好显著减少模型开发时间降低模型开发门槛

通过MindSpore自身的技术创新及MindSpore与华为昇腾AI处理器的协同优化,实现了运行态的高效,大大提高了计算性能;MindSpore也支持GPU、CPU等其它处理器。

"""Dice"""
import numpy as np
from mindspore._checkparam import Validator as validator
from .metric import Metricclass Dice(Metric):def __init__(self, smooth=1e-5):super(Dice, self).__init__()self.smooth = validator.check_positive_float(smooth, "smooth")self._dice_coeff_sum = 0self._samples_num = 0self.clear()def clear(self):# 是来清除历史数据self._dice_coeff_sum = 0self._samples_num = 0def update(self, *inputs):# 更新输入数据,y_pred和y,数据输入类型可以是Tensor,lisy或numpy,维度必须相等if len(inputs) != 2:raise ValueError('Dice need 2 inputs (y_pred, y), but got {}'.format(len(inputs)))# 将数据进行转换,统一转换为numpyy_pred = self._convert_data(inputs[0])y = self._convert_data(inputs[1])self._samples_num += y.shape[0]if y_pred.shape != y.shape:raise RuntimeError('y_pred and y should have same the dimension, but the shape of y_pred is{}, ''the shape of y is {}.'.format(y_pred.shape, y.shape))# 先求交集,利用dot对应点相乘再相加intersection = np.dot(y_pred.flatten(), y.flatten())# 求并集,先将输入shape都拉到一维,然后分别进行点乘,再将两个输入进行相加  unionset = np.dot(y_pred.flatten(), y_pred.flatten()) + np.dot(y.flatten(), y.flatten())# 利用公式进行计算,加smooth是为了防止分母为0,避免当pred和true都为0时,分子被0除的问题,同时减少过拟合single_dice_coeff = 2 * float(intersection) / float(unionset + self.smooth)# 对每一批次的系数进行累加self._dice_coeff_sum += single_dice_coeffdef eval(self):# 进行计算if self._samples_num == 0:raise RuntimeError('Total samples num must not be 0.')return self._dice_coeff_sum / float(self._samples_num)

使用方法如下:

import numpy as np
from mindspore import Tensor
from mindspore.nn.metrics Dicemetric = Dice(smooth=1e-5)
metric.clear()
x = Tensor(np.array([[0.2, 0.5], [0.3, 0.1], [0.9, 0.6]]))
y = Tensor(np.array([[0, 1], [1, 0], [0, 1]]))
metric.update(x, y)
dice = metric.eval()
print(dice)0.20467791371802546

每个batch(两组数据)进行计算的时候如下:

import numpy as np
from mindspore import Tensor
from mindspore.nn.metrics Dicemetric = Dice(smooth=1e-5)
metric.clear()
x = Tensor(np.array([[0.2, 0.5], [0.3, 0.1], [0.9, 0.6]]))
y = Tensor(np.array([[0, 1], [1, 0], [0, 1]]))
metric.update(x, y)x1= Tensor(np.array([[0.2, 0.5], [0.3, 0.1], [0.9, 0.6]]))
y1 = Tensor(np.array([[1, 0], [1, 1], [1, 0]]))
metric.update(x1, y1)
avg_dice = metric.eval()
print(dice)

Dice Loss 介绍及实现

Dice Loss原理

Dice Loss 原理是在 Dice 系数的基础上进行计算,用1去减Dice系数

这种是在二分类一个批次只有一张图的情况,当一个批次有N张图片时,可以将图片压缩为一维向量,如下图:

对应的label也会相应变化,最后一起计算N张图片的Dice系数和Dice Loss。

MindSpore 二分类 DiceLoss 代码实现

class DiceLoss(_Loss):def __init__(self, smooth=1e-5):super(DiceLoss, self).__init__()self.smooth = validator.check_positive_float(smooth, "smooth")self.reshape = P.Reshape()def construct(self, logits, label):# 进行维度校验,维度必须相等。(输入必须是tensor)_check_shape(logits.shape, label.shape)# 求交集,和dice系数一样的方式intersection = self.reduce_sum(self.mul(logits.view(-1), label.view(-1)))# 求并集,和dice系数一样的方式unionset = self.reduce_sum(self.mul(logits.view(-1), logits.view(-1))) + \self.reduce_sum(self.mul(label.view(-1), label.view(-1)))# 利用公式进行计算single_dice_coeff = (2 * intersection) / (unionset + self.smooth)dice_loss = 1 - single_dice_coeff / label.shape[0]return dice_loss.mean()@constexpr
def _check_shape(logits_shape, label_shape):validator.check('logits_shape', logits_shape, 'label_shape', label_shape)

使用方法如下:

import numpy as np
import mindspore.common.dtype as mstype
import mindspore.nn as nn
from mindspore import Tensorloss = nn.DiceLoss(smooth=1e-5)
y_pred = Tensor(np.array([[0.2, 0.5], [0.3, 0.1], [0.9, 0.6]]), mstype.float32)
y = Tensor(np.array([[0, 1], [1, 0], [0, 1]]), mstype.float32)
output = loss(y_pred, y)
print(output)[0.7953220862819745]

MindSpore 多分类 MultiClassDiceLoss 代码实现

在MindSpore中支持在语义分割中有多种损失函数可以选择,不过最常用的还是用交叉熵来做损失函数。

class MultiClassDiceLoss(_Loss):def __init__(self, weights=None, ignore_indiex=None, activation=A.Softmax(axis=1)):super(MultiClassDiceLoss, self).__init__()# 利用Dice系数self.binarydiceloss = DiceLoss(smooth=1e-5)# 权重是一个Tensor,应该和分类数的维度一样:Tensor of shape `[num_classes, dim]`。self.weights = weights if weights is None else validator.check_value_type("weights", weights, [Tensor])# 要忽略的类别序号self.ignore_indiex = ignore_indiex if ignore_indiex is None else \validator.check_value_type("ignore_indiex", ignore_indiex, [int])# 使用激活函数self.activation = A.get_activation(activation) if isinstance(activation, str) else activationif activation is not None and not isinstance(self.activation, Cell):raise TypeError("The activation must be str or Cell, but got {}.".format(activation))self.activation_flag = self.activation is not Noneself.reshape = P.Reshape()def construct(self, logits, label):# 进行维度校验,维度必须相等。(输入必须是tensor)_check_shape(logits.shape, label.shape)# 先定义一个loss,初始值为0total_loss = 0# 如果使用激活函数if self.activation_flag:logits = self.activation(logits)# 按照标签的维度的第一个数进行遍历for i in range(label.shape[1]):if i != self.ignore_indiex:dice_loss = self.binarydiceloss(logits[:, i], label[:, i])if self.weights is not None:_check_weights(self.weights, label)dice_loss *= self.weights[i]total_loss += dice_lossreturn total_loss/label.shape[1]

使用方法如下:

import numpy as np
import mindspore.common.dtype as mstype
import mindspore.nn as nn
from mindspore import Tensorloss = nn.MultiClassDiceLoss(weights=None, ignore_indiex=None, activation="softmax")
y_pred = Tensor(np.array([[0.2, 0.5], [0.3, 0.1], [0.9, 0.6]]), mstype.float32)
y = Tensor(np.array([[0, 1], [1, 0], [0, 1]]), mstype.float32)
output = loss(y_pred, y)
print(output)[0.7761003]

Dice Loss 存在的问题

训练误差曲线非常混乱,很难看出关于收敛的信息。尽管可以检查在验证集上的误差来避开此问题。

基于MindSpore高效完成图像分割,实现Dice!相关推荐

  1. 技术干货 | 基于 MindSpore 实现图像分割之豪斯多夫距离

    今天带来的内容是Hausdorff distance 豪斯多夫距离的原理介绍及MindSpore的实现代码. 当我们评价图像分割的质量和模型表现时,经常会用到各类表面距离的计算.比如: · Mean ...

  2. 基于MindSpore框架的室内场景图像分割方法研究

    基于MindSpore框架的室内场景图像分割方法研究 概述 本文以华为最新国产深度学习框架Mindspore为基础,研究室内场景语义分割方法.本文基于注意力机制改进U-Net网络,并选取VGG16与R ...

  3. 百度提出PADDLESEG:一个高效的图像分割开发工具

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 小白导读 论文是学术研究的精华和未来发展的明灯.小白决心每天为大家 ...

  4. 【深度学习】基于MindSpore和pytorch的Softmax回归及前馈神经网络

    1 实验内容简介 1.1 实验目的 (1)熟练掌握tensor相关各种操作: (2)掌握广义线性回归模型(logistic模型.sofmax模型).前馈神经网络模型的原理: (3)熟练掌握基于mind ...

  5. 基于MindSpore复现Deeplabv3—语义分割

    基于MindSpore复现Deeplabv3-语义分割 实验介绍 本实验主要介绍使用MindSpore深度学习框架在PASCAL VOC2012数据集上训练Deeplabv3网络模型.本实验使用了Mi ...

  6. 基于深度学习的图像分割

    摘要 遥感图像分割是利用遥感技术获取的高分辨率图像进行像素级别的分类,将图像中的不同物体或不同地物提取出来的过程.这个过程对于遥感应用具有重要意义,因为它能够提取出地物和地表特征,如河流.道路.建筑. ...

  7. 【图像分割】走进基于深度学习的图像分割

    深度学习中的图像分割 图像分割就是把图像分成若干个特定的.具有独特性质的区域并提出感兴趣目标的技术和过程.它是由图像处理到图像分析的关键步骤.现有的图像分割方法主要分以下几类:基于阈值的分割方法.基于 ...

  8. resnet50网络结构_Resnet50详解与实践(基于mindspore)

    1. 简述 Resnet是残差网络(Residual Network)的缩写,该系列网络广泛用于目标分类等领域以及作为计算机视觉任务主干经典神经网络的一部分,典型的网络有resnet50, resne ...

  9. 根据大小分割大文本_基于深度学习的图像分割在高德地图的实践

    一.前言 图像分割(Image Segmentation)是计算机视觉领域中的一项重要基础技术,是图像理解中的重要一环.图像分割是将数字图像细分为多个图像子区域的过程,通过简化或改变图像的表示形式,让 ...

最新文章

  1. 使用 AjaxManager 生成调用服务器端方法的 javascript 函数
  2. UOJ58 【WC2013】糖果公园
  3. (转)解决fasterxml中string字符串转对象json格式错误问题(无引号 单引号问题)...
  4. 入门demo---Mybatis学习笔记(三)
  5. docker容器之RabbitMQ
  6. Adaboost算法的学习笔记~
  7. Java动态代理实现(转载\整理)
  8. hosts文件修改完无效的解决办法
  9. 跨域cookie设置
  10. VNCTF2021 几个题解writeup
  11. PL/SQL 工具远程连接Oracle数据库方法,plsql免安装oracle客户端直接配置oci实战演示
  12. AS--›Gradle乐固加固和下载
  13. 安卓电视通过U盘安装第三方软件教程
  14. linux驱动开发:PWM驱动编写
  15. python做一个登录注册界面_Python 实现简单的登录注册界面
  16. 谷歌大脑新优化器VeLO火了!让AI自己调整超参数,自适应不同任务,83个任务训练加速比经典Adam更快!...
  17. 我那迷途知返的小羊-linux修复DNS解析问题
  18. 关闭华为的触摸屏+查看自己电脑主板型号顺便推荐了个全能检测工具+进入华为的bios看看
  19. java jtable 编辑_JTable可编辑
  20. 递归函数——头递归和尾递归

热门文章

  1. Protein Cell:肠道菌群及其代谢物在代谢性疾病中的作用
  2. Android系统开发之烧录开发板
  3. FinalShell连接windows虚拟机
  4. 变频器与PLC通讯的精简设计
  5. 戴尔计算机软件的安装,戴尔电脑如何安装系统
  6. Python 给视频添加水印源代码
  7. 超详细:VINS-Mono论文中文记录
  8. 吃个晚饭的时间,看明白三相交流感应电机驱动原理
  9. 几个网站站长用的到的网站分享
  10. delphi cookie发送php,phpwind 论坛发贴POST提交!cookie 设置,该如何解决