医疗图像领域的常见问题总结 | 笔记 | 2023-03-09

深度学习模型的相关方法

这部分主要是个人在阅读相关代码时,发现其中使用到了部分之前较少见过的方式方法,为了便于今后的学习,因此在这里进行总结。
可能在叙述顺序上缺乏一定的逻辑,如果论文能够顺利发表,再进行详细布局。

1 深度监督

1-1 概念

深度监督(Deep Supervision)是指在神经网络的训练过程中,同时利用神经网络中不同层次的输出结果来进行多任务训练,以帮助网络更好地学习特征和提高模型的性能。在一些任务中,模型的最终输出结果可能受到训练数据的噪声、样本数量不足等问题的影响,因此利用中间层次的输出结果来进行监督,有助于提高模型的鲁棒性和泛化能力。

1-2 PyTorch中的使用语法

#一共生成了六张注意力机制张量,编码器有三张,解码器中有三张
if args.sadencoder == 1:
	# attentions 0, 1, 2
	gamma_sad = [0.1, 0.1, 0.1] #决定了每个注意力张量的损失函数在总体损失函数中的权重
	for iter_sad in range(2):
		# sad_loss函数计算了两个注意力张量之间的余弦相似度
		loss += (gamma_sad[iter_sad])*sad_loss(attentions[iter_sad], attentions[iter_sad+1], encoder_flag=True)

if args.saddecoder == 1:
	# attentions 3, 4, 5, 6
	gamma_sad = [0.1, 0.1, 0.1]
	for iter_sad in range(3, 6):
		loss += (gamma_sad[iter_sad-3])*sad_loss(attentions[iter_sad], attentions[iter_sad+1], encoder_flag=False)

2 自注意力机制张量

对于一个三维CT图像,模型在进行注意力机制时,每个切片都会对应一个注意力张量,可以理解为每个切片都有自己的注意力分布。在实现时,可以将每个切片看作一个batch进行计算,即将每个切片作为一个输入,然后得到对应的注意力张量,这些张量可以组成一个三维的张量,对应输入CT图像的形状。

2-1 为什么在编码器阶段和解码器阶段的自注意力机制张量的数量不相等?

在观察代码时,发现在训练的train_casenet中,有关于自注意力机制张量的代码部分如下所示:

#一共生成了六张注意力机制张量,编码器有三张,解码器中有三张
if args.sadencoder == 1:
	# attentions 0, 1, 2
	gamma_sad = [0.1, 0.1, 0.1] #决定了每个注意力张量的损失函数在总体损失函数中的权重
	for iter_sad in range(2):
		# sad_loss函数计算了两个注意力张量之间的余弦相似度
		loss += (gamma_sad[iter_sad])*sad_loss(attentions[iter_sad], attentions[iter_sad+1], encoder_flag=True)

if args.saddecoder == 1:
	# attentions 3, 4, 5, 6
	gamma_sad = [0.1, 0.1, 0.1]
	for iter_sad in range(3, 6):
		loss += (gamma_sad[iter_sad-3])*sad_loss(attentions[iter_sad], attentions[iter_sad+1], encoder_flag=False)

从上述代码中可以看出,在编码器啊计算一共使用了3个自注意力机制张量,但是在解码阶段使用了4个自注意力机制张量,这是因为解码器需要将低分辨率的特征图恢复到原始特征图的尺寸,因此需要保存更多的空间信息,解码器需要更多的自注意力机制张量来实现更好的分割效果。

3 SAD损失函数

3-1 概念

SAD(Structure-Aware Distillation)损失函数是一种用于多尺度注意力机制的监督方法。它可以帮助网络学习结构信息和空间信息,从而提高模型的性能。SAD损失函数的定义包括了两个步骤:

1、计算多尺度注意力张量之间的相似度,具体地,对于一个多尺度注意力张量,它会被切成多个大小相同的子块,然后对这些子块之间的相似度进行计算。

2、计算多尺度注意力张量之间的距离,具体地,将两个多尺度注意力张量的所有子块分别取出来,然后计算它们之间的欧几里得距离。

