如何使用深度學(xué)習(xí)進行腦腫瘤檢測和定位?
問題陳述
通過使用 Kaggle 的 MRI 數(shù)據(jù)集的圖像分割來預(yù)測和定位腦腫瘤。
將本文分為兩個部分,因為我們將針對相同的數(shù)據(jù)集,不同的任務(wù)訓(xùn)練兩個深度學(xué)習(xí)模型。這部分的模型是一個分類模型,它會從 MRI 圖像中檢測腫瘤,然后如果存在腫瘤,我們將在本系列的下一部分中進一步定位有腫瘤的大腦部分。
先決條件
深度學(xué)習(xí)
讓我們?nèi)胧褂?python 的實現(xiàn)部分。數(shù)據(jù)集:
讓我們從導(dǎo)入所需的庫開始。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 文件轉(zhuǎn)換為數(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:對象)蒙版路徑:對應(yīng)圖像蒙版的路徑(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 顯示圖像。提示:上圖中的綠色部分可以認為是腫瘤。此外,顯示相應(yīng)的蒙版圖像。image1 = cv2.imread(brain_df.mask_path[1301])
plt.imshow(image1)
現(xiàn)在,你可能已經(jīng)知道蒙版是什么了。蒙版是對應(yī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、相應(yīng)的蒙版和帶有蒙版的 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ù)格式轉(zhuǎn)換為字符串格式,因為我們需要字符串格式的數(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ù)拆分為訓(xùn)練集和測試集。# 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ù)。
我們將從訓(xùn)練數(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)在,我們將學(xué)習(xí)遷移學(xué)習(xí)和 ResNet50 模型的概念,它們將用于進一步訓(xùn)練模型。顧名思義,遷移學(xué)習(xí)是一種在訓(xùn)練中使用預(yù)訓(xùn)練模型的技術(shù)。你可以在此預(yù)訓(xùn)練模型的基礎(chǔ)上構(gòu)建模型。這是一個可以幫助你減少開發(fā)時間并提高性能的過程。ResNet(殘差網(wǎng)絡(luò))是在 ImageNet 數(shù)據(jù)集上訓(xùn)練的 ANN,可用于在其之上訓(xùn)練模型。ResNet50 是 ResNet 模型的變體,它有 48 個卷積層以及 1 個 MaxPool 和 1 個平均池層。在這里,我們使用的是 ResNet50 模型,它是一種遷移學(xué)習(xí)模型。使用它,我們將進一步添加更多層來構(gòu)建我們的模型。# 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 模型中的層,如上所示。凍結(jié)模型權(quán)重。這意味著我們將保持權(quán)重不變,以便它不會進一步更新。這將避免在進一步訓(xùn)練期間破壞任何信息。# freeze the model weights
for layer in basemodel.layers:
layers.trainable = False
現(xiàn)在,如上所述,我們將在 ResNet50 層的頂部添加更多層。這些層會學(xué)習(xí)將舊特征轉(zhuǎn)化為對我們數(shù)據(jù)集的預(yù)測。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ù)轉(zhuǎn)換為向量。密集層是規(guī)則的深度連接神經(jīng)網(wǎng)絡(luò)層;旧,它接受輸入并計算輸出 = activation(dot(input, kernel) + bias)dropout 層可以防止模型過擬合。它在訓(xùn)練過程中將隱藏層的輸入單元隨機設(shè)置為 0。編譯上面構(gòu)建的模型。Compile 定義了損失函數(shù)、優(yōu)化器和指標。# compile the model
model.compile(loss = 'categorical_crossentropy', optimizer='adam', metrics= ["accuracy"])
執(zhí)行提前停止以保存具有最小驗證損失的最佳模型。提前停止執(zhí)行大量訓(xùn)練時期,一旦模型性能在驗證數(shù)據(jù)集上沒有進一步提高就停止訓(xùn)練。ModelCheckpoint 回調(diào)與使用 model.fit() 的訓(xùn)練一起使用,以在某個時間間隔保存權(quán)重,因此可以稍后加載權(quán)重,以便從保存的狀態(tài)繼續(xù)訓(xùn)練。# 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)在,你訓(xùn)練模型并在參數(shù)中提供上面定義的回調(diào)。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])
預(yù)測并將預(yù)測數(shù)據(jù)轉(zhuǎn)換為列表。# 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 UALink規(guī)范發(fā)布:挑戰(zhàn)英偉達AI統(tǒng)治的開始
- 2 北電數(shù)智主辦酒仙橋論壇,探索AI產(chǎn)業(yè)發(fā)展新路徑
- 3 降薪、加班、裁員三重暴擊,“AI四小龍”已折戟兩家
- 4 “AI寒武紀”爆發(fā)至今,五類新物種登上歷史舞臺
- 5 國產(chǎn)智駕迎戰(zhàn)特斯拉FSD,AI含量差幾何?
- 6 光計算迎來商業(yè)化突破,但落地仍需時間
- 7 東陽光:2024年扭虧、一季度凈利大增,液冷疊加具身智能打開成長空間
- 8 地平線自動駕駛方案解讀
- 9 封殺AI“照騙”,“淘寶們”終于不忍了?
- 10 優(yōu)必選:營收大增主靠小件,虧損繼續(xù)又逢關(guān)稅,能否乘機器人東風(fēng)翻身?