如何使用深度學習進行腦腫瘤檢測和定位?
問題陳述
通過使用 Kaggle 的 MRI 數(shù)據(jù)集的圖像分割來預測和定位腦腫瘤。
將本文分為兩個部分,因為我們將針對相同的數(shù)據(jù)集,不同的任務訓練兩個深度學習模型。這部分的模型是一個分類模型,它會從 MRI 圖像中檢測腫瘤,然后如果存在腫瘤,我們將在本系列的下一部分中進一步定位有腫瘤的大腦部分。
先決條件
深度學習
讓我們?nèi)胧褂?python 的實現(xiàn)部分。數(shù)據(jù)集:
讓我們從導入所需的庫開始。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.python.keras import Sequential
from tensorflow.keras import layers, optimizers
from tensorflow.keras.a(chǎn)pplications.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
%matplotlib inline
將數(shù)據(jù)集的 CSV 文件轉換為數(shù)據(jù)幀,對其進行特定的操作。# data containing path to Brain MRI and their corresponding mask
brain_df = pd.read_csv('/Healthcare AI Datasets/Brain_MRI/data_mask.csv')
查看數(shù)據(jù)幀詳細信息。brain_df.info()
數(shù)據(jù)集信息 | 腦腫瘤檢測brain_df.head(5)
患者 ID:每條記錄的患者 ID(dtype:對象)圖像路徑:MRI 圖像的路徑(dtype:對象)蒙版路徑:對應圖像蒙版的路徑(dtype:Object)蒙版:有兩個值:0 和 1,具體取決于蒙版的圖像。(數(shù)據(jù)類型:int64)計算每個類的值。brain_df['mask'].value_counts()
隨機顯示數(shù)據(jù)集中的 MRI 圖像。image = cv2.imread(brain_df.image_path[1301])
plt.imshow(image)
image_path 存儲大腦 MRI 的路徑,因此我們可以使用 matplotlib 顯示圖像。提示:上圖中的綠色部分可以認為是腫瘤。此外,顯示相應的蒙版圖像。image1 = cv2.imread(brain_df.mask_path[1301])
plt.imshow(image1)
現(xiàn)在,你可能已經(jīng)知道蒙版是什么了。蒙版是對應的 MRI 圖像中受腫瘤影響的大腦部分的圖像。這里,蒙版是上面顯示的大腦 MRI。分析蒙版圖像的像素值。cv2.imread(brain_df.mask_path[1301]).max()
輸出:255蒙版圖像中的最大像素值為 255,表示白色。cv2.imread(brain_df.mask_path[1301]).min()
輸出:0蒙版圖像中的最小像素值為 0,表示黑色?梢暬竽X 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,因為它不需要進一步處理。# Drop the patient id column
brain_df_train = brain_df.drop(columns = ['patient_id'])
brain_df_train.shape
你將在輸出中獲得數(shù)據(jù)框的大小:(3929, 3)將蒙版列中的數(shù)據(jù)從整數(shù)格式轉換為字符串格式,因為我們需要字符串格式的數(shù)據(jù)。brain_df_train['mask'] = brain_df_train['mask'].a(chǎn)pply(lambda x: str(x))
brain_df_train.info()
如你所見,現(xiàn)在每個特征都將數(shù)據(jù)類型作為對象。將數(shù)據(jù)拆分為訓練集和測試集。# split the data into train and test data
from sklearn.model_selection import train_test_split
train, test = train_test_split(brain_df_train, test_size = 0.15)
使用 ImageDataGenerator 擴充更多數(shù)據(jù)。ImageDataGenerator 通過實時數(shù)據(jù)增強生成批量的張量圖像數(shù)據(jù)。
我們將從訓練數(shù)據(jù)創(chuàng)建一個 train_generator 和 validation_generator,并從測試數(shù)據(jù)創(chuàng)建一個 test_generator。# create an image generator
from keras_preprocessing.image import ImageDataGenerator
#Create a data generator which scales the data from 0 to 1 and makes validation split of 0.15
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))
# Create a data generator for test images
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))
現(xiàn)在,我們將學習遷移學習和 ResNet50 模型的概念,它們將用于進一步訓練模型。顧名思義,遷移學習是一種在訓練中使用預訓練模型的技術。你可以在此預訓練模型的基礎上構建模型。這是一個可以幫助你減少開發(fā)時間并提高性能的過程。ResNet(殘差網(wǎng)絡)是在 ImageNet 數(shù)據(jù)集上訓練的 ANN,可用于在其之上訓練模型。ResNet50 是 ResNet 模型的變體,它有 48 個卷積層以及 1 個 MaxPool 和 1 個平均池層。在這里,我們使用的是 ResNet50 模型,它是一種遷移學習模型。使用它,我們將進一步添加更多層來構建我們的模型。# Get the ResNet50 base model (Transfer Learning)
basemodel = ResNet50(weights = 'imagenet', include_top = False, input_tensor = Input(shape=(256, 256, 3)))
basemodel.summary()
你可以使用 .summary() 查看 resnet50 模型中的層,如上所示。凍結模型權重。這意味著我們將保持權重不變,以便它不會進一步更新。這將避免在進一步訓練期間破壞任何信息。# freeze the model weights
for layer in basemodel.layers:
layers.trainable = False
現(xiàn)在,如上所述,我們將在 ResNet50 層的頂部添加更多層。這些層會學習將舊特征轉化為對我們數(shù)據(jù)集的預測。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()
這些圖層已添加,你可以在摘要中看到它們。池化層用于減少特征圖的維度。平均池化層返回值的平均值。Flatten 層將我們的數(shù)據(jù)轉換為向量。密集層是規(guī)則的深度連接神經(jīng)網(wǎng)絡層;旧,它接受輸入并計算輸出 = activation(dot(input, kernel) + bias)dropout 層可以防止模型過擬合。它在訓練過程中將隱藏層的輸入單元隨機設置為 0。編譯上面構建的模型。Compile 定義了損失函數(shù)、優(yōu)化器和指標。# compile the model
model.compile(loss = 'categorical_crossentropy', optimizer='adam', metrics= ["accuracy"])
執(zhí)行提前停止以保存具有最小驗證損失的最佳模型。提前停止執(zhí)行大量訓練時期,一旦模型性能在驗證數(shù)據(jù)集上沒有進一步提高就停止訓練。ModelCheckpoint 回調與使用 model.fit() 的訓練一起使用,以在某個時間間隔保存權重,因此可以稍后加載權重,以便從保存的狀態(tài)繼續(xù)訓練。# use early stopping to exit training if validation loss is not decreasing even after certain epochs
earlystopping = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=20)
# save the model with least validation loss
checkpointer = ModelCheckpoint(filepath="classifier-resnet-weights.hdf5", verbose=1, save_best_only=True)
現(xiàn)在,你訓練模型并在參數(shù)中提供上面定義的回調。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])
預測并將預測數(shù)據(jù)轉換為列表。# make prediction
test_predict = model.predict(test_generator, steps = test_generator.n // 16, verbose =1)
# Obtain the predicted class from the model prediction
predict = []
for i in test_predict:
predict.a(chǎn)ppend(str(np.a(chǎn)rgmax(i)))
predict = np.a(chǎn)sarray(predict)
測量模型的準確性。# Obtain the accuracy of the model
from sklearn.metrics import accuracy_score
accuracy = accuracy_score(original, predict)
accuracy
打印分類報告。from sklearn.metrics import classification_report
report = classification_report(original, predict, labels = [0,1])
print(report)

請輸入評論內(nèi)容...
請輸入評論/評論長度6~500個字
最新活動更多
推薦專題
- 1 AI 眼鏡讓百萬 APP「集體失業(yè)」?
- 2 大廠紛紛入局,百度、阿里、字節(jié)搶奪Agent話語權
- 3 深度報告|中國AI產(chǎn)業(yè)正在崛起成全球力量,市場潛力和關鍵挑戰(zhàn)有哪些?
- 4 上海跑出80億超級獨角獸:獲上市公司戰(zhàn)投,干人形機器人
- 5 國家數(shù)據(jù)局局長劉烈宏調研格創(chuàng)東智
- 6 下一代入口之戰(zhàn):大廠為何紛紛押注智能體?
- 7 百億AI芯片訂單,瘋狂傾銷中東?
- 8 Robotaxi新消息密集釋放,量產(chǎn)元年誰在領跑?
- 9 格斗大賽出圈!人形機器人致命短板曝光:頭腦過于簡單
- 10 一文看懂視覺語言動作模型(VLA)及其應用