最终,SAD损失函数可以通过以上两个步骤来监督网络的多尺度注意力机制,帮助网络更好地学习结构信息和空间信息。

3-2 为什么注意力图像机制中要计算SAD损失函数?

在注意力机制中,SAD(Spatial Attention Difference)损失函数的作用是衡量相邻的两个注意力张量之间的相似度。这样做的目的是在训练过程中强制模型生成相似的注意力张量,从而确保模型生成的注意力张量具有相关性,能够更好地捕捉特征。

在计算SAD损失函数时,通常会比较相邻两个注意力张量之间的相似度,然后将相似度作为损失函数的一部分,通过反向传播调整网络参数,使得模型可以生成更加相似的注意力张量。通过这种方式,可以确保在训练过程中,模型能够生成具有相关性的注意力张量,从而提高模型的性能。

3-3 PyTorch中的使用语法

#一共生成了六张注意力机制张量,编码器有三张,解码器中有三张
if args.sadencoder == 1:
	# attentions 0, 1, 2
	gamma_sad = [0.1, 0.1, 0.1] #决定了每个注意力张量的损失函数在总体损失函数中的权重
	for iter_sad in range(2):
		# sad_loss函数计算了两个注意力张量之间的余弦相似度
		loss += (gamma_sad[iter_sad])*sad_loss(attentions[iter_sad], attentions[iter_sad+1], encoder_flag=True)

if args.saddecoder == 1:
	# attentions 3, 4, 5, 6
	gamma_sad = [0.1, 0.1, 0.1]
	for iter_sad in range(3, 6):
		loss += (gamma_sad[iter_sad-3])*sad_loss(attentions[iter_sad], attentions[iter_sad+1], encoder_flag=False)

4 3D输入数据

首先可以明确的是,如果输入数据是3D形式,在预处理阶段往往会对其进行切片处理,使其变成2D数据,并且切片的数量与输入数据channel的数量是一致的。

4-1 3D输入数据本身自带标签问题(以CT图像为例)

1、介绍

CT图像中所给标签是二维像素级别的标签,而不是体素级别的标签,并且是多类别的,也就是每个像素点可能属于多个类别,而不是简单的二值标签,例如一个肿瘤可能被划分为不同的类型,而不同的类型会被赋予不同的标签值,因此在分割任务中,往往需要将多类别的标签转换为二值标签,以便可以进行分类任务。

2、二值化的处理方法

这个二值化过程一般通过设置一个阈值来完成,大于某值被认为是分割部分的区域,赋值为1,小于则认为是周围区域,赋值为0。

# for evaluation
lossHist.append(loss.item()) #将每一次计算得到了loss值存入列表lossHist中
# segmentation calculating metrics#######################
outdata = casePred.cpu().data.numpy() #获取模型的预测结果,并将其转为numpy数组
segdata = y.cpu().data.numpy() #获取真实真实标签,并将其转为numpy数组
segdata = (segdata > th_bin) #将真实标签中大于th_bin的像素值转为1,其余转为0,这里的th_bin是一个二值化的阈值,用于将连续的像素值转换为二值化的标签

4-2 3D输入数据预测结果标签问题

对于3D数据的输入模型,在切片的情况下,网络输出是对每个切片中每个像素的预测标签。如果要得到对应的体素的预测标签,可以通过对每个切片中预测结果的叠加来得到,即将每个切片的预测结果按照其在原始体积中的位置进行叠加,然后通过某种策略(例如简单地取每个体素预测结果中的众数)来得到对应体素的预测标签。这样就可以得到对整个3D体积的预测结果。

策略的方式:
1、平均投票法(Majority Voting):对于每个像素位置,在每个切片上的预测标签进行投票,得票数最多的标签作为该像素位置的最终预测结果。
2、最大投票法(Max Voting):对于每个像素位置,在每个切片上的预测标签中出现次数最多的标签作为该像素位置的最终预测结果。
3、级联法(Cascade):先使用一个网络对整个3D数据进行预测,再使用另一个网络对预测结果进行修正。
4、三维全卷积网络(3D Fully Convolutional Network):使用一个网络对整个3D数据进行预测,得到每个像素位置的预测结果。

