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

構(gòu)建自定義CNN模型:識(shí)別COVID-19

本文讓我們從頭開始,通過訓(xùn)練和測(cè)試我們的自定義圖像數(shù)據(jù)集,來構(gòu)建我們自己的自定義CNN(卷積神經(jīng)網(wǎng)絡(luò))模型。

我們將使用驗(yàn)證集方法來訓(xùn)練模型,從而將我們的數(shù)據(jù)集劃分為訓(xùn)練、驗(yàn)證和測(cè)試數(shù)據(jù)集。

在結(jié)束時(shí),你將能夠?yàn)?COVID-19 構(gòu)建你自己的自定義 CNN 模型,通過使用你自己的數(shù)據(jù)集進(jìn)行訓(xùn)練來執(zhí)行多類圖像分類!

此外,我們還將通過獲取其分類報(bào)告和混淆矩陣,在驗(yàn)證和測(cè)試數(shù)據(jù)集上徹底評(píng)估訓(xùn)練模型。此外,我們還將使用 Streamlit 創(chuàng)建一個(gè)漂亮而簡單的前端,并將我們的模型與 Web 應(yīng)用程序集成。

目前已經(jīng)使用 Google Colab 進(jìn)行所有實(shí)施。此外,已將數(shù)據(jù)集上傳到項(xiàng)目的Google drive 。Streamlit Web 應(yīng)用程序可以從 Google Colab 輕松啟動(dòng)。

那么,讓我們開始吧!

目錄

· 介紹

· 應(yīng)用

· 執(zhí)行

· 結(jié)論

介紹

首先,自定義數(shù)據(jù)集是你自己準(zhǔn)備的數(shù)據(jù)集,就像你去外面玩并拍攝照片以收集你感興趣的圖像一樣,或者從知名網(wǎng)站下載并使用開源圖像數(shù)據(jù)集來獲取數(shù)據(jù)集,例如 Kaggle、GitHub 等。

總而言之,它是你自己的數(shù)據(jù)集,其中你將所需類的圖像存儲(chǔ)在不同的文件夾中——每個(gè)類的文件夾。

在本文中,將解釋如何使用 TensorFlow 在 CT 掃描的 COVID 多類數(shù)據(jù)集之一上為 COVID-19 構(gòu)建 CNN 模型。可以直接從這里下載,F(xiàn)在,暫停并確保你下載數(shù)據(jù)集以跟隨實(shí)施。

給定的 Kaggle 數(shù)據(jù)集包括患有新型 COVID-19、其他肺部疾病和健康患者的患者的胸部 CT 掃描圖像。對(duì)于這三個(gè)類別中的每一個(gè),都有多個(gè)患者,并且對(duì)于每個(gè)類別,都有相應(yīng)的多個(gè) CT 掃描圖像。

我們將使用這些 CT 掃描圖像來訓(xùn)練我們的 CNN 模型,以識(shí)別給定的 CT 掃描是 COVID 患者、患有除 COVID 以外的其他肺部疾病的患者,還是健康患者的 CT 掃描。該問題包括 3 類,即:COVID、健康和其他肺部疾病,簡稱為“其他”。

應(yīng)用

我們知道,進(jìn)行 RTPCR 檢測(cè) COVID 是有風(fēng)險(xiǎn)的,因?yàn)槭米訖z測(cè)通過鼻子到達(dá)喉嚨,導(dǎo)致咳嗽,從而將病毒顆粒傳播到空氣中,從而危及衛(wèi)生工作者的生命。

因此,研究人員表示,CT 掃描比此類拭子測(cè)試更安全。此外,建議在對(duì) COVID 陽性患者進(jìn)行 RTPCR 測(cè)試后進(jìn)行 CT 掃描測(cè)試。

這就是我們現(xiàn)在正在做的項(xiàng)目可以證明對(duì)醫(yī)學(xué)界有幫助的地方。

執(zhí)行

Step-1:圖像預(yù)處理

Step-2:訓(xùn)練-測(cè)試-驗(yàn)證拆分

Step-3:模型構(gòu)建

Step-4:模型評(píng)估

Step-5:構(gòu)建 Streamlit Web 應(yīng)用程序

首先,讓我們導(dǎo)入所有需要的包,如下所示:

from tensorflow.keras.layers import Input, Lambda, Dense, Flatten,Dropout,Conv2D,MaxPooling2D

from tensorflow.keras.models import Model

from tensorflow.keras.preprocessing import image

from sklearn.metrics import accuracy_score,classification_report,confusion_matrix

from tensorflow.keras.preprocessing.image import ImageDataGenerator

from sklearn.model_selection import train_test_split

from tensorflow.keras.models import Sequential

import numpy as np

import pandas as pd

import os

import cv2

import matplotlib.pyplot as plt

Step-1 圖像預(yù)處理

