使用【PaddleSeg3D】搭建项目对肝脏进行3D分割
!git clone https://github.com/PaddleCV-SIG/PaddleSeg3D.git
1. PaddleSeg3D
从这个工具的github地址https://github.com/PaddleCV-SIG/PaddleSeg3D.git ,可以看出是飞桨的兴趣小组(PPSIG,飞桨特殊兴趣小组)的CV小组开发和维护的。如果对飞桨的分割套件PaddleSeg熟悉的话,知道PaddleSeg目前支持都是2D分割,没有3D分割这方面的工具,不过有很多用户或者行业有3D分割的需求,特别医疗行业的用户。现在飞桨兴趣小组开发了PaddleSeg3D的3D分割工具,后面估计会整合到PaddleSeg分割套件中。
现在尝试用PaddleSeg3D这个工具搭建3D分割项目,分割自己的医疗数据。
PaddleSeg3D跟PaddleSeg很像的,用起来也很方便,但是就是对自己的医疗数据预处理没有提供太多的脚本,例如PaddleSeg3D中快速运行的教程中,是对新冠胸部CT的数据集进行肺部的分割,里面的预处理都是根据肺部“打量的”,还不支持nii后缀名的医疗格式,所以如果你要分割自己的数据,器官不是肺部的话,那需要自己写脚本。不过除自己需要对数据进行预处理外,后面的训练,就很方便,PaddleSeg3D提供一行代码就可以训练、验证、评估。
希望PaddleSeg3D可以尽快加入PaddleSeg开发套件中。
# 安装依赖
!pip install -r ./PaddleSeg3D/requirements.txt
#解压数据
!unzip -o /home/aistudio/data/data129670/livers.zip -d /home/aistudio/PaddleSeg3D
2. 数据集介绍
这个项目主要分割肝脏和肿瘤,数据的模式是CT,属于薄层数据(体素约为0.7x0.7x0.7),在Z轴上可以达到500多层。通过ITK-SNAP中看到显示红色的是肝脏,显示绿色的是肿瘤。这个数据集一共有28例
#记得运行这行
%cd /home/aistudio/PaddleSeg3D/
/home/aistudio/PaddleSeg3D
#导入常用的库
import nibabel as nib
import SimpleITK as sitk
import matplotlib.pyplot as plt
import numpy as np
import os
from tqdm import tqdm
3. 对数据进行预处理
PaddleSeg3D的快速运行教程是分割胸部CT数据的肺部。对数据处理如下:
用nibabel读取医疗数据后,
if "nii.gz" in filename:f_np = nib.load(f).get_fdata(dtype=np.float32)
对CT值裁剪,然后对数据的Size 重采样到[128,128,128],再转换成numpy数据。
preprocess=[HUNorm,functools.partial(resample, new_shape=[128, 128, 128], order=1)],
HUNorm默认是 HU_min=-1000, HU_max=600
#这个值范围类似肺窗
如果是分割自己的数据(不是分割肺部)是不能用它提供的脚本,假如你的医疗数据是nii的话,直接不支持读取(脚本没有把nii的格式写进去),而且使用nibabel来读取nii的话,图像会旋转90度,对CT值裁剪也是针对肺部的。因此最好自己写脚本预处理自己的数据。
因此对这个项目的肝脏数据,自己写脚本进行如下的预处理:
- 用SimpleITK读取.nii医疗数据,而且用SimpleITK不会出现用nibabel读取后会旋转90度
- 对数据统一方向,避免SimpleITK读取后,图像上下翻转(统一方向后,用nibabel还是会旋转90度)
- 对数据的CT值根据窗宽窗位进行裁剪
- 对数据的Size 进行重采样到[128,128,128]
- 转换成numpy(.npy)文件
"""
发现nibabel读取会旋转90度,SImpleITK会上下翻转,为了解决这个问题,需要对数据进行方向统一.
不过统不统一方向,nibabel都会旋转90度,而PaddleSeg3D也是刚好用这库处理医学数据转换成numpy,
所以转换numpy时,我不用这分割套件自带的脚本,自己用SImpleITK写一个。
"""plt.figure(figsize=(10,5))f_nib = nib.load("./livers/data/volume-2.nii").get_fdata(dtype=np.float32)
print(f"nibabel读取文件转换numpy后形状为x,y,z{f_nib.shape}")f_sitk= sitk.GetArrayFromImage(sitk.ReadImage('./livers/data/volume-2.nii'))
print(f"SimpleITK读取文件转换numpy后形状为z,y,x{f_sitk.shape}")plt.subplot(1,2,1),plt.imshow(f_nib[:,:,60],'gray'),plt.title("nibabel")
plt.subplot(1,2,2),plt.imshow(f_sitk[60,:,:],'gray'),plt.title("SimpleITK")
plt.show()
nibabel读取文件转换numpy后形状为x,y,z(512, 512, 158)
SimpleITK读取文件转换numpy后形状为z,y,x(158, 512, 512)
"""
读取nii文件后,设置统一的Direction,
"""
def reorient_image(image):"""Reorients an image to standard radiology view."""dir = np.array(image.GetDirection()).reshape(len(image.GetSize()), -1)ind = np.argmax(np.abs(dir), axis=0)new_size = np.array(image.GetSize())[ind]new_spacing = np.array(image.GetSpacing())[ind]new_extent = new_size * new_spacingnew_dir = dir[:, ind]flip = np.diag(new_dir) < 0flip_diag = flip * -1flip_diag[flip_diag == 0] = 1flip_mat = np.diag(flip_diag)new_origin = np.array(image.GetOrigin()) + np.matmul(new_dir, (new_extent * flip))new_dir = np.matmul(new_dir, flip_mat)resample = sitk.ResampleImageFilter()resample.SetOutputSpacing(new_spacing.tolist())resample.SetSize(new_size.tolist())resample.SetOutputDirection(new_dir.flatten().tolist())resample.SetOutputOrigin(new_origin.tolist())resample.SetTransform(sitk.Transform())resample.SetDefaultPixelValue(image.GetPixelIDValue())resample.SetInterpolator(sitk.sitkNearestNeighbor)return resample.Execute(image) for f in tqdm(os.listdir("./livers/data")) :d_path = os.path.join('./livers/data',f)seg_path = os.path.join('./livers/mask',f.replace("volume","segmentation"))d_sitkimg = sitk.ReadImage(d_path)d_sitkimg = reorient_image(d_sitkimg)seg_sitkimg = sitk.ReadImage(seg_path)seg_sitkimg = reorient_image(seg_sitkimg)sitk.WriteImage(d_sitkimg,d_path)sitk.WriteImage(seg_sitkimg,seg_path)
#统一方向后,再用SimpleITK读取,不再是上下翻转了,显示正常了
plt.figure(figsize=(10,5))
img= sitk.GetArrayFromImage(sitk.ReadImage('./livers/data/volume-2.nii'))
seg= sitk.GetArrayFromImage(sitk.ReadImage('./livers/mask/segmentation-2.nii'))
plt.subplot(1,2,1),plt.imshow(img[60,:,:],'gray'),plt.title("origin")
plt.subplot(1,2,2),plt.imshow(seg[60,:,:],'gray'),plt.title("mask")
plt.show()
"""
对已经CT值裁剪和size重采样的数据转换成numpy并保存.npy文件
"""
from paddleseg3d.datasets.preprocess_utils import HUNorm, resampledataset_root = "livers/"
image_dir = os.path.join(dataset_root, "images") #images 不要改,存放转换后原始数据的npy文件
label_dir = os.path.join(dataset_root, "labels") #labels 不要改,存放转换后的标签npy文件
os.makedirs(image_dir, exist_ok=True)
os.makedirs(label_dir, exist_ok=True)
ww = 350
wc = 80for f in tqdm(os.listdir("./livers/data")) :d_path = os.path.join('./livers/data',f)seg_path = os.path.join('./livers/mask',f.replace("volume","segmentation"))d_img = sitk.GetArrayFromImage(sitk.ReadImage(d_path))d_img = HUNorm(d_img,HU_min=int(wc-int(ww/2)), HU_max=int(wc+int(ww/2)))d_img = resample(d_img,new_shape=[128, 128, 128], order=1).astype("float32")#new_shape=[z,y,x]seg_img = sitk.GetArrayFromImage(sitk.ReadImage(seg_path))seg_img = resample(seg_img,new_shape=[128, 128, 128], order=0).astype("int64")np.save(os.path.join(image_dir,f.split('.')[0]), d_img)np.save(os.path.join(label_dir,f.split('.')[0].replace("volume","segmentation")), seg_img)
# 划分数据集,训练集和测试集为8:2
import random
random.seed(1000)
path_origin = './livers/images/'
files = list(filter(lambda x: x.endswith('.npy'), os.listdir(path_origin)))
random.shuffle(files)
rate = int(len(files) * 0.8)#训练集和测试集8:2
train_txt = open('./livers/train_list.txt','w')
val_txt = open('./livers/val_list.txt','w')
for i,f in enumerate(files):image_path = os.path.join('images', f)label_path = image_path.replace("images", "labels").replace('volume','segmentation')if i < rate:train_txt.write(image_path + ' ' + label_path+ '\n')else:val_txt.write(image_path + ' ' + label_path+ '\n')
train_txt.close()
val_txt.close()print('完成')
完成
"""
最后读取转换后的npy文件并展示,可见图像显示肝脏的窗宽窗位,形状大小也为128*128,数据都归一化到0到1之间
"""
data = np.load('livers/images/volume-0.npy')
print(data.shape)
print(np.max(data),np.min(data))#把数据归一化到0-1
img = data[60,:,:]
plt.imshow(img,'gray')
plt.show()
(128, 256, 256)
1.0 0.0
4. 设置训练配置文件
PaddleSeg3D通过配置yaml文件来设置训练参数的。
这次训练用到的yaml文件内容如下:
data_root: livers/ #随便设置,只要是一个路径即可,因为dataset_root用来绝对路径batch_size: 2
iters: 15000train_dataset:type: LungCoronavirus #不用管dataset_root: /home/aistudio/PaddleSeg3D/livers/ #这里用绝对路径省事好似result_dir: None #目前好似没啥用transforms:- type: RandomResizedCrop3D #随机缩放裁剪size: 128scale: [0.8, 1.4]- type: RandomRotation3D #随机旋转degrees: 60 #旋转角度[-60 ,+60]度- type: RandomFlip3D # 随机翻转mode: train #训练模式num_classes: 3 #分割类别数(背景,肝脏,肿瘤)val_dataset:type: LungCoronavirusdataset_root: /home/aistudio/PaddleSeg3D/livers/result_dir: Nonenum_classes: 3transforms: []mode: valoptimizer: #优化器设置type: sgdmomentum: 0.9weight_decay: 1.0e-4lr_scheduler: #学习率设置type: PolynomialDecaydecay_steps: 15000learning_rate: 0.0003end_lr: 0power: 0.9loss: #损失函数,交叉熵和dice结合一起用types:- type: MixedLosslosses:- type: CrossEntropyLossweight: Null- type: DiceLosscoef: [1, 1] #设置交叉熵和dice的权重coef: [1]model:type: VNet #目前只有Unet3d和Vnet两个3D分割网络选择elu: Falsein_channels: 1num_classes: 3pretrained: null
5. VNet
VNet是医疗3D分割网络,结构上也是采用U型结构。比起Unet3D,层内采用残差结构(第一个红框)。用卷积层替代池化层(第二个红框)。论文中也强调了Dice损失函数的作用
#打印vnet的网络结构!python paddleseg3d/models/vnet.py
/home/aistudio/PaddleSeg3D/paddleseg3d/models/../../paddleseg3d/cvlibs/manager.py:118: UserWarning: VNet exists already! It is now updated to <class '__main__.VNet'> !!!component_name, component))
W0228 19:18:39.534801 27494 device_context.cc:447] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 10.1, Runtime API Version: 10.1
W0228 19:18:39.538172 27494 device_context.cc:465] device: 0, cuDNN Version: 7.6.
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/nn/layer/norm.py:653: UserWarning: When training, we now always track global mean and variance."When training, we now always track global mean and variance.")
out Tensor(shape=[1], dtype=float32, place=CUDAPlace(0), stop_gradient=False,[-0.45796004]) Tensor(shape=[1], dtype=float32, place=CUDAPlace(0), stop_gradient=True,[0.49996352])
-----------------------------------------------------------------------------------------------------------Layer (type) Input Shape Output Shape Param #
===========================================================================================================Conv3D-1 [[1, 1, 128, 256, 256]] [1, 16, 128, 256, 256] 2,016 BatchNorm3D-1 [[1, 16, 128, 256, 256]] [1, 16, 128, 256, 256] 64 PReLU-1 [[1, 16, 128, 256, 256]] [1, 16, 128, 256, 256] 16
InputTransition-1 [[1, 1, 128, 256, 256]] [1, 16, 128, 256, 256] 0 Conv3D-2 [[1, 16, 128, 256, 256]] [1, 32, 64, 128, 128] 4,128 BatchNorm3D-2 [[1, 32, 64, 128, 128]] [1, 32, 64, 128, 128] 128 PReLU-2 [[1, 32, 64, 128, 128]] [1, 32, 64, 128, 128] 32 Conv3D-3 [[1, 32, 64, 128, 128]] [1, 32, 64, 128, 128] 128,032 BatchNorm3D-3 [[1, 32, 64, 128, 128]] [1, 32, 64, 128, 128] 128 PReLU-4 [[1, 32, 64, 128, 128]] [1, 32, 64, 128, 128] 32 LUConv-1 [[1, 32, 64, 128, 128]] [1, 32, 64, 128, 128] 0 PReLU-3 [[1, 32, 64, 128, 128]] [1, 32, 64, 128, 128] 32 DownTransition-1 [[1, 16, 128, 256, 256]] [1, 32, 64, 128, 128] 0 Conv3D-4 [[1, 32, 64, 128, 128]] [1, 64, 32, 64, 64] 16,448 BatchNorm3D-4 [[1, 64, 32, 64, 64]] [1, 64, 32, 64, 64] 256 PReLU-5 [[1, 64, 32, 64, 64]] [1, 64, 32, 64, 64] 64 Conv3D-5 [[1, 64, 32, 64, 64]] [1, 64, 32, 64, 64] 512,064 BatchNorm3D-5 [[1, 64, 32, 64, 64]] [1, 64, 32, 64, 64] 256 PReLU-7 [[1, 64, 32, 64, 64]] [1, 64, 32, 64, 64] 64 LUConv-2 [[1, 64, 32, 64, 64]] [1, 64, 32, 64, 64] 0 Conv3D-6 [[1, 64, 32, 64, 64]] [1, 64, 32, 64, 64] 512,064 BatchNorm3D-6 [[1, 64, 32, 64, 64]] [1, 64, 32, 64, 64] 256 PReLU-8 [[1, 64, 32, 64, 64]] [1, 64, 32, 64, 64] 64 LUConv-3 [[1, 64, 32, 64, 64]] [1, 64, 32, 64, 64] 0 PReLU-6 [[1, 64, 32, 64, 64]] [1, 64, 32, 64, 64] 64 DownTransition-2 [[1, 32, 64, 128, 128]] [1, 64, 32, 64, 64] 0 Conv3D-7 [[1, 64, 32, 64, 64]] [1, 128, 16, 32, 32] 65,664 BatchNorm3D-7 [[1, 128, 16, 32, 32]] [1, 128, 16, 32, 32] 512 PReLU-9 [[1, 128, 16, 32, 32]] [1, 128, 16, 32, 32] 128 Dropout3D-3 [[1, 128, 16, 32, 32]] [1, 128, 16, 32, 32] 0 Conv3D-8 [[1, 128, 16, 32, 32]] [1, 128, 16, 32, 32] 2,048,128 BatchNorm3D-8 [[1, 128, 16, 32, 32]] [1, 128, 16, 32, 32] 512 PReLU-11 [[1, 128, 16, 32, 32]] [1, 128, 16, 32, 32] 128 LUConv-4 [[1, 128, 16, 32, 32]] [1, 128, 16, 32, 32] 0 Conv3D-9 [[1, 128, 16, 32, 32]] [1, 128, 16, 32, 32] 2,048,128 BatchNorm3D-9 [[1, 128, 16, 32, 32]] [1, 128, 16, 32, 32] 512 PReLU-12 [[1, 128, 16, 32, 32]] [1, 128, 16, 32, 32] 128 LUConv-5 [[1, 128, 16, 32, 32]] [1, 128, 16, 32, 32] 0 Conv3D-10 [[1, 128, 16, 32, 32]] [1, 128, 16, 32, 32] 2,048,128 BatchNorm3D-10 [[1, 128, 16, 32, 32]] [1, 128, 16, 32, 32] 512 PReLU-13 [[1, 128, 16, 32, 32]] [1, 128, 16, 32, 32] 128 LUConv-6 [[1, 128, 16, 32, 32]] [1, 128, 16, 32, 32] 0 PReLU-10 [[1, 128, 16, 32, 32]] [1, 128, 16, 32, 32] 128 DownTransition-3 [[1, 64, 32, 64, 64]] [1, 128, 16, 32, 32] 0 Conv3D-11 [[1, 128, 16, 32, 32]] [1, 256, 8, 16, 16] 262,400 BatchNorm3D-11 [[1, 256, 8, 16, 16]] [1, 256, 8, 16, 16] 1,024 PReLU-14 [[1, 256, 8, 16, 16]] [1, 256, 8, 16, 16] 256 Dropout3D-4 [[1, 256, 8, 16, 16]] [1, 256, 8, 16, 16] 0 Conv3D-12 [[1, 256, 8, 16, 16]] [1, 256, 8, 16, 16] 8,192,256 BatchNorm3D-12 [[1, 256, 8, 16, 16]] [1, 256, 8, 16, 16] 1,024 PReLU-16 [[1, 256, 8, 16, 16]] [1, 256, 8, 16, 16] 256 LUConv-7 [[1, 256, 8, 16, 16]] [1, 256, 8, 16, 16] 0 Conv3D-13 [[1, 256, 8, 16, 16]] [1, 256, 8, 16, 16] 8,192,256 BatchNorm3D-13 [[1, 256, 8, 16, 16]] [1, 256, 8, 16, 16] 1,024 PReLU-17 [[1, 256, 8, 16, 16]] [1, 256, 8, 16, 16] 256 LUConv-8 [[1, 256, 8, 16, 16]] [1, 256, 8, 16, 16] 0 PReLU-15 [[1, 256, 8, 16, 16]] [1, 256, 8, 16, 16] 256 DownTransition-4 [[1, 128, 16, 32, 32]] [1, 256, 8, 16, 16] 0 Dropout3D-5 [[1, 256, 8, 16, 16]] [1, 256, 8, 16, 16] 0 Dropout3D-6 [[1, 128, 16, 32, 32]] [1, 128, 16, 32, 32] 0
Conv3DTranspose-1 [[1, 256, 8, 16, 16]] [1, 128, 16, 32, 32] 262,272 BatchNorm3D-14 [[1, 128, 16, 32, 32]] [1, 128, 16, 32, 32] 512 PReLU-18 [[1, 128, 16, 32, 32]] [1, 128, 16, 32, 32] 128 Conv3D-14 [[1, 256, 16, 32, 32]] [1, 256, 16, 32, 32] 8,192,256 BatchNorm3D-15 [[1, 256, 16, 32, 32]] [1, 256, 16, 32, 32] 1,024 PReLU-20 [[1, 256, 16, 32, 32]] [1, 256, 16, 32, 32] 256 LUConv-9 [[1, 256, 16, 32, 32]] [1, 256, 16, 32, 32] 0 Conv3D-15 [[1, 256, 16, 32, 32]] [1, 256, 16, 32, 32] 8,192,256 BatchNorm3D-16 [[1, 256, 16, 32, 32]] [1, 256, 16, 32, 32] 1,024 PReLU-21 [[1, 256, 16, 32, 32]] [1, 256, 16, 32, 32] 256 LUConv-10 [[1, 256, 16, 32, 32]] [1, 256, 16, 32, 32] 0 PReLU-19 [[1, 256, 16, 32, 32]] [1, 256, 16, 32, 32] 256 UpTransition-1 [[1, 256, 8, 16, 16], [1, 128, 16, 32, 32]] [1, 256, 16, 32, 32] 0 Dropout3D-7 [[1, 256, 16, 32, 32]] [1, 256, 16, 32, 32] 0 Dropout3D-8 [[1, 64, 32, 64, 64]] [1, 64, 32, 64, 64] 0
Conv3DTranspose-2 [[1, 256, 16, 32, 32]] [1, 64, 32, 64, 64] 131,136 BatchNorm3D-17 [[1, 64, 32, 64, 64]] [1, 64, 32, 64, 64] 256 PReLU-22 [[1, 64, 32, 64, 64]] [1, 64, 32, 64, 64] 64 Conv3D-16 [[1, 128, 32, 64, 64]] [1, 128, 32, 64, 64] 2,048,128 BatchNorm3D-18 [[1, 128, 32, 64, 64]] [1, 128, 32, 64, 64] 512 PReLU-24 [[1, 128, 32, 64, 64]] [1, 128, 32, 64, 64] 128 LUConv-11 [[1, 128, 32, 64, 64]] [1, 128, 32, 64, 64] 0 Conv3D-17 [[1, 128, 32, 64, 64]] [1, 128, 32, 64, 64] 2,048,128 BatchNorm3D-19 [[1, 128, 32, 64, 64]] [1, 128, 32, 64, 64] 512 PReLU-25 [[1, 128, 32, 64, 64]] [1, 128, 32, 64, 64] 128 LUConv-12 [[1, 128, 32, 64, 64]] [1, 128, 32, 64, 64] 0 PReLU-23 [[1, 128, 32, 64, 64]] [1, 128, 32, 64, 64] 128 UpTransition-2 [[1, 256, 16, 32, 32], [1, 64, 32, 64, 64]] [1, 128, 32, 64, 64] 0
Conv3DTranspose-3 [[1, 128, 32, 64, 64]] [1, 32, 64, 128, 128] 32,800 BatchNorm3D-20 [[1, 32, 64, 128, 128]] [1, 32, 64, 128, 128] 128 PReLU-26 [[1, 32, 64, 128, 128]] [1, 32, 64, 128, 128] 32 Conv3D-18 [[1, 64, 64, 128, 128]] [1, 64, 64, 128, 128] 512,064 BatchNorm3D-21 [[1, 64, 64, 128, 128]] [1, 64, 64, 128, 128] 256 PReLU-28 [[1, 64, 64, 128, 128]] [1, 64, 64, 128, 128] 64 LUConv-13 [[1, 64, 64, 128, 128]] [1, 64, 64, 128, 128] 0 PReLU-27 [[1, 64, 64, 128, 128]] [1, 64, 64, 128, 128] 64 UpTransition-3 [[1, 128, 32, 64, 64], [1, 32, 64, 128, 128]] [1, 64, 64, 128, 128] 0
Conv3DTranspose-4 [[1, 64, 64, 128, 128]] [1, 16, 128, 256, 256] 8,208 BatchNorm3D-22 [[1, 16, 128, 256, 256]] [1, 16, 128, 256, 256] 64 PReLU-29 [[1, 16, 128, 256, 256]] [1, 16, 128, 256, 256] 16 Conv3D-19 [[1, 32, 128, 256, 256]] [1, 32, 128, 256, 256] 128,032 BatchNorm3D-23 [[1, 32, 128, 256, 256]] [1, 32, 128, 256, 256] 128 PReLU-31 [[1, 32, 128, 256, 256]] [1, 32, 128, 256, 256] 32 LUConv-14 [[1, 32, 128, 256, 256]] [1, 32, 128, 256, 256] 0 PReLU-30 [[1, 32, 128, 256, 256]] [1, 32, 128, 256, 256] 32 UpTransition-4 [[1, 64, 64, 128, 128], [1, 16, 128, 256, 256]] [1, 32, 128, 256, 256] 0 Conv3D-20 [[1, 32, 128, 256, 256]] [1, 2, 128, 256, 256] 8,002 BatchNorm3D-24 [[1, 2, 128, 256, 256]] [1, 2, 128, 256, 256] 8 PReLU-32 [[1, 2, 128, 256, 256]] [1, 2, 128, 256, 256] 2 Conv3D-21 [[1, 2, 128, 256, 256]] [1, 2, 128, 256, 256] 6
OutputTransition-1 [[1, 32, 128, 256, 256]] [1, 2, 128, 256, 256] 0
===========================================================================================================
Total params: 45,609,250
Trainable params: 45,598,618
Non-trainable params: 10,632
-----------------------------------------------------------------------------------------------------------
Input size (MB): 32.00
Forward/backward pass size (MB): 29372.00
Params size (MB): 173.99
Estimated Total Size (MB): 29577.99
-----------------------------------------------------------------------------------------------------------Vnet test is complete
6. 开始训练
一行代码开始训练
#开始训练
"""
!python3 train.py --config /home/aistudio/vnet_livers.yml #yaml文件路径--save_dir "/home/aistudio/output/livers" #模型保存路径--save_interval 500 #多少iters保存模型参数--log_iters 60 #多少iters打印一次信息--iters 15000 #训练多少iters--num_workers 6 --do_eval #是否训练期间验证模型性能--use_vdl #是否使用VisualDL可视化训练指标的走势
"""
!python3 train.py --config /home/aistudio/vnet_livers.yml \--save_dir "/home/aistudio/output/livers_vent128x128x128" \--save_interval 500 --log_iters 20 \--num_workers 6 --do_eval --use_vdl
7. 模型的验证和导出
2022-02-28 01:24:12 [INFO] [EVAL] #Images: 6, Dice: 0.6289, Loss: 0.634533
2022-02-28 01:24:12 [INFO] [EVAL] Class dice:
[0.9893 0.8679 0.0295]
用VNet跑了15000,验证集的效果如下:肝脏的dice为0.8679,肿瘤的dice为0.0295。对肿瘤这些小目标的检测效果比较差
#验证
"""
!python3 val.py --config /home/aistudio/vnet_livers.yml \ #yaml文件路径
--model_path /home/aistudio/output/livers/best_model/model.pdparams \ #最优模型的路径
--save_dir /home/aistudio/output/livers/best_model #验证后结果的保存路径
"""
!python3 val.py --config /home/aistudio/vnet_livers.yml \
--model_path /home/aistudio/output/livers/best_model/model.pdparams \
--save_dir /home/aistudio/output/livers/best_model
2022-02-28 01:24:04 [INFO]
---------------Config Information---------------
batch_size: 2
data_root: livers/
iters: 15000
loss:coef:- 1types:- coef:- 0.7- 0.3losses:- type: CrossEntropyLossweight: null- type: DiceLosstype: MixedLoss
lr_scheduler:decay_steps: 15000end_lr: 0learning_rate: 0.0003power: 0.9type: PolynomialDecay
model:elu: falsein_channels: 1num_classes: 3pretrained: nulltype: VNet
optimizer:momentum: 0.9type: sgdweight_decay: 0.0001
train_dataset:dataset_root: /home/aistudio/PaddleSeg3D/livers/mode: trainnum_classes: 3result_dir: Nonetransforms:- scale:- 0.8- 1.2size: 128type: RandomResizedCrop3D- degrees: 60type: RandomRotation3D- type: RandomFlip3Dtype: LungCoronavirus
val_dataset:dataset_root: /home/aistudio/PaddleSeg3D/livers/mode: valnum_classes: 3result_dir: Nonetransforms: []type: LungCoronavirus
------------------------------------------------
W0228 01:24:04.360675 32748 device_context.cc:447] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 10.1, Runtime API Version: 10.1
W0228 01:24:04.360720 32748 device_context.cc:465] device: 0, cuDNN Version: 7.6.
2022-02-28 01:24:08 [INFO] Loading pretrained model from /home/aistudio/output/livers/best_model/model.pdparams
2022-02-28 01:24:09 [INFO] There are 178/178 variables loaded into VNet.
2022-02-28 01:24:09 [INFO] Loaded trained params of model successfully
2022-02-28 01:24:09 [INFO] Start evaluating (total_samples: 6, total_iters: 6)...
2022-02-28 01:24:10 [INFO] [EVAL] Sucessfully save iter 0 pred and label.
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/fluid/dygraph/math_op_patch.py:253: UserWarning: The dtype of left and right variables are not the same, left dtype is paddle.float32, but right dtype is paddle.bool, the right dtype will convert to paddle.float32format(lhs_dtype, rhs_dtype, lhs_dtype))
1/6 [====>.........................] - ETA: 3s - batch_cost: 0.6990 - reader cost: 0.20632022-02-28 01:24:10 [INFO] [EVAL] Sucessfully save iter 1 pred and label.
2/6 [=========>....................] - ETA: 2s - batch_cost: 0.5683 - reader cost: 0.10322022-02-28 01:24:11 [INFO] [EVAL] Sucessfully save iter 2 pred and label.
3/6 [==============>...............] - ETA: 1s - batch_cost: 0.5247 - reader cost: 0.06882022-02-28 01:24:11 [INFO] [EVAL] Sucessfully save iter 3 pred and label.
4/6 [===================>..........] - ETA: 1s - batch_cost: 0.5027 - reader cost: 0.05172022-02-28 01:24:12 [INFO] [EVAL] Sucessfully save iter 4 pred and label.
5/6 [========================>.....] - ETA: 0s - batch_cost: 0.4912 - reader cost: 0.04132022-02-28 01:24:12 [INFO] [EVAL] Sucessfully save iter 5 pred and label.
6/6 [==============================] - 3s 483ms/step - batch_cost: 0.4830 - reader cost: 0.0345
2022-02-28 01:24:12 [INFO] [EVAL] #Images: 6, Dice: 0.6289, Loss: 0.634533
2022-02-28 01:24:12 [INFO] [EVAL] Class dice:
[0.9893 0.8679 0.0295]
#导出模型,方便推理和部署
"""
!python export.py --config /home/aistudio/vnet_livers.yml \ #yaml文件路径
--save_dir '/home/aistudio/save_model' \#导出模型的保存路径
--model_path /home/aistudio/output/livers/best_model/model.pdparams #需要导出的模型的路径
"""
!python export.py --config /home/aistudio/vnet_livers.yml \
--save_dir '/home/aistudio/save_model' \
--model_path /home/aistudio/output/livers/best_model/model.pdparams
#加载导出来的模型,对数据进行推理
!python deploy/python/infer.py --config /home/aistudio/save_model/deploy.yaml \
--image_path /home/aistudio/PaddleSeg3D/livers/images/volume-5.npy \
--save_dir '/home/aistudio'
#可视化推理后的结果
pre = np.load('/home/aistudio/volume-5.npy')
pre = np.squeeze(pre)
print(pre.shape)img = pre[60,:,:]
plt.imshow(img,'gray')
plt.show()
(256, 128, 128)
使用【PaddleSeg3D】搭建项目对肝脏进行3D分割相关推荐
- angular搭建项目步骤_建立健康的Angular项目应采取的步骤
angular搭建项目步骤 by Ashish Gaikwad 通过Ashish Gaikwad 建立健康的Angular项目应采取的步骤 (Steps you should take to buil ...
- 从零搭建一套结构光3D重建系统[理论+源码+实践]
01 背景介绍 图1 典型3D结构光系统 尽管结构光作为一种已经相当成熟,并且广泛应用的三维重建技术,不同于深度学习,依旧缺乏相关的课程,网上的开源资料寥寥无几,即使有,也是晦涩难懂,许多刚入门的研究 ...
- 新人上路-搭建项目-springweb-controller测试
新人上路-搭建项目-springweb-controller测试 maven和gradle配置 测试controller最基本的依赖 maven <!-- main framework begi ...
- vue项目结构php写哪里,Vue-cli搭建项目后目录结构的分析(图文)
这篇文章给大家介绍的文章内容是关于Vue-cli搭建项目后目录结构的分析,有很好的参考价值,希望可以帮助到有需要的朋友. 1.前言 Vue并不限制你的代码结构.但是,它规定了一些需要遵守的规则: 1. ...
- 支付宝支付 第三集:搭建项目及测试(含代码)
支付宝支付 第三集:搭建项目及测试(含代码) 一.资源 在搭建项目的时候,涉及到了SpringBoot的配置文件properties与yml文件,由于之前的项目使用的全部是properties类型,这 ...
- SpringBoot(一)_快速实战搭建项目
现在在学习springboot 相关的知识,感觉真的很好用,用idea 进行开发,根据慕课网和纯洁的微笑的课程.进行总结下. 使用idea创建springboot项目 (1)单击 File | New ...
- SpringCloud系列二:Restful 基础架构(搭建项目环境、创建 Dept 微服务、客户端调用微服务)...
声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:Restful 基础架构 2.具体内容 对于 Rest 基础架构实现处理是 SpringCloud 核心所在,其基本操 ...
- JavaEE企业级快速开发平台jeesite4的使用和快速搭建项目
场景 JeeSIte是一个JavaEE企业级快速开发平台,基于经典技术组合(SpringBoot.Apache Shiro .MyBatis.Beetl.Bootstrap)在线代码生成工具,支持Sp ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目
基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 转载于:https://github.com/Meowv/Blog 首先,默认咱们已经有了.net ...
最新文章
- android webview loadurl本地,Android WebView 使用loadUrl方法执行本地JavaScript
- “要么你去驾驭生命,要么生命驾驭你。你的心态决定谁是坐骑,谁是骑师。”...
- C++基本数据类型列表
- y查询硬盘内存CPU
- java编程创建警告_java – 无法阻止ant生成编译器Sun专有API警告
- 计算机组成原理硬件设计,计算机组成原理硬件设计报告..doc
- java 接口传数组_Restful接口传递数组参数
- rustdesk:远控工具说明
- 求解3维空间中点到直线的距离
- prosody之component
- Linux 文件格式转码工具
- PID控制器原理详解
- UE5——Actor生命周期——销毁
- 2月15日市场游资操作情况以及龙虎榜
- C语言 日期转时间戳
- ARM中的MOV指令
- Chainer Chemistry | 用于化学和生物学的深度学习库
- 别以为有文化就了不起
- ADDS:设置域间信任 SID Filter Quarantining
- Churchill资本集团和科睿唯安合并,将在纽交所上市