unet脑肿瘤分割_2D UNet3+ Pytorch实现 脑肿瘤分割

本文详细介绍了使用Pytorch实现2D UNet3+网络进行脑肿瘤分割的过程,包括数据预处理、环境配置、网络结构和关键代码。通过BraTs数据集,利用新增的样本作为测试集,解决数据不足导致的过拟合问题。文章提供了完整的预处理代码和网络结构,并分享了训练和测试的命令。
摘要由CSDN通过智能技术生成

一、网络介绍

论文下载地址及论文翻译与解读:玖零猴:UNet3+(UNet+++)论文翻译与详细解读​zhuanlan.zhihu.com

原代码链接:链接

二、BraTs数据预处理

本文用的训练集和验证集均来自BraTs2018的训练集(其中HGG:210个病人,LGG:75个病人)

但由于BraTs只公开训练集数据,没有测试集数据,如果在训练集中再拆一部分用来作测试集的话,那训练集便少了许多,训练数据如果过少,容易出现过拟合现象,即在训练集中表现好,而在测试集中表现差,此时的网络泛化能力变差了.为了解决数据少的问题,灵机一动的我想出了一个办法.

因为BraTs2019的训练集在BraTs2018的基础上增多了,其中HGG增加了49例,LGG增加了1例,那么我就把这些新增的作为我的测试集

下面我提供百度云盘给大家下载,这是原始数据

BraTs18数据集下载地址(不包含测试集,提供的验证集无GT)

链接:https://pan.baidu.com/s/1Ry41OVl9VLOMzhQQR9qXuA 提取码:qvmo

BraTs19数据集下载地址如下(不包含测试集,提供的验证集无GT)

链接: https://pan.baidu.com/s/1S5XGTdHkwFnagKS-5vWYBg 提取码: 2333

数据的预处理以及实现代码

把上面两年的数据下下来,然后我对数据的预处理方法是链接

完整的实现代码(jupyter notebook打开)https://github.com/Merofine/BraTS2Dpreprocessing​github.comGetTrainingSets.ipynb——>训练集和验证集

GetTestingSetsFrom2019.ipynb-—>测试集

代码执行完后,获得npy数据

链接:https://pan.baidu.com/s/1W3rcl9I-Y8DwWu5p4o--cw 密码:hfe7

三、运行环境的安装

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

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

四、核心代码

# -*- coding: utf-8 -*-

import torch

import torch.nn as nn

import torch.nn.functional as F

from layers import unetConv2

from init_weights import init_weights

'''

UNet 3+

'''

class UNet_3Plus(nn.Module):

def __init__(self, args):

super(UNet_3Plus, self).__init__()

self.args = args

in_channels = 4

n_classes = 3

feature_scale = 4

is_deconv = True

is_batchnorm = True

self.is_deconv = is_deconv

self.in_channels = in_channels

self.is_batchnorm = is_batchnorm

self.feature_scale = feature_scale

filters = [64, 128, 256, 512, 1024]

## -------------Encoder--------------

self.conv1 = unetConv2(self.in_channels, filters[0], self.is_batchnorm)

self.maxpool1 = nn.MaxPool2d(kernel_size=2)

self.conv2 = unetConv2(filters[0], filters[1], self.is_batchnorm)

self.maxpool2 = nn.MaxPool2d(kernel_size=2)

self.conv3 = unetConv2(filters[1], filters[2], self.is_batchnorm)

self.maxpool3 = nn.MaxPool2d(kernel_size=2)

self.conv4 = unetConv2(filters[2], filters[3], self.is_batchnorm)

self.maxpool4 = nn.MaxPool2d(kernel_size=2)

self.conv5 = unetConv2(filters[3], filters[4], self.is_batchnorm)

## -------------Decoder--------------

self.CatChannels = filters[0]

self.CatBlocks = 5

self.UpChannels = self.CatChannels * self.CatBlocks

'''stage 4d'''

# h1->320*320, hd4->40*40, Pooling 8 tim

