热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

3DUNet脑胶质瘤分割BraTs+Pytorch实现

原论文地址:连接一、网络模型的分析和对比原始2D-Unet网络模型我的2D-Unet网络模型1、和原来的2D-Unet网络不同的是,我输入通道为4,我这里应该改为4个通道,对应四个

原论文地址: 连接

一、网络模型的分析和对比

原始2D-Unet网络模型

v2-cf0ead284f68d91a42cd3908cf793956_b.jpg

我的2D-Unet网络模型

1、和原来的2D-Unet网络不同的是,我输入通道为4,我这里应该改为4个通道,对应四个模态图像,而输出通道为3,我对应的是三个嵌套子区域标签(WT、TC、ET)

2、另外,最大不同的是我的3X3卷积后的图像尺寸与卷积前一致,所以不用像原来2D-Unet那样因为编码和解码的尺寸不一致,需要裁剪后再拼接.问题来了,为什么原来2D-Unet的卷积会导致卷积前后图尺寸发生改变,因为原来的卷积操作为 kernelsize = 3 ,stride =1 ,padding=0,此卷积为valid方式,这种卷积只能使得图的尺寸越卷越小.而我这里为 kernelsize = 3 ,stride =1 ,padding=1.根据公式可以得出卷积前后的特征图尺寸一致.这种卷积方式为same卷积.

[概念]卷积的三种模式:valid、same、full_程序猿的养生馆-CSDN博客

关于2D-Unet的讲解和Pytorch代码实现前面我也做了详细地讲解.

玖零猴:U-Net+与FCN的区别+医学表现+网络详解+创新 玖零猴:2D-UNet脑胶质瘤分割BraTs + Pytorch实现


原始3D-Unet网络模型

v2-b96c16ddee163ebfe2542cc13c074a17_b.jpg

1、和原始的2D-Unet对比,最显著的不同就是3D-Unet池化下采样共3次,所以这里一共有4个尺度,而原来2D-Unet有5个尺度

3、另外,需要注意的是在编码部分中每个尺度的两次卷积后特征图的通道数变化,很明显和2D-Unet不同.而解码部分却一样.

我的3D-Unet网络模型

1、原来3D-Unet输入通道为3,我这里应该改为4个通道,对应四个模态图像,而输出通道一样都为3,我对应的是三个嵌套子区域标签(WT、TC、ET).这里根据自己的需求设置自己网络的输入和输出通道.

2、原来3D-Unet和原来2D-Unet一样都采用了valid卷积,为了保证网络的输入输出分辨率一致,因此我的2D-Unet和3D-Unet都采用same卷积,所以就不用裁剪了,同时可以保证网络的输入输出分辨率一致

其余都是和原始3D-Unet一样的,为了更加好看,我把网络标注清晰点,如下图

v2-31891a71999bfe4a119c599000461936_b.jpg

二、预处理与数据的获取

玖零猴:(3D网络)医学三维数据且又多模态多标签该如何预处理

三、环境的配置

1、系统环境 WIN10 + CUDA 92 + CUDNN7 + ANACONDA

2、ANACONDA指令快速配置环境,先下载下面文件

https:// download.csdn.net/downl oad/weixin_40519315/12394604 

v2-1e6ab2b0230d510b9f6685399508900f_b.jpg

四、工程代码下载

from torch import nn
from torch import catclass pub(nn.Module):def __init__(self, in_channels, out_channels, batch_norm=True):super(pub, self).__init__()inter_channels = out_channels if in_channels > out_channels else out_channels//2layers = [nn.Conv3d(in_channels, inter_channels, 3, stride=1, padding=1),nn.ReLU(True),nn.Conv3d(inter_channels, out_channels, 3, stride=1, padding=1),nn.ReLU(True)]if batch_norm:layers.insert(1, nn.BatchNorm3d(inter_channels))layers.insert(len(layers)-1, nn.BatchNorm3d(out_channels))self.pub = nn.Sequential(*layers)def forward(self, x):return self.pub(x)class unet3dEncoder(nn.Module):def __init__(self, in_channels, out_channels, batch_norm=True):super(unet3dEncoder, self).__init__()self.pub = pub(in_channels, out_channels, batch_norm)self.pool = nn.MaxPool3d(2, stride=2)def forward(self, x):x = self.pub(x)return x,self.pool(x)class unet3dUp(nn.Module):def __init__(self, in_channels, out_channels, batch_norm=True, sample=True):super(unet3dUp, self).__init__()self.pub = pub(in_channels//2+in_channels, out_channels, batch_norm)if sample:self.sample = nn.Upsample(scale_factor=2, mode='nearest')else:self.sample = nn.ConvTranspose3d(in_channels, in_channels, 2, stride=2)def forward(self, x, x1):x = self.sample(x)#c1 = (x1.size(2) - x.size(2)) // 2#c2 = (x1.size(3) - x.size(3)) // 2#x1 = x1[:, :, c1:-c1, c2:-c2, c2:-c2]x = cat((x, x1), dim=1)x = self.pub(x)return xclass unet3d(nn.Module):def __init__(self, args):super(unet3d, self).__init__()init_channels = 4class_nums = 3batch_norm = Truesample = Trueself.en1 = unet3dEncoder(init_channels, 64, batch_norm)self.en2 = unet3dEncoder(64, 128, batch_norm)self.en3 = unet3dEncoder(128, 256, batch_norm)self.en4 = unet3dEncoder(256, 512, batch_norm)self.up3 = unet3dUp(512, 256, batch_norm, sample)self.up2 = unet3dUp(256, 128, batch_norm, sample)self.up1 = unet3dUp(128, 64, batch_norm, sample)self.con_last = nn.Conv3d(64, class_nums, 1)#self.sigmoid = nn.Sigmoid()def forward(self, x):x1,x = self.en1(x)x2,x= self.en2(x)x3,x= self.en3(x)x4,_ = self.en4(x)x = self.up3(x4, x3)x = self.up2(x, x2)x = self.up1(x, x1)out = self.con_last(x)return outdef _initialize_weights(self):for m in self.modules():if isinstance(m, nn.Conv3d):nn.init.kaiming_uniform(m.weight.data)if m.bias is not None:m.bias.data.zero_()elif isinstance(m, nn.BatchNorm3d):m.weight.data.fill_(1)m.bias.data.zero_()

