构建自定义CNN模型:识别COVID-19

磐创AI 2022-03-01

测试模型test

3098 字丨阅读本文需 12 分钟

本文让我们从头开始,通过训练和测试我们的自定义图像数据集,来构建我们自己的自定义CNN(卷积神经网络)模型。

我们将使用验证集方法来训练模型,从而将我们的数据集划分为训练、验证和测试数据集。

在结束时,你将能够为 COVID-19 构建你自己的自定义 CNN 模型,通过使用你自己的数据集进行训练来执行多类图像分类!

此外,我们还将通过获取其分类报告和混淆矩阵,在验证和测试数据集上彻底评估训练模型。此外,我们还将使用 Streamlit 创建一个漂亮而简单的前端,并将我们的模型与 Web 应用程序集成。

目前已经使用 Google Colab 进行所有实施。此外,已将数据集上传到项目的Google drive 。Streamlit Web 应用程序可以从 Google Colab 轻松启动。

那么,让我们开始吧!

目录

· 介绍

· 应用

· 执行

· 结论

介绍

首先,自定义数据集是你自己准备的数据集,就像你去外面玩并拍摄照片以收集你感兴趣的图像一样,或者从知名网站下载并使用开源图像数据集来获取数据集,例如 Kaggle、GitHub 等。

总而言之,它是你自己的数据集,其中你将所需类的图像存储在不同的文件夹中——每个类的文件夹。

在本文中,将解释如何使用 TensorFlow 在 CT 扫描的 COVID 多类数据集之一上为 COVID-19 构建 CNN 模型。可以直接从这里下载。现在,暂停并确保你下载数据集以跟随实施。

给定的 Kaggle 数据集包括患有新型 COVID-19、其他肺部疾病和健康患者的患者的胸部 CT 扫描图像。对于这三个类别中的每一个,都有多个患者,并且对于每个类别,都有相应的多个 CT 扫描图像。

我们将使用这些 CT 扫描图像来训练我们的 CNN 模型,以识别给定的 CT 扫描是 COVID 患者、患有除 COVID 以外的其他肺部疾病的患者,还是健康患者的 CT 扫描。该问题包括 3 类,即:COVID、健康和其他肺部疾病,简称为“其他”。

应用

我们知道,进行 RTPCR 检测 COVID 是有风险的,因为拭子检测通过鼻子到达喉咙,导致咳嗽,从而将病毒颗粒传播到空气中,从而危及卫生工作者的生命。

因此,研究人员表示,CT 扫描比此类拭子测试更安全。此外,建议在对 COVID 阳性患者进行 RTPCR 测试后进行 CT 扫描测试。

这就是我们现在正在做的项目可以证明对医学界有帮助的地方。

执行

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 图像预处理

每当我们处理图像数据时,图像预处理是第一步,也是最关键的一步。

在这里,我们将所有图像重新缩放为所需的大小(在这个项目中为 100×100)并将它们除以 255 进行标准化。

根据我们数据集的目录结构,如上一节所述,我们必须遍历文件夹 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 张图像,而不是跳过大量的图像。

下面的代码执行图像的标准化:

x=np.array(data)

x=x/255.0

现在,由于我们的自定义数据集在文件夹中有图像,我们如何获取标签?

使用 ImageDataGenerator 以及以下代码实现:

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

运行上面的代码,你将观察到以下索引已用于相应的类:

注意:在这一步的最后,所有的图像都将被调整到100×100,尽管它们是CT扫描,但它们已被作为彩色图像提供在选定的Kaggle数据集中。这就是为什么当我们在下一节中尝试查看 x_train,x_val 和 x_test 的形状时,会得到100x100x3。这里,3表示彩色图像(R-G-B)

Step-2:训练-测试-验证拆分

在这一步中,我们将数据集划分为训练集、测试集和验证集,以便使用验证集方法来训练我们的模型,以便在 COVID、健康或其他的 CT 扫描中进行分类。

我们可以使用传统的 sklearn 来实现。

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)