每當(dāng)我們處理圖像數(shù)據(jù)時(shí),圖像預(yù)處理是第一步,也是最關(guān)鍵的一步。

在這里,我們將所有圖像重新縮放為所需的大。ㄔ谶@個(gè)項(xiàng)目中為 100×100)并將它們除以 255 進(jìn)行標(biāo)準(zhǔn)化。

根據(jù)我們數(shù)據(jù)集的目錄結(jié)構(gòu),如上一節(jié)所述,我們必須遍歷文件夾 2(患者文件夾)中存在的每個(gè)圖像,該圖像進(jìn)一步存在于文件夾 1(類別文件夾:COVID、健康或其他)。

因此,相同的代碼是這樣的:

# re-size all the images to this

IMAGE_SIZE = (100,100)

path="/content/drive/MyDrive/MLH Project/dataset"

data=[]

c=0

for folder in os.listdir(path):

  sub_path=path+"/"+folder

  for folder2 in os.listdir(sub_path):

    sub_path2=sub_path+"/"+folder2

    for img in os.listdir(sub_path2):

      image_path=sub_path2+"/"+img        

      img_arr=cv2.imread(image_path)

      try:

        img_arr=cv2.resize(img_arr,IMAGE_SIZE)

        data.a(chǎn)ppend(img_arr)

      except:

        c+=1

        continue

print("Number of images skipped= ",c)

注意:在案例中可能會(huì)跳過兩個(gè)圖像。我們可以忽略它們,因?yàn)橹皇?2 張圖像,而不是跳過大量的圖像。

下面的代碼執(zhí)行圖像的標(biāo)準(zhǔn)化:

x=np.a(chǎn)rray(data)

x=x/255.0

現(xiàn)在,由于我們的自定義數(shù)據(jù)集在文件夾中有圖像,我們?nèi)绾潍@取標(biāo)簽?

使用 ImageDataGenerator 以及以下代碼實(shí)現(xiàn):

datagen = ImageDataGenerator(rescale = 1./255)

dataset = datagen.flow_from_directory(path,
                                     target_size = IMAGE_SIZE,
                                     batch_size = 32,
                                     class_mode = 'sparse')

此外,要注意類的索引并將這些類分配為標(biāo)簽,請(qǐng)使用以下代碼:

dataset.class_indices

y=dataset.classes

y.shape

運(yùn)行上面的代碼,你將觀察到以下索引已用于相應(yīng)的類:

image.png

注意:在這一步的最后,所有的圖像都將被調(diào)整到100×100,盡管它們是CT掃描,但它們已被作為彩色圖像提供在選定的Kaggle數(shù)據(jù)集中。這就是為什么當(dāng)我們?cè)谙乱还?jié)中嘗試查看 x_train,x_val 和 x_test 的形狀時(shí),會(huì)得到100x100x3。這里,3表示彩色圖像(R-G-B)

Step-2:訓(xùn)練-測(cè)試-驗(yàn)證拆分

在這一步中,我們將數(shù)據(jù)集劃分為訓(xùn)練集、測(cè)試集和驗(yàn)證集,以便使用驗(yàn)證集方法來訓(xùn)練我們的模型,以便在 COVID、健康或其他的 CT 掃描中進(jìn)行分類。

我們可以使用傳統(tǒng)的 sklearn 來實(shí)現(xiàn)。

x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.1)

x_train,x_val,y_train,y_val=train_test_split(x_train,y_train,test_size=0.2)

此外,使用以下代碼查看每個(gè)數(shù)據(jù)集的大小:

x_train.shape,y_train.shape

x_val.shape,y_val.shape

x_test.shape,y_test.shape

從上面的代碼中,你將觀察到 3002 幅圖像屬于訓(xùn)練集,751 幅圖像屬于驗(yàn)證集,418 幅圖像屬于測(cè)試集。

Step-3 模型構(gòu)建

現(xiàn)在,我們都準(zhǔn)備好從頭開始為 COVID-19 編碼我們的 CNN 模型了。為此,我們只需要不斷添加層,主要是 Conv2D 來提取特征,MaxPooling2D 來執(zhí)行圖像的下采樣。

此外,還使用了 BatchNormalization 層來提高模型在訓(xùn)練和驗(yàn)證準(zhǔn)確性方面的性能。

因此,我們可以編寫我們自己的 CNN 模型,如下所示:

model=Sequential()

#covolution layer

model.a(chǎn)dd(Conv2D(32,(3,3),activation='relu',input_shape=(100,100,3)))

#pooling layer

model.a(chǎn)dd(MaxPooling2D(2,2))

model.a(chǎn)dd(BatchNormalization())

#covolution layer

model.a(chǎn)dd(Conv2D(32,(3,3),activation='relu'))

#pooling layer

model.a(chǎn)dd(MaxPooling2D(2,2))

