使用MONAI时,如何选择合适的Dataset加载数据,提升训练速度!

news2024/12/24 21:45:13

在深度学习中,MONAI(Medical Open Network for AI)是一个专注于医学图像分析的开源框架。它提供了一系列用于医学图像处理和深度学习的工具和函数,其中包括了Dataset函数。

Dataset函数是MONAI框架中的一个重要组件,它用于加载和管理医学图像数据集,并提供了数据增强、预处理和批处理等功能。

  • 数据加载:Dataset函数用于加载医学图像数据集,可以是常见的格式如NIfTI、DICOM等。
  • 数据预处理:Dataset函数可以对加载的医学图像数据进行预处理操作,如裁剪、缩放、平衡化等,以适应模型的需求。
  • 数据增强:Dataset函数可以实现数据增强操作,如旋转、平移、翻转、弹性变形等,以扩充数据集并提高模型的鲁棒性。
  • 批处理:Dataset函数支持批处理操作,可以将数据划分为固定大小的批次,并提供了多线程加载数据的功能,以加快模型训练过程。

这篇文章建议和之前的文章一起食用:
MONAI中,一定要学会的三种Dataset使用方法

文章目录

    • 常规 Dataset
    • CacheDataset
    • PersistentDataset
    • DecathlonDataset
    • MedNISTDataset
    • 不同Dataset之间的速度PK

常规 Dataset

一个典型的用法案例:
我们创建了一个Dataset对象,并传入数据集路径和预处理操作。最后,通过索引访问数据集中的样本。

  1. 导入相关库和模块:
import monai.data as data
from monai.transforms import Compose, AddChannel, ScaleIntensity
  1. 定义数据集路径和预处理操作:
data_dir = 'path/to/dataset'
transforms = Compose([AddChannel(), ScaleIntensity()])
# 其中`Compose`函数用于组合多个预处理操作,`AddChannel`函数用于在医学图像数据中添加通道维度,`ScaleIntensity`函数用于对图像数据进行强度归一化。
  1. 创建Dataset对象并加载数据:
dataset = data.Dataset(data_dir, transforms)
  1. 使用索引访问数据集中的样本:
sample = dataset[index]

在MONAI中,除了通用的Dataset函数外,还提供了一些专门用于医学图像的Dataset,下面列举几个常用Dataset

CacheDataset

提供了一种机制,可以预加载所有原始数据。然后并将non-random transforms(非随机变换)应用到数据并缓存起来,就不需要每个epoch都做这些transform。这样就大大提升了数据加载速度。而random transforms(随机变换)则需要实时做,因为会随着epoch的变化,transform的结果也会跟着变化,没办法提前做了缓存起来。

例如,如果变换是由以下操作组成的 Compose

transforms = Compose([
    LoadImaged(),
    EnsureChannelFirstd(),
    Spacingd(),
    Orientationd(),
    ScaleIntensityRanged(),
    RandCropByPosNegLabeld(),
    ToTensord()
])

transforms 在多个epoch的训练流程中使用时,在第一个训练epoch之前,所有非随机变换 LoadImagedEnsureChannelFirstdSpacingdOrientationdScaleIntensityRanged 都可以被缓存。在训练期间,数据集将加载缓存的结果并运行 RandCropByPosNegLabeldToTensord,因为 RandCropByPosNegLabeld 是一个随机化变换,其结果不会被缓存。

参数解析

train_transforms = transforms.Compose(省略)
train_ds = CacheDataset(data=train_dicts, transform=train_transforms, cache_rate=1.0, num_workers=4, progress=True)
  • cache_rate:总缓存数据的百分比(如果不能全部缓存,可以设置百分比),默认为 1.0(全部缓存)。将取 (cache_num,data_length x cache_rate,data_length) 中的最小值。
  • cache_num:要缓存的项目数量,默认是 sys.maxsize。将取 (cache_num, data_length x cache_rate, data_length) 的最小值。
  • num_workers:如果在初始化时计算缓存,这是工作线程的数量。如果 num_workers 是 None,则使用 os.cpu_count() 返回的数字。如果指定的值小于 1,则会使用 1。
  • progress:是否显示进度条。