以下是一个简单的UNet 3+的PyTorch实现,仅供参考: ```python import torch import torch.nn as nn import torch.nn.functional as F class DoubleConv(nn.Module): def __init__(self, in_channels, out_channels, mid_channels=None): super().__init__() if not mid_channels: mid_channels = out_channels self.double_conv = nn.Sequential( nn.Conv2d(in_channels, mid_channels, kernel_size=3, padding=1), nn.BatchNorm2d(mid_channels), nn.ReLU(inplace=True), nn.Conv2d(mid_channels, out_channels, kernel_size=3, padding=1), nn.BatchNorm2d(out_channels), nn.ReLU(inplace=True) ) def forward(self, x): return self.double_conv(x) class Down(nn.Module): def __init__(self, in_channels, out_channels): super().__init__() self.maxpool_conv = nn.Sequential( nn.MaxPool2d(2), DoubleConv(in_channels, out_channels) ) def forward(self, x): return self.maxpool_conv(x) class Up(nn.Module): def __init__(self, in_channels, out_channels, bilinear=True): super().__init__() if bilinear: self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True) else: self.up = nn.ConvTranspose2d(in_channels // 2, in_channels // 2, kernel_size=2, stride=2) self.conv = DoubleConv(in_channels, out_channels) def forward(self, x1, x2): x1 = self.up(x1) # input is CHW diffY = x2.size()[2] - x1.size()[2] diffX = x2.size()[3] - x1.size()[3] x1 = F.pad(x1, [diffX // 2, diffX - diffX // 2, diffY // 2, diffY - diffY // 2]) x = torch.cat([x2, x1], dim=1) return self.conv(x) class AttentionBlock(nn.Module): def __init__(self, F_g, F_l, F_int): super(AttentionBlock, self).__init__() self.W_g = nn.Sequential( nn.Conv2d(F_g, F_int, kernel_size=1, stride=1, padding=0, bias=True), nn.BatchNorm2d(F_int) ) self.W_x = nn.Sequential( nn.Conv2d(F_l, F_int, kernel_size=1, stride=1, padding=0, bias=True), nn.BatchNorm2d(F_int) ) self.psi = nn.Sequential( nn.Conv2d(F_int, 1, kernel_size=1, stride=1, padding=0, bias=True), nn.BatchNorm2d(1), nn.Sigmoid() ) self.relu = nn.ReLU(inplace=True) def forward(self, g, x): g1 = self.W_g(g) x1 = self.W_x(x) psi = self.relu(g1 + x1) psi = self.psi(psi) return x * psi class UNet3Plus(nn.Module): def __init__(self, in_channels=3, out_channels=1, bilinear=True): super().__init__() self.in_channels = in_channels self.out_channels = out_channels self.bilinear = bilinear self.down1 = Down(in_channels, 32) self.att1 = AttentionBlock(F_g=32, F_l=32, F_int=16) self.down2 = Down(32, 64) self.att2 = AttentionBlock(F_g=64, F_l=64, F_int=32) self.down3 = Down(64, 128) self.att3 = AttentionBlock(F_g=128, F_l=128, F_int=64) self.down4 = Down(128, 256) self.att4 = AttentionBlock(F_g=256, F_l=256, F_int=128) self.center = DoubleConv(256, 512) self.att5 = AttentionBlock(F_g=512, F_l=512, F_int=256) self.up4 = Up(512, 256, self.bilinear) self.att6 = AttentionBlock(F_g=256, F_l=256, F_int=128) self.up3 = Up(256, 128, self.bilinear) self.att7 = AttentionBlock(F_g=128, F_l=128, F_int=64) self.up2 = Up(128, 64, self.bilinear) self.att8 = AttentionBlock(F_g=64, F_l=64, F_int=32) self.up1 = Up(64, 32, self.bilinear) self.outc = nn.Conv2d(32, out_channels, kernel_size=1) def forward(self, x): x1 = self.down1(x) x2 = self.down2(x1) x3 = self.down3(x2) x4 = self.down4(x3) center = self.center(x4) center = self.att5(g=center, x=center) x4 = self.att4(g=center, x=x4) x3 = self.att3(g=x4, x=x3) x2 = self.att2(g=x3, x=x2) x1 = self.att1(g=x2, x=x1) x = self.up4(center, x4) x = self.att6(g=x, x=center) x = self.up3(x, x3) x = self.att7(g=x, x=x3) x = self.up2(x, x2) x = self.att8(g=x, x=x2) x = self.up1(x, x1) logits = self.outc(x) return logits ``` 在这个实现中,我们首先定义了一个双卷积块(DoubleConv)、下采样块(Down)和上采样块(Up)。然后定义了一个注意力块(AttentionBlock)来实现UNet 3+中的跨通道注意力机制。最后,我们将所有块组合在一起以定义UNet 3+网络。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值