神经网络|构建自定义 CNN 模型(识别 COVID-19)

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

我们将使用验证集方法来训练模型,从而将我们的数据集划分为训练、验证和测试数据集。
在结束时,你将能够为 COVID-19 构建你自己的自定义 CNN 模型,通过使用你自己的数据集进行训练来执行多类图像分类!
此外,我们还将通过获取其分类报告和混淆矩阵,在验证和测试数据集上彻底评估训练模型。此外,我们还将使用 Streamlit 创建一个漂亮而简单的前端,并将我们的模型与 Web 应用程序集成。
目前已经使用 Google Colab 进行所有实施。此外,已将数据集上传到项目的Google drive 。Streamlit Web 应用程序可以从 Google Colab 轻松启动。
那么,让我们开始吧!
目录

  • 介绍
  • 应用
  • 执行
  • 结论
介绍
神经网络|构建自定义 CNN 模型(识别 COVID-19)
文章图片
首先,自定义数据集是你自己准备的数据集,就像你去外面玩并拍摄照片以收集你感兴趣的图像一样,或者从知名网站下载并使用开源图像数据集来获取数据集,例如 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=https://www.it610.com/article/[] 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

运行上面的代码,你将观察到以下索引已用于相应的类:
索引
0 冠状病毒
1 健康
2 其他
注意:在这一步的最后,所有的图像都将被调整到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() 函数添加了输入层。
【神经网络|构建自定义 CNN 模型(识别 COVID-19)】这里没有隐藏层,因为它们对提高模型在训练期间的性能没有用处。
最后,添加了输出层,它确实给了我们最后的输出!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=https://www.it610.com/article/(x_val,y_val),epochs=30,callbacks=[early_stop],shuffle=True)

在第 16 个 epoch 遇到了提前停止,因此模型只训练了 16 个 epoch,在结束时它显示出 100% 的训练准确度和 78.83% 的验证准确度。
神经网络|构建自定义 CNN 模型(识别 COVID-19)
文章图片
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()

准确率和损失图如下:
神经网络|构建自定义 CNN 模型(识别 COVID-19)
文章图片

神经网络|构建自定义 CNN 模型(识别 COVID-19)
文章图片

验证数据集的分类报告和混淆矩阵:
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))

神经网络|构建自定义 CNN 模型(识别 COVID-19)
文章图片
confusion_matrix(y_val_pred,y_val)

神经网络|构建自定义 CNN 模型(识别 COVID-19)
文章图片
因此,可以清楚地得出结论,我们用于 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)

神经网络|构建自定义 CNN 模型(识别 COVID-19)
文章图片

神经网络|构建自定义 CNN 模型(识别 COVID-19)
文章图片
它在测试数据集上显示了 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 应用程序应如下所示。
神经网络|构建自定义 CNN 模型(识别 COVID-19)
文章图片

神经网络|构建自定义 CNN 模型(识别 COVID-19)
文章图片
结论

因此,我们使用我们的数据集成功构建并训练了我们自己的 COVID-19 CNN 模型!相同的方法可用于两个或更多类。你所要做的就是更改输出层或模型架构的最后一层中的类数量。
☆ END ☆
如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。
↓扫描二维码添加小编↓
神经网络|构建自定义 CNN 模型(识别 COVID-19)
文章图片

    推荐阅读