适用情况:如果数据量不太大,能全部缓存到内存,则这是最高性能的Dataset。

注意CacheDataset 在第一个epoch之前,在主进程中执行非随机变换并准备缓存内容,然后 DataLoader 的所有子进程在训练期间将从主进程读取相同的缓存内容。根据缓存数据的大小,准备缓存内容可能需要很长时间。因此,为了在实际训练之前调试或验证程序,用户可以设置 cache_rate=0.0 或 cache_num=0 来临时跳过缓存。代码调试完毕后再改回去。

PersistentDataset

我们知道一般中小型服务器内存大多在512GB及以下,假设想要训练一个大模型,数据量在几万到十几万的3D CT数据,想要全部缓存在内存中是根本不可能的。PersistentDataset就可以用于处理大型数据集,支持高效的数据加载和管理。

PersistentDataset在第一个epoch之前,将non-random transforms(非随机变换)应用到数据并缓存储到磁盘上的持久化表示中。它同样是把数据全部缓存起来,CacheDataset是缓存在内存中,PersistentDataset是缓存在磁盘中(磁盘读写速度肯定没有内存快)

参数解析

train_transforms = transforms.Compose(省略)
train_ds = PersistentDataset(data=train_dicts, transform=train_transforms, cache_dir="./data/cache")
train_loader = DataLoader(train_ds, batch_size=1, num_workers=8, pin_memory=torch.cuda.is_available())
  • cache_dir: 这里需要输入缓存的地址
    当你只运行到train_loader的时候,缓存地址里是不会有数据的,需要调用它才会对数据进行处理。因此,它不会像CacheDataset把数据都加载进去,所以这一步运行的贼快。

如果想要调试它是否会加载数据:

data = iter(train_loader).next()
print(data["image"].shape)

这是你就会发现缓存地址了存了数据

所以使用PersistentDataset后,哪怕训练结束,仍然会占用磁盘空间去存储这些中间结果。而CacheDataset会在训练结束就释放内存。

适用情况:适用于大规模数据集,搞大模型就用这个!!

DecathlonDataset

医学分割十项全能挑战数据集(DecathlonDataset)是一个用于医学图像分割任务的数据集(very hot!)。该数据集包含来自不同医学影像模态(如MRI、CT等)的图像数据以及标签。

MONAI的DecathlonDataset会自动下载该数据集,并且分好了训练、验证和测试集。它还基于monai.data.CacheDataset类来加速训练过程。

train_ds = DecathlonDataset(
    root_dir=root_dir,
    task="Task01_BrainTumour",
    section="training",
    cache_rate=1.0,  # you may need a few Gb of RAM... Set to 0 otherwise
    num_workers=4,
    download=True,  # Set download to True if the dataset hasnt been downloaded yet
    seed=0,
    transform=train_transforms,
)
train_loader = DataLoader(
    train_ds, batch_size=32, shuffle=True, num_workers=4, drop_last=True, persistent_workers=True
)

MedNISTDataset

受 Medical Segmentation Decathlon(医学分割十项全能)的启发,上海交通大学的研究人员创建了医疗图像数据集 MedMNIST,共包含 10 个预处理开放医疗图像数据集(其数据来自多个不同的数据源,并经过预处理)。和 MNIST 数据集一样,MedMNIST 数据集在轻量级 28 × 28 图像上执行分类任务,所含任务覆盖主要的医疗图像模态和多样化的数据规模,作为 AutoML 在医疗图像分类领域的基准。

代码如下:

train_ds = MedNISTDataset(root_dir=root_dir, transform=transform, section="training", download=True)
# the dataset can work seamlessly with the pytorch native dataset loader,
# but using monai.data.DataLoader has additional benefits of mutli-process
# random seeds handling, and the customized collate functions
train_loader = DataLoader(train_ds, batch_size=300, shuffle=True, num_workers=10)

DecathlonDatasetMedNISTDataset主要是用于加载特定的公开数据集,具体的使用方法详见之前的教程 使用MONAI轻松加载医学公开数据集

不同Dataset之间的速度PK

