在医学影像领域,深度学习技术的应用日益广泛,特别是在脑肿瘤的检测和定位方面。本文将介绍如何利用深度学习技术,通过MRI数据集对脑肿瘤进行预测和定位。这是系列文章的第二部分,如果尚未阅读第一部分,建议先阅读《深度学习在脑肿瘤检测和定位中的应用:第一部分》,以便更好地理解代码,因为这两篇文章是相互关联的。
在第一部分中,已经在ResNet50的基础上训练了一个分类模型,用于判断脑部MRI图像是否含有肿瘤,并使用回调函数来提高性能。在本部分,将训练一个模型来定位肿瘤。图像分割的目标是在像素级别上理解图像,将每个像素与某个类别关联起来。图像分割模型产生的输出被称为图像的掩码。
首先,需要从上一部分创建的数据框中选择掩码值为1的记录,因为只有当肿瘤存在时,才能定位它。以下是选择含有掩码的MRI数据的代码示例:
brain_df_mask = brain_df[brain_df['mask'] == 1]
brain_df_mask.shape
Output: (1373, 4)
接下来,将数据分为训练集和测试集。首先,将整个数据集分为训练集和验证集,然后将验证集的一半进一步分为测试集。
from sklearn.model_selection import train_test_split
X_train, X_val = train_test_split(brain_df_mask, test_size=0.15)
X_test, X_val = train_test_split(X_val, test_size=0.5)
将再次生成虚拟数据,即training_generator和validation_generator,使用DataGenerator。为此,首先创建一个包含图像和掩码路径的列表,以便传递给生成器。
train_ids = list(X_train.image_path)
train_mask = list(X_train.mask_path)
val_ids = list(X_val.image_path)
val_mask = list(X_val.mask_path)
from utilities import DataGenerator
training_generator = DataGenerator(train_ids, train_mask)
validation_generator = DataGenerator(val_ids, val_mask)
在深度学习模型中,定义了一个名为Resblock的方法,如下所示。Resblocks用于模型中以获得更好的结果。这些块仅仅是一些层的集合。resblocks的主要特点是在顶部学习一个残差函数,同时在底部不变地传递信息。
def resblock(X, f):
# 复制输入
X_copy = X
# ... 省略部分代码 ...
return X
类似地,定义了upsample_concat方法,该方法用于上采样和连接传递的值。上采样层是一个没有权重的简单层,它将输入的尺寸加倍。
def upsample_concat(x, skip):
x = UpSampling2D((2,2))(x)
merge = Concatenate()([x, skip])
return merge
构建一个包含上述定义的resblock和upsample_concat的分割模型。以下是构建模型的代码示例:
input_shape = (256,256,3)
# 输入张量形状
X_input = Input(input_shape)
# ... 省略部分代码 ...
output = Conv2D(1, (1,1), padding = "same", activation = "sigmoid")(up_4)
model_seg = Model(inputs = X_input, outputs = output)
接下来,编译上述训练的模型。这次将自定义优化器的参数。Focal tversky是损失函数,tversky是度量。
from utilities import focal_tversky, tversky
adam = tf.keras.optimizers.Adam(lr = 0.05, epsilon = 0.1)
model_seg.compile(optimizer = adam, loss = focal_tversky, metrics = [tversky])
现在,已经了解了在分类模型中使用的回调函数。将使用相同的回调函数来获得更好的性能。最后,训练分割模型。
earlystopping = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=20)
checkpointer = ModelCheckpoint(filepath="ResUNet-weights.hdf5", verbose=1, save_best_only=True)
model_seg.fit(training_generator, epochs = 1, validation_data = validation_generator, callbacks = [checkpointer, earlystopping])
为测试数据集预测掩码。在这里,模型是之前训练的分类模型,model_seg是上面训练的分割模型。
from utilities import prediction
# 进行预测
image_id, mask, has_mask = prediction(test, model, model_seg)
df_pred = pd.DataFrame({'image_path': image_id,'predicted_mask': mask,'has_mask': has_mask})
df_pred = test.merge(df_pred, on = 'image_path')
df_pred.head()
count = 0
fig, axs = plt.subplots(10, 5, figsize=(30, 50))
for i in range(len(df_pred)):
if df_pred['has_mask'][i] == 1 and count < 5:
# ... 省略部分代码 ...
count += 1
fig.tight_layout()