model.a(chǎn)dd(BatchNormalization())

#covolution layer

model.a(chǎn)dd(Conv2D(64,(3,3),activation='relu'))

#pooling layer

model.a(chǎn)dd(MaxPooling2D(2,2))

model.a(chǎn)dd(BatchNormalization())

#covolution layer

model.a(chǎn)dd(Conv2D(64,(3,3),activation='relu'))

#pooling layer

model.a(chǎn)dd(MaxPooling2D(2,2))

model.a(chǎn)dd(BatchNormalization())

#i/p layer

model.a(chǎn)dd(Flatten())

#o/p layer

model.a(chǎn)dd(Dense(3,activation='softmax'))

model.summary()

卷積神經(jīng)網(wǎng)絡(luò)由幾個(gè)卷積層和池化層組成。我添加了四個(gè) Conv2D 和 MaxPooling 層。Conv2D 層的第一個(gè)參數(shù)是我們必須在其中進(jìn)行大量操作以達(dá)到最佳模型。

你可以從 Keras 官方文檔中了解更多關(guān)于 Conv2D、MaxPooling2D 和 BatchNormalization 的語法。

添加卷積層和最大池化層后,包含了 BatchNormalization 層,然后使用 Flatten() 函數(shù)添加了輸入層。

這里沒有隱藏層,因?yàn)樗鼈儗?duì)提高模型在訓(xùn)練期間的性能沒有用處。

最后,添加了輸出層,它確實(shí)給了我們最后的輸出!Dense() 函數(shù)也用于相同的目的。它需要參數(shù) 3,因?yàn)槲覀冇?3 個(gè)類別:COVID、健康和其他。

此外,這里使用的激活函數(shù)是 softmax 函數(shù),因?yàn)檫@是一個(gè)多類問題。

這是模型架構(gòu),F(xiàn)在,在我們訓(xùn)練它之前,我們必須按如下方式編譯它:

使用的優(yōu)化器是常見的 Adam 優(yōu)化器。由于所考慮的數(shù)據(jù)集的標(biāo)簽是分類的而不是獨(dú)熱編碼的,我們必須選擇稀疏分類交叉熵?fù)p失函數(shù)。

提前停止用于避免過度擬合。當(dāng)它開始過度擬合時(shí),它會(huì)停止訓(xùn)練我們的模型,而過擬合又通過驗(yàn)證損失的突然增加被識(shí)別出來。

#compile model:

model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])

提前停止可用于避免過度擬合。這樣做是因?yàn)槲覀儾恢牢覀兊哪P捅仨氂?xùn)練多少個(gè) epoch。

from tensorflow.keras.callbacks import EarlyStopping

early_stop=EarlyStopping(monitor='val_loss',mode='min',verbose=1,patience=5)

#Early stopping to avoid overfitting of model

現(xiàn)在,讓我們最終訓(xùn)練我們的自定義 CNN 模型,比如 30 個(gè) epoch:

history=model.fit(x_train,y_train,validation_data=(x_val,y_val),epochs=30,callbacks=[early_stop],shuffle=True)

在第 16 個(gè) epoch 遇到了提前停止,因此模型只訓(xùn)練了 16 個(gè) epoch,在結(jié)束時(shí)它顯示出 100% 的訓(xùn)練準(zhǔn)確度和 78.83% 的驗(yàn)證準(zhǔn)確度。

Step-4 模型評(píng)估

可視化我們的模型訓(xùn)練的最佳方法是使用損失和準(zhǔn)確度圖。

以下代碼可用于獲取我們訓(xùn)練的模型的損失和準(zhǔn)確度圖:

#loss graph

plt.plot(history.history['loss'],label='train loss')

plt.plot(history.history['val_loss'],label='val loss')

plt.legend()

plt.savefig('loss-graph.png')

plt.show()

#accuracies

plt.plot(history.history['accuracy'], label='train acc')

plt.plot(history.history['val_accuracy'], label='val acc')

plt.legend()

plt.savefig('acc-graph.png')

plt.show()

準(zhǔn)確率和損失圖如下:

驗(yàn)證數(shù)據(jù)集的分類報(bào)告和混淆矩陣:

y_val_pred=model.predict(x_val)

y_val_pred=np.a(chǎn)rgmax(y_val_pred,axis=1)

print(classification_report(y_val_pred,y_val))

confusion_matrix(y_val_pred,y_val)

因此,可以清楚地得出結(jié)論,我們用于 COVID CT 掃描的 CNN 模型是最好的。它顯示了其他肺部疾病類別的平均表現(xiàn)。

然而,它對(duì)健康患者的表現(xiàn)相對(duì)較差。此外,我們的模型在驗(yàn)證數(shù)據(jù)集上顯示出 79% 的準(zhǔn)確率。