所以到底哪个Dataset快?MONAI官方对PersistentDataset, CacheDataset, LMDBDataset, and simple Dataset 进行了速度PK,代码详见monai dataset 性能比较。使用unet对十项全能数据集Task09_Spleen进行分割,相同的实验设置下,仅改变Datasets,结果如下

左边是一共训练30个epoch,不同Dataset用的总时间对比,右边是每个epoch花费的时间曲线。

结论:常规Dataset花费的时间最多,PersistentDatasetCacheDataset效率相差不大。数据量不大,选择CacheDataset。数据量大选择PersistentDataset。当然还有好多其他的Dataset,以后遇到再做分享。

文章持续更新,可以关注微公【医学图像人工智能实战营】获取最新动态,一个关注于医学图像处理领域前沿科技的公众号。坚持以实践为主,手把手带你做项目,打比赛,写论文。凡原创文章皆提供理论讲解,实验代码,实验数据。只有实践才能成长的更快,关注我们,一起学习进步~

我是Tina, 我们下篇博客见~

白天工作晚上写文,呕心沥血

觉得写的不错的话最后,求点赞,评论,收藏。或者一键三连
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1289256.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Redis】redis 高性能--线程模型以及epoll网络框架

目录 一.前言 二.多线程的弊端 2.1 锁的开销问题 2.2 多线程上下文切换带来的额外开销 2.3 多线程占用内存成本增高 三.基本IO模型与epoll 模式 3.1 基本IO模型 3.2 单线程处理机制 四.总结 一.前言 我们经常讨论到,redis 是单线程,那为什么单线…

【开发板测评】一起玩转ACM32G103开发板,释放MCU无限潜能!

为帮助小伙伴们更好的快速熟悉了解ACM32G103系列的特性,航芯特别发起了该系列开发板评测试用,以帮助大家更好地运用MCU进行项目设计。 ACM32G103开发板介绍 ACM32G103系列是航芯推出的一款有着丰富模拟外设及安全存储扩展能力的高性价比通用MCU。 高性…

git bash查看远程仓库地址

进入代码路径 git remote -vgit remote -v

springBoot如何快速发布webService接口?(含测试工具)

文章目录 引入maven依赖 org.apache.cxf cxf-rt-frontend-jaxws 3.4.5 org.apache.cxf cxf-rt-transports-http 3.4.5 org.apache.cxf cxf-spring-boot-starter-jaxws 3.4.5 新建webService接口 注意接口要添加注释WebService,且要添加name和targetNamespace属性…

「遮天」叶凡斩杀同等级,寻回丢失秘宝,暴打神桥境同等级强者

Hello,小伙伴们,我是拾荒君。 《遮天》国漫第34集已经更新了!我的小伙伴们,包括拾荒君在内,都是迫不及待的去观看这一集。在这一集中,叶凡一直寻找的丢失的法器,被吴清风查出是被韩易水偷走的。这位韩长老…

Android audio环形缓冲队列

1、背景 在学习audio的过程中,看到了大神zyuanyun的博客,在博客的结尾,大神留下了这些问题: 但是大神没有出后续的博文来说明audio环形缓冲队列的具体实现,这勾起了我强烈的好奇心。经过一段时间的走读代码&#xff…

【日常总结】树莓派导致的公司无法上网 - 广播风暴

一、场景 二、问题 三、分析原因 四、解决方案 方案一:更换树莓派后ping路由器恢复正常 方案二:配置交换机 交换机广播风暴配置 也可以通过PPS来限速 查看配置 一、场景 宽带:公司3条500M光纤-联通 路由器:锐捷 在线用户…

Memory-augmented Deep Autoencoder for Unsupervised Anomaly Detection 论文阅读

Memorizing Normality to Detect Anomaly: Memory-augmented Deep Autoencoder for Unsupervised Anomaly Detection 摘要1.介绍2.相关工作异常检测Memory networks 3. Memory-augmented Autoencoder3.1概述3.2. Encoder and Decoder3.3. Memory Module with Attention-based S…

el-table全部选择和全部取消

el-table实现全部选择和全部取消 其实非常简单&#xff0c;el-table自带的都有方法toggleAllSelection()和clearSelection() 具体代码如下&#xff1a; <el-button typesuccess clickcheckAll sizesmall>全选</el-button> <el-button typesuccess clickcancel…

