DLTK,即 医学成像的深度学习工具包 ,扩展了 TensorFlow, 使针对生物医学影像的深度学习成为可能。此工具包提供了专用运算与函数、模型实现、教程(如本博客中所用)和典型应用的代码示例。
本篇博文对生物医学影像深度学习进行了简要介绍,我们将围绕当前工程难点指出一些问题和解决方案,并展示如何针对您的问题启动和运行原型。
网站:https://dltk.github.io;
来源:https://github.com/DLTK/DLTK;
概述
什么是生物医学影像分析?为什么需要这种分析?
生物医学影像是在不同尺度(即微观、宏观等)下对人体进行的测量。它们具有多种成像模式(如 CT 扫描仪、超声机等)并测量人体的物理特性(如放射强度、对 X 射线的不透明度)。这些影像由临床任务(如诊断)的领域专家(如放射科医师)解释并对医生的决策具有重大影响。
医学影像示例(从左上方到右下方):多序列脑部 MRI:T1 加权、T1 反转恢复和 T2 FLAIR 通道;全身拼接 MRI;平面心脏超声;胸部 X 光片;心脏电影 MRI
生物医学影像通常为体积影像 (3D),有时还会加上时间维度 (4D) 和/或多个通道 (4-5D)(如多序列 MR 影像)。生物医学影像中的差异与自然影像(如照片)中的差异完全不同,因为临床方案的目的是对影像的采集方式进行分层(例如,患者平躺、头部保持正直,等等)。在影像分析过程中,我们的目标是发现细微差异(即一些小区域表明发现异常)。
为什么采用计算机视觉和机器学习?
长期以来,计算机视觉方法一直用于自动分析生物医学影像。近年来,随着深度学习的出现,许多其他机器学习方法被取代,因为深度学习免去了创建手工工程特征的必要,从过程中消除了一个关键的误差来源。此外,完全采用 GPU 加速的网络可以实现快速推断,让分析的数据量得到前所未有的增加(例如,10⁶ 个受试者影像)。
我们能否直接使用深度学习库进行生物医学成像?为什么要创建 DLTK?
之所以要创建 DLTK ,是因为要提供开箱即用并特定于该领域的专业工具。 尽管许多深度学习库向开发者公开了低级运算(如张量乘法等),但许多用于体积影像的较高级别专用运算却并未公开(例如,可区分的 3D 上采样层等),并且由于影像的其他空间维度,我们可能会遇到内存问题(例如,假设影像尺寸为 512x512x256 体素,那么以 float32 格式存储包含 1000 个 CT 影像的数据库的单个副本将需要大约 268 GB)。由于采集的性质不同,一些影像需要特殊的预处理(例如,强度归一化、偏置场校正、去噪、空间归一化/配准等)。
文件格式、头和读取影像
虽然许多成像模式供应商都按照 DICOM 标准格式制作影像并在一系列 2D 切片中保存卷,许多分析库还是依赖于更适合计算和与医学影像连接的格式。我们使用的是 NifTI (或 .nii 格式),这种格式最初开发用于脑部成像,但广泛用于 DLTK 和本教程中的大多数其他体积影像。这种格式和其他格式保存的内容是重建影像容器并将其在物理空间中定位的必要信息。
为此,它需要专用头信息,我们将对用于深度学习的一些属性进行介绍:
尺寸和大小存储有关如何重建影像的信息(例如,使用大小向量将体积分解为三维)
数据类型
体素间距(也是体素的物理尺寸,通常以毫米为单位)
物理坐标系原点
方向
为什么这些属性很重要?网络将在体素空间中进行训练,这意味着我们将创建形状和尺寸为 [batch_size, dx, dy, dz, channels/features] 的张量并将其提供给网络。网络将在该体素空间中进行训练并假设所有影像(包括未见过的测试影像)在该空间中归一化或者可能有需要泛化的问题。在该体素空间中,特征提取器(如卷积层)将假设体素尺寸各向同性(即,在每个维度中均相同)并且所有影像以相同的方式定向。
然而,由于大多数影像描述的都是物理空间,我们需要从该物理空间转换为常见的体素空间:
如果所有影像均以相同的方式定向(有时我们需要进行配准以在空间内归一化影像:请参见 MIRTK),我们可以通过以下公式计算从物理空间到体素空间的缩放转换:
phys_coords = origin + voxel_spacing * voxel_coord
所有上述信息均为 .nii 头文件中存储的向量。
读取 .nii 影像:可通过一些库读取 .nii 文件并访问和解析头信息以获得 numpy 阵列格式的重建影像容器。我们选择的是 SimpleITK,这是 ITK 库的一种 python 包装器,可用于导入额外的影像过滤器以进行预处理和其他任务。
数据 I/O 注意事项
根据训练数据库的大小,可通过几种不同方法将 .nii 影像数据提供给网络图。每种方法在速度方面都有特定的权衡,并且在训练期间可能成为瓶颈。我们将介绍并解释以下三个选项:
在内存和馈送字典中:
我们可以创建一个指向网络图的 tf.placeholder 并在训练期间通过 feed_dict 提供。我们从磁盘读取所有 .nii 文件,在 python 中处理文件(参见 load_data())并将所有训练示例存储在内存中,通过以下方式提供:
TLDR:此直接法通常速度最快且最容易实现,因为它避免了从磁盘连续读取数据,但需要在内存中保留整个训练示例(和验证示例)数据库,这对于较大的数据库或影像文件并不可行。
使用 TFRecords 数据库:
对于有关体积影像的大多数深度学习问题,训练示例数据库太大而无法存入内存。 TFRecords 格式允许序列化训练示例并将其存储在磁盘上,支持快速写访问(即并行数据读取):
此格式可以直接与 TensorFlow 连接并且可以直接集成到 tf.graph 中的训练循环中:
TLDR: TFRecords 可快速访问磁盘文件,但需要为整个训练数据库另外存储一个副本。如果我们要使用几 TB 大小的数据库,这种方法可能会让人望而却步。
使用原生 python 生成器:
最后,我们可以使用 python 生成器创建一个 read_fn() 以直接加载影像数据…
并使用 tf.data.Dataset.from_generator() 将示例排队:
TLDR: 这种方法避免了额外创建影像数据库副本,但速度要比 TFRecords慢得多,因为生成器不能并行读取和映射函数。
速度基准测试以及选择方法:
我们运行了上述三种方法向 TensorFlow 读取 .nii 文件,并比较了加载和提供固定大小的示例数据库所需的时间。所有代码和结果都可以在上文找到。
显而易见,最快的方法是通过占位符从内存中提供,时间为 5.6 秒,其次是 TFRecords ,时间为 31.1 秒,最后是使用 python 生成器的未优化磁盘读取,时间为 123.5 秒。然而,只要训练期间的前向/后向传递是计算瓶颈,数据 I/O 的速度就可以忽略不计。
数据归一化
与自然影像一样,我们也可以对生物医学影像数据进行归一化,但方法可能略有不同。归一化的目的是消除数据中的一些已知差异(例如,受试者姿势或影像对比度不同等),从而简化对我们感兴趣的细微差异的检测(例如,存在病变)。本文将介绍最常见的归一化形式:
体素强度归一化:
这种形式高度依赖于采集数据所用的成像模式。典型的零均值单位方差归一化是定性影像的标准(例如,加权脑部 MR 影像,其中对比度高度依赖于采集参数,通常由专家设置)。如果我们采用这种统计方法,我们将使用完整单一卷的统计数据,而不是整个数据库。
与此相反,定量成像测量物理量(例如,CT 成像中的放射强度,其中不同扫描仪的强度类似)并且受益于削波和/或重新缩放,如简单范围归一化(例如 [-1,1])。
强度归一化方法示例
空间归一化:
通过使用影像方向归一化,模型无需学习所有可能的方向,从而大大减少了所需的训练影像的数量(请参见头属性的重要性,了解影像的方向)。此外,我们还考虑了体素间距,即使采集自同一扫描仪,影像之间也可能存在差异。可通过重新采样为各向同性分辨率来实现这一点:
如果需要进一步归一化,我们可以使用医学影像配准包(例如 MIRTK,等等)将影像配准到相同的空间中,使影像之间的体素位置彼此对应。分析结构性脑部 MR 影像(例如 T1 加权 MR 影像)的典型步骤是按参考标准配准训练数据库中的所有影像,例如平均图集(如 MNI 305 图集)。根据配准方法的自由度,也可以针对尺寸(仿射配准)或形状(可变形配准)归一化。这两种变体很少使用,因为它们去除了影像中的一些信息(即形状信息或尺寸信息),而这些信息可能对分析有着重要意义(例如,心脏较大可能预示有心脏病)。
数据增强
通常情况下,可用的数据量有限,并且未涵盖某些差异。一些例子如下所示:
存在各种正常形状的软组织器官
形状和位置存在显著差异的病变,如癌变
可能有很多视图的手动超声影像
为了正确地泛化到未见过的测试用例,我们通过模拟待增强数据中的差异来增强训练影像。与归一化方法类似,我们对强度和空间增强加以区分:
强度增强示例:
向训练影像添加噪声以泛化为噪声影像
添加随机偏移或对比度以处理影像之间的差异
空间增强示例:
在需要对称性的方向上翻转影像张量(例如,在扫描脑部时左/右翻转)
随机变形(例如,用于模仿器官形状的差异)
沿轴旋转(例如,用于模拟超声视角差异)
在块上进行随机裁剪和训练
强度和空间增强技术示例
关于增强和数据 I/O 的重要说明: 根据所需或有用的增强,某些操作仅在 python 中可用(例如,随机变形),也就是说,如果采用使用原始 TensorFlow (即 TFRecords 或 tf.placeholder)的读取方法,它们需要预先计算并存储到磁盘中,因此大大增加了训练数据库的大小。
类平衡
基于医学影像进行监督式学习期间,必须由领域专家解释(如手动分割或疾病类别)。通常,影像级(如疾病类别)或体素级(即分割)标签的比率不能相同,这意味着在训练期间网络不会从每个类看到相同数量的示例。如果类比率基本相似(例如,对于二元分类情况,比率为 30/70),则对准确性没有太大影响。然而,由于大多数损失是整个批次的平均成本,因此网络将首先学会正确预测最常见的类(例如,背景或正常情况,通常有更多可用的示例)。
如果训练期间类不平衡,将对罕见现象(如影像分割中的小病变)产生较大影响,并在很大程度上影响测试的准确性。
为了避免这种情况,可通过两种典型方法来解决数据集中的类不平衡问题:
通过采样实现类平衡:我们此时的目标是更正采样过程中已见过示例的频率。可通过以下方式来完成:
a) 从每个类中抽取相等的量
b) 对出现过多的类进行欠采样或
c) 对频率较低的类进行过采样。
在 DLTK中,我们提供了针对方式 a 的实现,可点击此处获取。我们对影像卷中的随机位置进行采样,并考虑一个提取的示例(如果包含我们要寻找的类)。
注:此处 链接
https://github.com/DLTK/DLTK/blob/blog/dltk/io/augmentation.py#L120
通过损失函数实现类平衡:与典型的体素平均损失(如分类交叉熵、L2 等)相反,我们可以 a) 使用本质上平衡的损失函数(如平滑的 Dice 损失,即所有类的平均 Dice 系数)或 b) 按类频率将每个预测的损失重新加权(例如,中值频率重新加权交叉熵)。
应用亮点示例
通过本博文中提供的所有基础知识,我们现在可以使用 TensorFlow着手构建用于医学影像深度学习的完整应用。我们已经使用深度神经网络实现了几个典型应用,接下来将对其中一些进行介绍,让您了解现在可以尝试解决哪些问题。
注:这些示例应用学习了一些有意义的内容,但它们是为了演示而构建,而不是高性能的实现。
示例数据集
对于以下所有示例,我们均提供下载和预处理脚本。对于大多数情况(包括上面的演示),我们使用的是 IXI 大脑数据库。对于影像分割,我们下载了 MRBrainS13 挑战数据库,您需要注册才能下载。
多通道脑部 MR 影像的影像分割
多序列影像输入、目标标签和预测的 Tensorboard 可视化
此影像分割应用基于小型 (N=5) MRBrainS 挑战数据集根据多序列 MR 影像(T1 加权、T1 反转恢复和 T2 FLAIR)学习预测脑组织和白质病变。它使用以残差单位作为特征提取器的 3D U-Net 型网络,并在 TensorBoard中跟踪每个标签的 Dice 系数精度。
有关代码和说明,请点击此处。
注:此处链接
https://github.com/DLTK/DLTK/tree/master/examples/applications/MRBrainS13_tissue_segmentation
T1 加权脑部 MR 影像的年龄回归和性别分类
用于回归和分类的 T1 加权脑部 MR 影像输入示例
采用可扩展 3D ResNet 架构的两个类似应用基于 IXI 数据库中的 T1 加权脑部 MR 图像学习预测受试者的年龄(回归)或受试者的性别(分类)。这两个应用的主要区别在于损失函数:尽管我们训练回归网络将年龄预测为具有 L2 损失的连续变量(预测年龄与实际年龄之间的均方差),但我们使用分类交叉熵损失来预测性别类别。
有关这些应用的代码和说明,请点击分类和回归。
注:分类链接https://github.com/DLTK/DLTK/tree/master/examples/applications/IXI_HH_sex_classification_resnet
回归链接
https://github.com/DLTK/DLTK/tree/master/examples/applications/IXI_HH_age_regression_resnet
3T 多通道脑部 MR 影像的表示学习
使用深度卷积自动编码器网络测试影像和重建
此处我们演示了深度卷积自动编码器架构(一种强大的表示学习工具)的使用方法:网络将多序列 MR 影像作为输入,旨在对其进行重建。借此在其潜在变量中压缩整个训练数据库的信息。训练后的权重也可用于转移学习或信息压缩。请注意,重建的影像非常平滑:这可能是由于此应用使用 L2 损失函数或网络太小而无法正确编码详细信息。
有关代码和说明,请点击此处。
注:此处链接
https://github.com/DLTK/DLTK/tree/master/examples/applications/IXI_HH_representation_learning_cae
T1w 脑部 MR 影像的简单影像超分辨率
影像超分辨率:原始目标影像;下采样输入影像;线性上采样影像;预测超分辨率;
单影像超分辨率旨在学习如何基于低分辨率输入上采样和重建高分辨率影像。这一简单实现创建了低分辨率版本的影像,超分辨率网络学习将影像上采样为其原始分辨率(此处上采样因子为 [4,4,4])。此外,我们还计算线性采样版本以显示与重建影像的差异。
最后
我们希望本教程能够帮助您轻松开启生物医学图像深度学习的探索之旅。如果您觉得这篇教程有用,敬请分享并关注 github 上的 DLTK 。如果您有类似问题需要帮助,请访问我们的 gitter.io 聊天室并询问。或许有一天我们可以在 DLTK model zoo 中托管您的应用。感谢您的阅读!
全部0条评论
快来发表一下你的评论吧 !