訂閱
糾錯(cuò)
加入自媒體

如何使用深度學(xué)習(xí)進(jìn)行腦腫瘤檢測和定位?

問題陳述

通過使用 Kaggle 的 MRI 數(shù)據(jù)集的圖像分割來預(yù)測和定位腦腫瘤。

將本文分為兩個(gè)部分,因?yàn)槲覀儗⑨槍ο嗤臄?shù)據(jù)集,不同的任務(wù)訓(xùn)練兩個(gè)深度學(xué)習(xí)模型。這部分的模型是一個(gè)分類模型,它會(huì)從 MRI 圖像中檢測腫瘤,然后如果存在腫瘤,我們將在本系列的下一部分中進(jìn)一步定位有腫瘤的大腦部分。

先決條件

深度學(xué)習(xí)

讓我們?nèi)胧褂?python 的實(shí)現(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ù)幀,對其進(jìn)行特定的操作。# 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ù)幀詳細(xì)信息。brain_df.info()

數(shù)據(jù)集信息 |  腦腫瘤檢測brain_df.head(5)

患者 ID:每條記錄的患者 ID(dtype:對象)圖像路徑:MRI 圖像的路徑(dtype:對象)蒙版路徑:對應(yīng)圖像蒙版的路徑(dtype:Object)蒙版:有兩個(gè)值:0 和 1,具體取決于蒙版的圖像。(數(shù)據(jù)類型:int64)計(jì)算每個(gè)類的值。brain_df['mask'].value_counts()

隨機(jī)顯示數(shù)據(jù)集中的 MRI 圖像。image = cv2.imread(brain_df.image_path[1301])
plt.imshow(image)

image_path 存儲(chǔ)大腦 MRI 的路徑,因此我們可以使用 matplotlib 顯示圖像。提示:上圖中的綠色部分可以認(rèn)為是腫瘤。此外,顯示相應(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,因?yàn)樗恍枰M(jìn)一步處理。# 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)換為字符串格式,因?yà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)在每個(gè)特征都將數(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 擴(kuò)充更多數(shù)據(jù)。ImageDataGenerator 通過實(shí)時(shí)數(shù)據(jù)增強(qiáng)生成批量的張量圖像數(shù)據(jù)。

我們將從訓(xùn)練數(shù)據(jù)創(chuàng)建一個(gè) train_generator 和 validation_generator,并從測試數(shù)據(jù)創(chuàng)建一個(gè) 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 模型的概念,它們將用于進(jìn)一步訓(xùn)練模型。顧名思義,遷移學(xué)習(xí)是一種在訓(xùn)練中使用預(yù)訓(xùn)練模型的技術(shù)。你可以在此預(yù)訓(xùn)練模型的基礎(chǔ)上構(gòu)建模型。這是一個(gè)可以幫助你減少開發(fā)時(shí)間并提高性能的過程。ResNet(殘差網(wǎng)絡(luò))是在 ImageNet 數(shù)據(jù)集上訓(xùn)練的 ANN,可用于在其之上訓(xùn)練模型。ResNet50 是 ResNet 模型的變體,它有 48 個(gè)卷積層以及 1 個(gè) MaxPool 和 1 個(gè)平均池層。在這里,我們使用的是 ResNet50 模型,它是一種遷移學(xué)習(xí)模型。使用它,我們將進(jìn)一步添加更多層來構(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)重不變,以便它不會(huì)進(jìn)一步更新。這將避免在進(jìn)一步訓(xùn)練期間破壞任何信息。# freeze the model weights
for layer in basemodel.layers:
 layers.trainable = False
現(xiàn)在,如上所述,我們將在 ResNet50 層的頂部添加更多層。這些層會(huì)學(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ò)層;旧,它接受輸入并計(jì)算輸出 = activation(dot(input, kernel) + bias)dropout 層可以防止模型過擬合。它在訓(xùn)練過程中將隱藏層的輸入單元隨機(jī)設(shè)置為 0。編譯上面構(gòu)建的模型。Compile 定義了損失函數(shù)、優(yōu)化器和指標(biāo)。# compile the model
model.compile(loss = 'categorical_crossentropy', optimizer='adam', metrics= ["accuracy"])
執(zhí)行提前停止以保存具有最小驗(yàn)證損失的最佳模型。提前停止執(zhí)行大量訓(xùn)練時(shí)期,一旦模型性能在驗(yàn)證數(shù)據(jù)集上沒有進(jìn)一步提高就停止訓(xùn)練。ModelCheckpoint 回調(diào)與使用 model.fit() 的訓(xùn)練一起使用,以在某個(gè)時(shí)間間隔保存權(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)
測量模型的準(zhǔn)確性。# Obtain the accuracy of the model
from sklearn.metrics import accuracy_score
accuracy = accuracy_score(original, predict)
accuracy

打印分類報(bào)告。from sklearn.metrics import classification_report
report = classification_report(original, predict, labels = [0,1])
print(report)


聲明: 本文由入駐維科號(hào)的作者撰寫,觀點(diǎn)僅代表作者本人,不代表OFweek立場。如有侵權(quán)或其他問題,請聯(lián)系舉報(bào)。

發(fā)表評論

0條評論,0人參與

請輸入評論內(nèi)容...

請輸入評論/評論長度6~500個(gè)字

您提交的評論過于頻繁,請輸入驗(yàn)證碼繼續(xù)

  • 看不清,點(diǎn)擊換一張  刷新

暫無評論

暫無評論

人工智能 獵頭職位 更多
掃碼關(guān)注公眾號(hào)
OFweek人工智能網(wǎng)
獲取更多精彩內(nèi)容
文章糾錯(cuò)
x
*文字標(biāo)題:
*糾錯(cuò)內(nèi)容:
聯(lián)系郵箱:
*驗(yàn) 證 碼:

粵公網(wǎng)安備 44030502002758號(hào)