完整代码

链接:百度网盘 请输入提取码

提取码:c27k

五、训练

python train.py --arch=“unet3d” --dataset=“Jiu0Monkey”

六、测试

python test.py --name="jiu0Monkey_unet3d_woDS"

七、和2D U-Net对比

在此之前,本专栏中的2D网络预测的时候,是把所有的切片预测完指标再求平均值,这样测的值极容易收到一些差的切片而影响整体的指标.所以以后的2D网络预测都采用下面方式进行计算指标,即把所有预测的切片拼接回3D,然后对3D数据整体进行计算指标.这样计算的值会偏高点.不只是2D网络这样,3D网络也是如此,把所有分块拼接后再对整体进行指标的计算.这样统一之后,我们就可以将2D和3D网络进行对比了.此外,代码预测生成的数据都是NII格式的,可以通过ITK-SNAP软件查看三维的分割效果,如果想看2D切片的分割效果,可以用该软件导出即可.

2D网络新的预测代码(test.py)如下

https://download.csdn.net/download/weixin_40519315/12466322​download.csdn.net

通过实验得出,2D U-Net、3D U-Net分割指标表如下:

分割效果对比图如下,可见3D网络提高了肿瘤周围的预测,少了很多小渣点.



推荐阅读
  • Python实现变声器功能(萝莉音御姐音)的方法及步骤
    本文介绍了使用Python实现变声器功能(萝莉音御姐音)的方法及步骤。首先登录百度AL开发平台,选择语音合成,创建应用并填写应用信息,获取Appid、API Key和Secret Key。然后安装pythonsdk,可以通过pip install baidu-aip或python setup.py install进行安装。最后,书写代码实现变声器功能,使用AipSpeech库进行语音合成,可以设置音量等参数。 ... [详细]
  • vue使用
    关键词: ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • 十大经典排序算法动图演示+Python实现
    本文介绍了十大经典排序算法的原理、演示和Python实现。排序算法分为内部排序和外部排序,常见的内部排序算法有插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。文章还解释了时间复杂度和稳定性的概念,并提供了相关的名词解释。 ... [详细]
  • 本文整理了315道Python基础题目及答案,帮助读者检验学习成果。文章介绍了学习Python的途径、Python与其他编程语言的对比、解释型和编译型编程语言的简述、Python解释器的种类和特点、位和字节的关系、以及至少5个PEP8规范。对于想要检验自己学习成果的读者,这些题目将是一个不错的选择。请注意,答案在视频中,本文不提供答案。 ... [详细]
  • Python脚本编写创建输出数据库并添加模型和场数据的方法
    本文介绍了使用Python脚本编写创建输出数据库并添加模型数据和场数据的方法。首先导入相应模块,然后创建输出数据库并添加材料属性、截面、部件实例、分析步和帧、节点和单元等对象。接着向输出数据库中添加场数据和历程数据,本例中只添加了节点位移。最后保存数据库文件并关闭文件。文章还提供了部分代码和Abaqus操作步骤。另外,作者还建立了关于Abaqus的学习交流群,欢迎加入并提问。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 无损压缩算法专题——LZSS算法实现
    本文介绍了基于无损压缩算法专题的LZSS算法实现。通过Python和C两种语言的代码实现了对任意文件的压缩和解压功能。详细介绍了LZSS算法的原理和实现过程,以及代码中的注释。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
author-avatar
鬎瀰_418
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有