測(cè)試數(shù)據(jù)集的分類報(bào)告和混淆矩陣,這對(duì)我們的模型來說是全新的:

y_pred=model.predict(x_test)

y_pred=np.a(chǎn)rgmax(y_pred,axis=1)

print(classification_report(y_pred,y_test))

confusion_matrix(y_pred,y_test)

它在測(cè)試數(shù)據(jù)集上顯示了 75% 的準(zhǔn)確度,與驗(yàn)證數(shù)據(jù)集的性能相似。

總的來說,我們可以得出結(jié)論,我們已經(jīng)從頭開始為 COVID-19 開發(fā)了一個(gè)現(xiàn)實(shí)的 CNN 模型。

現(xiàn)在讓我們使用以下代碼保存模型:

model.save('/content/drive/MyDrive/MLH Project/model-recent.h5')

Step-5 構(gòu)建 Streamlit Web 應(yīng)用程序

在這一步中,我們將使用 Streamlit 創(chuàng)建一個(gè)前端,用戶可以在其中上傳胸部 CT 掃描的圖像。單擊“預(yù)測(cè)”按鈕將輸入圖像預(yù)處理為 100×100,這是我們用于 COVID-19 的 CNN 模型的輸入形狀,然后將其發(fā)送到我們的模型。

為了檢查我們的模型預(yù)測(cè)該圖像是哪個(gè)類別,我們使用 np.a(chǎn)rgmax() 函數(shù)獲得對(duì)應(yīng)于最大值的索引,從而根據(jù)步驟 1 表中討論的標(biāo)簽索引得出結(jié)論。

首先,我們必須安裝 Streamlit 并導(dǎo)入 ngrok:

!pip install streamlit --quiet

!pip install pyngrok==4.1.1 --quiet

from pyngrok import ngrok

然后是實(shí)際代碼。

這里,我們主要加載保存的模型——h5文件,并使用它進(jìn)行預(yù)測(cè)。模型文件的名稱是 model-recent.h5。可以選擇直接從本地系統(tǒng)上傳圖像并檢查其類別 - 如果 CT 掃描是 COVID 或健康或其他肺部疾病。

st. button(‘Predict’)  創(chuàng)建一個(gè)寫有“Predict”的按鈕,并在用戶單擊按鈕時(shí)返回 True。st.title() 使其參數(shù)中的文本以深色粗體顯示。

這些是要討論的一些 Streamlit 功能。

%%writefile app.py

import streamlit as st

import tensorflow as tf

import numpy as np

from PIL import Image # Strreamlit works with PIL library very easily for Images

import cv2

model_path='/content/drive/MyDrive/MLH Project/model-recent.h5'

st.title("COVID-19 Identification Using CT Scan")

upload = st.file_uploader('Upload a CT scan image')

if upload is not None:

file_bytes = np.a(chǎn)sarray(bytearray(upload.read()), dtype=np.uint8)

opencv_image = cv2.imdecode(file_bytes, 1)

opencv_image = cv2.cvtColor(opencv_image,cv2.COLOR_BGR2RGB)

# Color from BGR to RGB

img = Image.open(upload)

st.image(img,caption='Uploaded Image',width=300)

if(st.button('Predict')):

  model = tf.keras.models.load_model(model_path)

  x = cv2.resize(opencv_image,(100,100))

  x = np.expand_dims(x,axis=0)    

  y = model.predict(x)

  ans=np.a(chǎn)rgmax(y,axis=1)

  if(ans==0):

    st.title('COVID')

  elif(ans==1):

    st.title('Healthy')

  else:

    st.title('Other Pulmonary Disorder')

最后,從以下位置獲取 Web 應(yīng)用程序的 URL:

!nohup streamlit run app.py &

url = ngrok.connect(port='8501')

url

將此 URL 粘貼到 Chrome 網(wǎng)絡(luò)瀏覽器中以查看我們漂亮的應(yīng)用程序。

結(jié)果

使用瀏覽按鈕上傳圖像然后單擊預(yù)測(cè)按鈕后,你的 Web 應(yīng)用程序應(yīng)如下所示。

結(jié)論

因此,我們使用我們的數(shù)據(jù)集成功構(gòu)建并訓(xùn)練了我們自己的 COVID-19 CNN 模型!相同的方法可用于兩個(gè)或更多類。你所要做的就是更改輸出層或模型架構(gòu)的最后一層中的類數(shù)量。

       原文標(biāo)題 : 構(gòu)建自定義CNN模型:識(shí)別COVID-19

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

發(fā)表評(píng)論

0條評(píng)論,0人參與

請(qǐng)輸入評(píng)論內(nèi)容...

請(qǐng)輸入評(píng)論/評(píng)論長度6~500個(gè)字

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

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

暫無評(píng)論

暫無評(píng)論

人工智能 獵頭職位 更多
掃碼關(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)