在本文中,将探讨如何利用深度学习技术对MRI数据集中的脑肿瘤进行检测和定位。这项技术对于提高医疗诊断的准确性和效率具有重要意义。将分两部分来介绍:首先是分类模型的构建,用于检测MRI图像中的肿瘤;其次是定位模型的构建,用于确定肿瘤在大脑中的具体位置。
在深入实现部分之前,需要了解一些预备知识,包括深度学习的基础知识。将详细解释每个部分,如果在阅读过程中遇到任何困难,请在评论区提出。接下来,将使用Python进行实现。
使用的数据集是一个公开的MRI图像分割数据集,可以在Kaggle上找到。首先,需要导入所需的库,包括Pandas、Numpy、Seaborn、Matplotlib、OpenCV、Scikit-image、TensorFlow等。
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import cv2
from skimage import io
import tensorflow as tf
from tensorflow.keras import Sequential, layers, optimizers
from tensorflow.keras.applications.resnet50 import ResNet50
from tensorflow.keras.layers import *
from tensorflow.keras.models import Model
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
from tensorflow.keras import backend as K
from sklearn.preprocessing import StandardScaler
将CSV文件转换为DataFrame,以便进行特定的操作。DataFrame包含了MRI图像的路径和对应的掩码路径。查看DataFrame的详细信息,并统计每个类别的值。
brain_df = pd.read_csv('/Healthcare AI Datasets/Brain_MRI/data_mask.csv')
brain_df.info()
brain_df.head(5)
随机显示数据集中的一个MRI图像,并分析掩码图像的像素值。掩码图像的最大像素值为255,表示白色;最小像素值为0,表示黑色。
image = cv2.imread(brain_df.image_path[1301])
plt.imshow(image)
接下来,可视化MRI图像、对应的掩码以及带有掩码的MRI图像。
count = 0
fig, axs = plt.subplots(12, 3, figsize = (20, 50))
for i in range(len(brain_df)):
if brain_df['mask'][i] ==1 and count <5:
img = io.imread(brain_df.image_path[i])
axs[count][0].title.set_text('Brain MRI')
axs[count][0].imshow(img)
mask = io.imread(brain_df.mask_path[i])
axs[count][1].title.set_text('Mask')
axs[count][1].imshow(mask, cmap = 'gray')
img[mask == 255] = (255, 0, 0) #Red color
axs[count][2].title.set_text('MRI with Mask')
axs[count][2].imshow(img)
count+=1
fig.tight_layout()
删除不需要的ID列,并将掩码列的数据从整数转换为字符串格式。然后,将数据集分为训练集和测试集。
brain_df_train = brain_df.drop(columns = ['patient_id'])
brain_df_train['mask'] = brain_df_train['mask'].apply(lambda x: str(x))
train, test = train_test_split(brain_df_train, test_size = 0.15)
使用ImageDataGenerator进行数据增强,生成带有实时数据增强的批次张量图像数据。将创建一个训练生成器和一个验证生成器,以及一个测试数据生成器。
from keras_preprocessing.image import ImageDataGenerator
datagen = ImageDataGenerator(rescale=1./255., validation_split = 0.15)
train_generator=datagen.flow_from_dataframe(
dataframe=train,
directory='./',
x_col='image_path',
y_col='mask',
subset="training",
batch_size=16,
shuffle=True,
class_mode="categorical",
target_size=(256,256))
valid_generator=datagen.flow_from_dataframe(
dataframe=train,
directory='./',
x_col='image_path',
y_col='mask',
subset="validation",
batch_size=16,
shuffle=True,
class_mode="categorical",
target_size=(256,256))
test_datagen=ImageDataGenerator(rescale=1./255.)
test_generator=test_datagen.flow_from_dataframe(
dataframe=test,
directory='./',
x_col='image_path',
y_col='mask',
batch_size=16,
shuffle=False,
class_mode='categorical',
target_size=(256,256))
迁移学习是一种使用预训练模型的技术,可以在预训练模型的基础上构建自己的模型。ResNet(残差网络)是在ImageNet数据集上训练的ANN,可以用于在之上训练模型。ResNet50是ResNet模型的一个变体,包含48个卷积层以及1个最大池化层和1个平均池化层。
basemodel = ResNet50(weights = 'imagenet', include_top = False, input_tensor = Input(shape=(256, 256, 3)))
basemodel.summary()
for layer in basemodel.layers:
layer.trainable = False
headmodel = basemodel.output
headmodel = AveragePooling2D(pool_size = (4,4))(headmodel)
headmodel = Flatten(name= 'flatten')(headmodel)
headmodel = Dense(256, activation = "relu")(headmodel)
headmodel = Dropout(0.3)(headmodel)
headmodel = Dense(256, activation = "relu")(headmodel)
headmodel = Dropout(0.3)(headmodel)
headmodel = Dense(256, activation = "relu")(headmodel)
headmodel = Dropout(0.3)(headmodel)
headmodel = Dense(2, activation = 'softmax')(headmodel)
model = Model(inputs = basemodel.input, outputs = headmodel)
model.summary()
model.compile(loss = 'categorical_crossentropy', optimizer='adam', metrics= ["accuracy"])
earlystopping = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=20)
checkpointer = ModelCheckpoint(filepath="classifier-resnet-weights.hdf5", verbose=1, save_best_only=True)
model.fit(train_generator, steps_per_epoch= train_generator.n // 16, epochs = 1, validation_data= valid_generator, validation_steps= valid_generator.n // 16, callbacks=[checkpointer, earlystopping])
test_predict = model.predict(test_generator, steps = test_generator.n // 16, verbose =1)
predict = []
for i in test_predict:
predict.append(str(np.argmax(i)))
predict = np.asarray(predict)
from sklearn.metrics import accuracy_score, classification_report
accuracy = accuracy_score(original, predict)
accuracy
report = classification_report(original, predict, labels = [0,1])
print(report)