1.摘要
COVID-19是一种由肺炎感染导致的传染病,截至2020年4月底,已在全世界造成23万多人死亡。在短短几个月内,由于其高传播率,已在全球感染了400多万人。因此,许多政府已尽最大努力提高医院的诊断和确诊能力,以便尽早发现该疾病。然而,在大多数情况下,该检测结果仅在一两天后才能够反馈,这直接增加了由于延迟诊断而导致的疾病传播问题。因此,可以借助X射线等现有工具快速筛查方法帮助减轻大规模诊断测试的负担。胸部 X 射线检测是诊断肺炎症状的最佳方式之一,而肺炎症状也是 COVID-19 的主要症状之一。因此,本文提出了一种轻量级深度学习模型,以准确筛查COVID-19肺炎的可能性。该模型基于14层卷积神经网络(CNN)和改进的空间金字塔池化模块(SPP),通过使用SPP的并行池层替换原始网络的最后几层来嵌入多尺度特征向量,实现的模型对各种输入尺度图像具有鲁棒性,能够适应各种大小的X射线图像,并捕获其中的图像特征。所构建的模型结构具有对多尺度输入图像进行特征提取的能力,使其能够识别各种严重程度的COVID-19疾病。根据实验结果,所提出的SPP-COVID-Net得到了0.946的精度,最后本文将该模型应用到系统页面,做了一个可用于分类不同类型肺炎的轻量级检测网站,医生可以立即运行,以便自动执行筛查过程。
2.数据集介绍
实验中将要使用与网上公开数据集相同的数据用于验证SPP-COVID-Net模型的性能。该数据集是基于来自不同国家的在线数据库构建的。在完整数据集中包括219例确诊阳性COVID-19患者的胸部X光图像,1341张正常人肺部图像和1345张其他类型的病毒性肺炎图像。每个X射线图像的分辨率为1024*1024。其数据展示如下所示(完整源码\数据联系525894654):
3.模型介绍
SPP-COVID-19模型是一种用于肺炎类型的检测模型,即将检测任务转换为分类任务,可将X射线图像分为三类(COVID-19,正常和其他类型的病毒性肺炎)。该网络由14层普通CNN和一个SPP模块组成。完整的网络架构如图所示,前14层传统卷积池化之后将进行SPP池化操作,SPP 模块不执行卷积操作,而是仅使用多个最大池化结构进行特征的下采样。在实验中,执行三个池化操作,池化窗口大小为4x4,6x6和7x7,每个池化输出将被展平为一个特征向量,然后将每个特征向量连接成一个长向量。最后,SPP-COVID-19模型使用SoftMax激活函数将图像分类到各自的类中。模型参数结构如下所示:
实现代码:
def SPPCovidNet(class_no,input_height,input_width):
input_images=tf.keras.layers.Input(shape=(input_height,input_width,3))
x = tf.keras.layers.Conv2D(8,(3,3),strides=(1,1),padding='same',use_bias=False)(input_images)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.LeakyReLU(alpha=0.1)(x)
x = tf.keras.layers.MaxPooling2D((2,2),strides=(2,2))(x)
x = tf.keras.layers.Conv2D(16,(3,3),strides=(1,1),padding='same',use_bias=False)(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.LeakyReLU(alpha=0.1)(x)
x = tf.keras.layers.MaxPooling2D((2,2),strides=(2,2))(x)
#first triple
x = tf.keras.layers.Conv2D(32,(3,3),strides=(1,1),padding='same',use_bias=False)(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.LeakyReLU(alpha=0.1)(x)
x = tf.keras.layers.Conv2D(16,(1,1),strides=(1,1),padding='same',use_bias=False)(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.LeakyReLU(alpha=0.1)(x)
x = tf.keras.layers.Conv2D(32,(3,3),strides=(1,1),padding='same',use_bias=False)(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.LeakyReLU(alpha=0.1)(x)
x = tf.keras.layers.MaxPooling2D((2,2),strides=(2,2))(x)
#second triple
x = tf.keras.layers.Conv2D(64,(3,3),strides=(1,1),padding='same',use_bias=False)(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.LeakyReLU(alpha=0.1)(x)
x = tf.keras.layers.Conv2D(32,(1,1),strides=(1,1),padding='same',use_bias=False)(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.LeakyReLU(alpha=0.1)(x)
x = tf.keras.layers.Conv2D(64,(3,3),strides=(1,1),padding='same',use_bias=False)(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.LeakyReLU(alpha=0.1)(x)
x = tf.keras.layers.MaxPooling2D((2,2),strides=(2,2))(x)
#third triple
x = tf.keras.layers.Conv2D(128,(3,3),strides=(1,1),padding='same',use_bias=False)(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.LeakyReLU(alpha=0.1)(x)
x = tf.keras.layers.Conv2D(64,(1,1),strides=(1,1),padding='same',use_bias=False)(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.LeakyReLU(alpha=0.1)(x)
x = tf.keras.layers.Conv2D(128,(3,3),strides=(1,1),padding='same',use_bias=False)(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.LeakyReLU(alpha=0.1)(x)
x = tf.keras.layers.MaxPooling2D((2,2),strides=(2,2))(x)
#fourth triple
x = tf.keras.layers.Conv2D(256,(3,3),strides=(1,1),padding='same',use_bias=False)(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.LeakyReLU(alpha=0.1)(x)
x = tf.keras.layers.Conv2D(128,(1,1),strides=(1,1),padding='same',use_bias=False)(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.LeakyReLU(alpha=0.1)(x)
x = tf.keras.layers.Conv2D(256,(3,3),strides=(1,1),padding='same',use_bias=False)(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.LeakyReLU(alpha=0.1)(x)
#ending network
L1 = tf.keras.layers.MaxPooling2D((7,7),strides=(1,1),padding='valid')(x)
L2 = tf.keras.layers.MaxPooling2D((6,6),strides=(1,1),padding='valid')(x)
L3 = tf.keras.layers.MaxPooling2D((4,4),strides=(1,1),padding='valid')(x)
FL1 = tf.keras.layers.Flatten()(L1)
FL2 = tf.keras.layers.Flatten()(L2)
FL3 = tf.keras.layers.Flatten()(L3)
x = tf.keras.layers.Concatenate(axis=1)([FL1,FL2,FL3])
x = tf.keras.layers.Dense(class_no,activation='softmax')(x)
# Create model.
model=tf.keras.models.Model(inputs=input_images,outputs=x)
return model
4.实验结果及应用
在Python平台上使用Kera2.2.4、TensorFlow1.12等依赖包进行编码实现。Adam 优化器用于训练分类交叉熵损失函数,其中 epoch 为100,学习率为 0.0001。Minibatch 大小为 64。总的实验结果如图所示:
为了进行性能比较,测试了六个更轻量级的深度学习模型,其中包括MobileNetV1 ,MobileNet V2,MobileNet V3 等。每种算法都经过了5倍交叉验证测试,我们的SPP-COVID-Net得到了最佳平均准确度为0.946。
训练后的模型进行保存参数,并使用flask进行API的部署。网页界面实现如下所示:
5.结论
综上所述,与基准方法相比,所提出的SPP-COVID-Net已经实现了良好检测精度,其精确度在[0.938,0.957]范围内。SPP-COVID-Net的优势可以归因于SPP模块集成而能够处理多尺度特征。
参考
1.D. Cao, H. Yin, J. Chen, F. Tang, M. Peng, R. Li, et al., "Clinical analysis of ten pregnant women with covid19 in wuhan china: A retrospective study", International Journal of Infectious Diseases, vol. 95, pp. 294-300, 2020.
2.T. Ozturk, M. Talo, E. A. Yildirim, U. B. Baloglu, O. Yildirim and U. R. Acharya, "Automated detection of covid-19 cases using deep neural networks with x-ray images", Computers in Biology and Medicine, vol. 121, pp. 103792, 2020.