訂閱
糾錯
加入自媒體

構建自定義CNN模型:識別COVID-19

本文讓我們從頭開始,通過訓練和測試我們的自定義圖像數(shù)據(jù)集,來構建我們自己的自定義CNN(卷積神經網絡)模型。

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

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

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

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

那么,讓我們開始吧!

目錄

· 介紹

· 應用

· 執(zhí)行

· 結論

介紹

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

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

在本文中,將解釋如何使用 TensorFlow 在 CT 掃描的 COVID 多類數(shù)據(jù)集之一上為 COVID-19 構建 CNN 模型?梢灾苯訌倪@里下載。現(xiàn)在,暫停并確保你下載數(shù)據(jù)集以跟隨實施。

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

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

應用

我們知道,進行 RTPCR 檢測 COVID 是有風險的,因為拭子檢測通過鼻子到達喉嚨,導致咳嗽,從而將病毒顆粒傳播到空氣中,從而危及衛(wèi)生工作者的生命。

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

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

執(zhí)行

Step-1:圖像預處理

Step-2:訓練-測試-驗證拆分

Step-3:模型構建

Step-4:模型評估

Step-5:構建 Streamlit Web 應用程序

首先,讓我們導入所有需要的包,如下所示:

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 圖像預處理

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

在這里,我們將所有圖像重新縮放為所需的大小(在這個項目中為 100×100)并將它們除以 255 進行標準化。

根據(jù)我們數(shù)據(jù)集的目錄結構,如上一節(jié)所述,我們必須遍歷文件夾 2(患者文件夾)中存在的每個圖像,該圖像進一步存在于文件夾 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.append(img_arr)

      except:

        c+=1

        continue

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

注意:在案例中可能會跳過兩個圖像。我們可以忽略它們,因為只是 2 張圖像,而不是跳過大量的圖像。

下面的代碼執(zhí)行圖像的標準化:

x=np.array(data)

x=x/255.0

現(xiàn)在,由于我們的自定義數(shù)據(jù)集在文件夾中有圖像,我們如何獲取標簽?

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

datagen = ImageDataGenerator(rescale = 1./255)

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

此外,要注意類的索引并將這些類分配為標簽,請使用以下代碼:

dataset.class_indices

y=dataset.classes

y.shape

運行上面的代碼,你將觀察到以下索引已用于相應的類:

image.png

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

Step-2:訓練-測試-驗證拆分

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

我們可以使用傳統(tǒng)的 sklearn 來實現(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)

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

x_train.shape,y_train.shape

x_val.shape,y_val.shape

x_test.shape,y_test.shape

從上面的代碼中,你將觀察到 3002 幅圖像屬于訓練集,751 幅圖像屬于驗證集,418 幅圖像屬于測試集。

Step-3 模型構建

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

此外,還使用了 BatchNormalization 層來提高模型在訓練和驗證準確性方面的性能。

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

model=Sequential()

#covolution layer

model.add(Conv2D(32,(3,3),activation='relu',input_shape=(100,100,3)))

#pooling layer

model.add(MaxPooling2D(2,2))

model.add(BatchNormalization())

#covolution layer

model.add(Conv2D(32,(3,3),activation='relu'))

#pooling layer

model.add(MaxPooling2D(2,2))

model.add(BatchNormalization())

#covolution layer

model.add(Conv2D(64,(3,3),activation='relu'))

#pooling layer

model.add(MaxPooling2D(2,2))

model.add(BatchNormalization())

#covolution layer

model.add(Conv2D(64,(3,3),activation='relu'))

#pooling layer

model.add(MaxPooling2D(2,2))

model.add(BatchNormalization())

#i/p layer

model.add(Flatten())

#o/p layer

model.add(Dense(3,activation='softmax'))

model.summary()

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

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

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

這里沒有隱藏層,因為它們對提高模型在訓練期間的性能沒有用處。

最后,添加了輸出層,它確實給了我們最后的輸出!Dense() 函數(shù)也用于相同的目的。它需要參數(shù) 3,因為我們有 3 個類別:COVID、健康和其他。

此外,這里使用的激活函數(shù)是 softmax 函數(shù),因為這是一個多類問題。

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

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

提前停止用于避免過度擬合。當它開始過度擬合時,它會停止訓練我們的模型,而過擬合又通過驗證損失的突然增加被識別出來。

#compile model:

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

提前停止可用于避免過度擬合。這樣做是因為我們不知道我們的模型必須訓練多少個 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)在,讓我們最終訓練我們的自定義 CNN 模型,比如 30 個 epoch:

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

在第 16 個 epoch 遇到了提前停止,因此模型只訓練了 16 個 epoch,在結束時它顯示出 100% 的訓練準確度和 78.83% 的驗證準確度。

Step-4 模型評估

可視化我們的模型訓練的最佳方法是使用損失和準確度圖。

以下代碼可用于獲取我們訓練的模型的損失和準確度圖:

#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()

準確率和損失圖如下:

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

y_val_pred=model.predict(x_val)

y_val_pred=np.argmax(y_val_pred,axis=1)

print(classification_report(y_val_pred,y_val))

confusion_matrix(y_val_pred,y_val)

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

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

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

y_pred=model.predict(x_test)

y_pred=np.argmax(y_pred,axis=1)

print(classification_report(y_pred,y_test))

confusion_matrix(y_pred,y_test)

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

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

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

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

Step-5 構建 Streamlit Web 應用程序

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

為了檢查我們的模型預測該圖像是哪個類別,我們使用 np.argmax() 函數(shù)獲得對應于最大值的索引,從而根據(jù)步驟 1 表中討論的標簽索引得出結論。

首先,我們必須安裝 Streamlit 并導入 ngrok:

!pip install streamlit --quiet

!pip install pyngrok==4.1.1 --quiet

from pyngrok import ngrok

然后是實際代碼。

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

st. button(‘Predict’)  創(chuàng)建一個寫有“Predict”的按鈕,并在用戶單擊按鈕時返回 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.asarray(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.argmax(y,axis=1)

  if(ans==0):

    st.title('COVID')

  elif(ans==1):

    st.title('Healthy')

  else:

    st.title('Other Pulmonary Disorder')

最后,從以下位置獲取 Web 應用程序的 URL:

!nohup streamlit run app.py &

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

url

將此 URL 粘貼到 Chrome 網絡瀏覽器中以查看我們漂亮的應用程序。

結果

使用瀏覽按鈕上傳圖像然后單擊預測按鈕后,你的 Web 應用程序應如下所示。

結論

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

       原文標題 : 構建自定義CNN模型:識別COVID-19

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

發(fā)表評論

0條評論,0人參與

請輸入評論內容...

請輸入評論/評論長度6~500個字

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

暫無評論

暫無評論

人工智能 獵頭職位 更多
掃碼關注公眾號
OFweek人工智能網
獲取更多精彩內容
文章糾錯
x
*文字標題:
*糾錯內容:
聯(lián)系郵箱:
*驗 證 碼:

粵公網安備 44030502002758號