【往届见刊检索速度hin OK】 第五届计算机工程与应用国际学术会议 (ICCEA 2024)

第五届计算机工程与应用国际学术会议 (ICCEA 2024) 2024 5th International Conference on Computer Engineering and Application 2024年4月12-14日 中国-杭州 计算机工程与应用在人工智能、大数据、云计算、物联网、网络安全等领域发挥着重要作用&#xff0c;随着科技日…

docker 安装mysql 主从复制

一、搭建主服务器的mysql 1.1 先新建文件夹 mkdir -p /data/dockerData/mysql-master/conf 1.2 进入/data/dockerData/mysql-master/conf目录下新建my.config, [mysqld] ## 设置server_id&#xff0c;同一局域网中需要唯一 server_id101 ## 指定不需要同步的数据库名称 bin…

Redis7--基础篇7(哨兵sentinel)

1. 关于哨兵的介绍 1、监控redis运行状态&#xff0c;包括master和slave&#xff08;主从监控&#xff09; 2、哨兵可以将故障转移的结果发送给客户端&#xff08;消息通知&#xff09; 3、当master down机&#xff0c;能自动将slave切换成新master&#xff08;故障转移&#…

学生档案管理系统设计

摘要 随着科学技术的不断提高,计算机科学日渐成熟,其强大的功能已为人们深刻认识,它已进入人类社会的各个领域并发挥着越来越重要的作用。作为计算机应用的一部分,使用计算机对学生档案信息进行管理,具有着手工管理所无法比拟的优点.例如:检索迅速、查找方便、可靠性高、存储量…

20、pytest中的参数化

官方实例 # content of test_expectation.pyimport pytestpytest.mark.parametrize("test_input, expected",[("35",8),("24",6),("6*9",42)]) def test_eval(test_input, expected):assert eval(test_input) expected# content of …

Vmware虚拟机简介和安装

作者&#xff1a;余小小 常见的虚拟机 vmwarevirtualBox Vmware 运行在win系统上centos运行在Vm上 先安装vm&#xff0c;在安装centos系统 Vmware介绍 不用分区或者重开机&#xff0c;就可以在同一台pc上使用多种操作系统完全隔离&#xff0c;且保护不同的操作系统环境和文…

掌控安全 暖冬杯 CTF Writeup By AheadSec

本来结束时发到了学校AheadSec的群里面了的&#xff0c;觉得这比赛没啥好外发WP的&#xff0c;但是有些师傅来问了&#xff0c;所以还是发一下吧。 文章目录 Web签到&#xff1a;又一个计算题计算器PHP反序列化又一个PHP反序列化 Misc这是邹节伦的桌面背景图什么鬼&#xff1f;…

【分享】PDF文件不能编辑的3个原因

PDF文件具有很好的兼容性&#xff0c;可靠性&#xff0c;安全性&#xff0c;是很多人办公常用的电子文档格式。但有时候想要编辑PDF时&#xff0c;却发现不能编辑&#xff0c;是什么原因呢&#xff1f;下面小编来分享一下常见的3个原因。 原因1&#xff1a; PDF文件是扫描件&a…

035.Python面向对象_三大特性_封装、继承、多态

我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448; 入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448; 虚 拟 环 境 搭 建 &#xff1a;&#x1f449;&…

Android studio中如何生成jar包?

文章目录 需求背景目录结构gradle结构makeJar的语法解析 执行makeJar 任务拿到jar包 需求背景 别部门做C语言开发的同学开发了一个库&#xff0c;需要给我们Android端去调用。 我们拿到源码&#xff0c;首先需要做的是通过CMake去把C源码编译链接成动态库。 当然静态库也行&am…

NDIS协议驱动开发指南

文章目录 NDIS协议驱动开发指南1. 技术概览2. NDIS协议驱动2.1 BindAdapterHandlerEx2.2 SendNetBufferListsCompleteHandler2.3 ReceiveNetBufferListsHandler2.4 ProtocolNetPnpEvent 3. NET_BUFFER_LIST4. ndisprot实例5. 总结 NDIS协议驱动开发指南 我们知道&#xff0c;在…