此外,使用以下代码查看每个数据集的大小:

x_train.shape,y_train.shape

x_val.shape,y_val.shape

x_test.shape,y_test.shape

从上面的代码中,你将观察到 3002 幅图像属于训练集,751 幅图像属于验证集,418 幅图像属于测试集。

Step-3 模型构建

现在,我们都准备好从头开始为 COVID-19 编码我们的 CNN 模型了。为此,我们只需要不断添加层,主要是 Conv2D 来提取特征,MaxPooling2D 来执行图像的下采样。

此外,还使用了 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 层的第一个参数是我们必须在其中进行大量操作以达到最佳模型。

你可以从 Keras 官方文档中了解更多关于 Conv2D、MaxPooling2D 和 BatchNormalization 的语法。

添加卷积层和最大池化层后,包含了 BatchNormalization 层,然后使用 Flatten() 函数添加了输入层。

这里没有隐藏层,因为它们对提高模型在训练期间的性能没有用处。

最后,添加了输出层,它确实给了我们最后的输出!Dense() 函数也用于相同的目的。它需要参数 3,因为我们有 3 个类别:COVID、健康和其他。

此外,这里使用的激活函数是 softmax 函数,因为这是一个多类问题。

这是模型架构。现在,在我们训练它之前,我们必须按如下方式编译它:

使用的优化器是常见的 Adam 优化器。由于所考虑的数据集的标签是分类的而不是独热编码的,我们必须选择稀疏分类交叉熵损失函数。

提前停止用于避免过度拟合。当它开始过度拟合时,它会停止训练我们的模型,而过拟合又通过验证损失的突然增加被识别出来。

#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

现在,让我们最终训练我们的自定义 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()

准确率和损失图如下:

验证数据集的分类报告和混淆矩阵:

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 模型是最好的。它显示了其他肺部疾病类别的平均表现。

然而,它对健康患者的表现相对较差。此外,我们的模型在验证数据集上显示出 79% 的准确率。

测试数据集的分类报告和混淆矩阵,这对我们的模型来说是全新的:

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)

它在测试数据集上显示了 75% 的准确度,与验证数据集的性能相似。

总的来说,我们可以得出结论,我们已经从头开始为 COVID-19 开发了一个现实的 CNN 模型。

现在让我们使用以下代码保存模型:

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

Step-5 构建 Streamlit Web 应用程序

在这一步中,我们将使用 Streamlit 创建一个前端,用户可以在其中上传胸部 CT 扫描的图像。单击“预测”按钮将输入图像预处理为 100×100,这是我们用于 COVID-19 的 CNN 模型的输入形状,然后将其发送到我们的模型。

为了检查我们的模型预测该图像是哪个类别,我们使用 np.argmax() 函数获得对应于最大值的索引,从而根据步骤 1 表中讨论的标签索引得出结论。

首先,我们必须安装 Streamlit 并导入 ngrok:

!pip install streamlit --quiet

!pip install pyngrok==4.1.1 --quiet

from pyngrok import ngrok

然后是实际代码。

这里,我们主要加载保存的模型——h5文件,并使用它进行预测。模型文件的名称是 model-recent.h5。可以选择直接从本地系统上传图像并检查其类别 - 如果 CT 扫描是 COVID 或健康或其他肺部疾病。

st. button(‘Predict’)  创建一个写有“Predict”的按钮,并在用户单击按钮时返回 True。st.title() 使其参数中的文本以深色粗体显示。

这些是要讨论的一些 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 应用程序应如下所示。

结论

因此,我们使用我们的数据集成功构建并训练了我们自己的 COVID-19 CNN 模型!相同的方法可用于两个或更多类。你所要做的就是更改输出层或模型架构的最后一层中的类数量。

免责声明:凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处本网。非本网作品均来自其他媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如您发现有任何侵权内容,请依照下方联系方式进行沟通,我们将第一时间进行处理。

0赞 好资讯,需要你的鼓励
来自:磐创AI
0

参与评论

登录后参与讨论 0/1000

为你推荐

加载中...