5 样本的敏感度

5-1 概念

在机器学习中,样本的敏感度通常是指训练数据中每个样本对于模型预测结果的影响程度。通常情况下,样本的敏感度与其在训练数据中的重要性相关,即在训练数据中起到更重要作用的样本更加敏感。在一些场景下,例如对于异常检测和离群点检测,样本的敏感度可以帮助我们发现那些对于模型预测结果影响较大的异常样本或者离群点。

5-2 PyTorch中的使用语法

sensiti = sensitivity_np(segpred, segdata[j, 0]) #计算当前样本的敏感度

6 CT图像中的坐标点

6-1 物理坐标点

物理坐标通常是以图像的左上角(即坐标轴的原点)为基准点,因为计算机中图像的存储方式也是以左上角为起点的。但是在医学图像中,物理坐标也可能以某个特定的物理点为基准点,例如CT图像中的切片位置可能会以扫描仪的中心点作为物理坐标的基准点。

6-2 org坐标轴原点

在医学图像处理中,org常常是指采样的原点,即采样时采集到的体素中的第一个体素在物理坐标系中的位置,通常也称为图像的原点或起始点。org记录的是采样时的原点在物理坐标系中的位置,通常是一个三元组 (x0, y0, z0),分别表示x、y、z三个方向上的位置。org的记录方式可以是具体的坐标值,也可以是采样原点在物理坐标系中的索引值,具体要看具体的实现方式。在医学图像处理中,org的记录通常会被用来计算体素的物理坐标位置,方便后续的处理和分析。

7 训练阶段使用随机patch

7-1 概念

在深度学习中,选择随机patch通常是指在训练阶段对输入图像进行数据增强的一种方式。具体来说,随机patch指从原始输入图像中随机选择一个小的矩形区域(也称为“patch”),并将其作为一个新的训练样本输入到模型中进行训练。

7-2 意义

选择随机patch的目的是为了增加数据的多样性,从而提高模型的泛化能力。通过随机选择不同的patch,可以使模型在训练时学习到更多的图像变化和纹理信息,从而能够更好地应对测试数据中的不同场景和情况。

在实际应用中,选择随机patch通常与其他数据增强技术一起使用,如图像翻转、旋转、缩放等。这些技术可以帮助模型更好地学习到数据的不同方面,从而提高模型的性能。

7-3 PyTorch中的使用语法

def __init__(self, config, phase='train', split_comber=None,
				 debug=False, random_select=False):
	# random_select就是随机选择部分数据作为训练集patch进行训练
	self.rand_sel = random_select #通常代表从图像中随机选择一部分patch
	self.patch_per_case = 5  # patches used per case if random training 在随机训练时,每次使用5个数据块
	if self.rand_sel:
	   """
	   only chooses random number of patches for training
	   只选择随机数量的patch进行训练
	   """
	   cubelist.append(cube_train)
	else:
	   cubelist += cube_train

8 对数据集打乱规律

8-1 意义

对于包含训练集、验证集和测试集三个不同类型的数据集的 cubelist,随机打乱的目的是为了消除数据的排序规律,避免模型在学习过程中出现对特定数据顺序的依赖性,提高模型的泛化能力和稳定性。

具体来说,如果数据集按照某种规律排序(例如按照标签排序),那么模型可能会学到这种规律,而不是真正的数据特征。这就会导致模型在处理未知数据时的性能下降。通过随机打乱数据集,可以有效地减少这种规律的影响,提高模型的鲁棒性和泛化能力。

8-2 PyTorch中的使用语法

random.shuffle(cubelist) 

PyTorch架构中的常见语法

之前没有接触过PyTorch的相关结构,因此在阅读代码是存在部分困难,在这里做部分总结学习。

1 enumerate&tqdm

for i, (x, y, coord, org, spac, NameID, SplitID, nzhw, ShapeOrg) in enumerate(tqdm(data_loader)):

2 .cpu()

.cpu() 是 PyTorch 中 Tensor 对象的一个方法,用于将 Tensor 从 GPU 设备移动到 CPU 设备上。在机器学习模型的训练过程中,通常需要将输入数据和模型参数存储在 GPU 上进行计算,以提高计算效率。但在某些情况下,如需要将 Tensor 转换为 NumPy 数组以便进行后续处理时,需要将其移回 CPU 上。

outdata = casePred.cpu().data.numpy() 

3 .cuda()

.cuda()是PyTorch中的一个方法,用于将模型或数据转移到GPU上进行加速运算。它会将对象移动到默认的CUDA设备上。在使用.cuda()方法时,需要保证CUDA已经被正确安装并且可用。

x = x.cuda() # 将x转移到GPU上
y = y.cuda()

4 .append()和+=运算符的区别

.append() 方法:.append() 是列表对象的一个方法,用于向列表的末尾添加单个元素。例如,语句cubelist.append(cube_train) 将一个名为 cube_train 的列表添加到 cubelist 列表的末尾。

+= 运算符:+= 运算符也可以用于向一个列表中添加另一个列表。但是,与 .append() 不同,+= 会将另一个列表中的所有元素添加到目标列表中,而不是将整个列表作为单个元素添加。语句 cubelist += cube_train 将 cubelist 和 cube_train 中的元素合并为一个新列表,并将其赋值给 cubelist。

为方便理解起见,下面将给出一个具体的例子:

cubelist1 = [1, 2, 3]
cubelist2 = [1, 2, 3]
cube_train = [4, 5, 6]

# 使用 .append() 方法将 cube_train 添加到 cubelist 中
cubelist1.append(cube_train)
print(cubelist1)  # 输出:[1, 2, 3, [4, 5, 6]]

# 使用 += 运算符将 cube_train 添加到 cubelist 中
cubelist2 += cube_train
print(cubelist2)  # 输出:[1, 2, 3, 4, 5, 6]

输出结果如下所示:

[1, 2, 3, [4, 5, 6]]
[1, 2, 3, 4, 5, 6]

进程已结束,退出代码0

5 load_itk_image()

load_itk_image() 是一个用于读取 ITK 格式的医学图像数据的函数。ITK(Insight Segmentation and Registration Toolkit)是一个强大的图像分割和配准开源软件库,被广泛应用于医学影像处理领域。

load_itk_image() 函数的主要作用是将一个 ITK 格式的图像文件读入内存,并将其转换为 NumPy 数组。

下面是其示例代码:

import itk
import numpy as np

def load_itk_image(filename):
    # 读取 ITK 格式的图像文件
    itk_image = itk.imread(filename)

    # 获取图像的大小和像素间距
    size = itk_image.GetBufferedRegion().GetSize()
    spacing = itk_image.GetSpacing()

    # 将 ITK 图像转换为 NumPy 数组
    np_array = itk.GetArrayFromImage(itk_image)

    return np_array, size, spacing

该函数接受一个字符串类型的参数 filename,表示要读取的 ITK 格式的图像文件的路径。函数内部首先使用 ITK 库的 itk.imread() 函数读取图像文件,并将其保存在一个 ITK 图像对象中。然后,函数通过 ITK 库的 itk.GetArrayFromImage() 函数将 ITK 图像对象转换为 NumPy 数组,并返回该数组、图像的大小和像素间距。

使用该函数可以方便地读取和处理 ITK 格式的医学图像数据。

Python中代码常用变量所代意思

在医学图像领域,部分变量的名称已经变得”约定俗成“,因此在这里对所遇到的代码进行总结,以便后期进行代码编写时方便查找

变量名含义
augtype数据增强的类型或方法
stridetbatch的边长
cubesize输入的立方体的边长
stridev输入图像被切割成块的滑动窗口的步长
split_conmber用于图像分割或重组的函数
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值