荧光图像中的自动COVID-19检测器



在本指南中,您将学习如何使用Keras,TensorFlow和深度学习在特殊选择的数据集中自动检测COVID-19。

像现在世界上大多数人一样,我真诚地关心COVID-19。我注意到我开始不断分析自己的健康状况,并怀疑自己已经被感染。

我越担心这一点,将真实症状与软骨病的痛苦组合表现得越痛苦:

  • 我早上醒来,感到有点不知所措。
  • 当我下床时,我的鼻子已经漏水了(尽管现在知道流鼻涕不是COVID-19的症状)。
  • 当他到达浴室拿餐巾纸时,他还咳嗽了。

起初,我对此并不十分重视-我对花粉过敏,而且由于东海岸的温暖天气,今年初春天来了。我的过敏很可能刚爆发。

但是症状并没有整日改善。

我坐在这里,在嘴里用温度计写这本手册。向下看时显示37.4°C。温度高于我通常的36.3°C。高于37.2°C的一切,我已经考虑过轻微发烧。

咳嗽和有点发烧?可能是COVID-19,或者只是我的过敏。

没有测试就不可能发现,正是这种“无知”使这种情况对于心理平衡如此危险。

对于人们来说,没有什么比未知更可怕了。

尽管有种种担忧,我还是试图以合理的方式摆脱它们。我已经三十多岁了,身体状况很好,我的免疫系统很强。我将隔离(以防万一),我会休息并恢复正常。 COVID-19不会在我的个人健康方面吓到我(至少我一直对自己说这句话)。

但是,我担心我的老年亲戚,包括那些患有慢性疾病的人以及在疗养院或医院里的人。它们很脆弱,如果我们由于这种感染而失去它们,那将是非常可悲的。

为了不袖手旁观,不屈服于虚弱(无论是过敏,COVID-19还是焦虑症),我决定尽我所能-通过编写代码,进行实验以及教别人如何在实际的实际应用中使用计算机视觉和深度学习,为整个机器视觉和深度学习社区提供服务

但是,老实说,这不是我写过的最科学的文章。其实远非如此。所使用的方法和数据集不值得发表。但是它们可以成为想要帮助的人的起点。

但是我想尽我所能。本文只是我在精神上克服困难并同时在类似情况下帮助他人的方式。

我希望你能理解我。

在今天的课程中,我们将执行以下操作:

  1. 我们将从收集的COXID-19呈阳性的患者的透视图中收集一组公开数据。
  2. 我们收集一系列健康患者的荧光图。
  3. 我们将训练卷积神经网络,以从创建的集合中自动检测图像中的COVID-19。
  4. 我们将从教育的角度评估获得的结果。

免责声明:我已经暗示过,但我会直言不讳。本文中的方法和技术仅用于教育目的。这不是真正的科学研究,也不会在期刊上发表。本文适用于对(1)计算机视觉/深度学习感兴趣并希望使用实用方法学习的读者,以及(2)关注时事的读者。求您以这种方式与您联系。

荧光图上的COVID-19


在第一部分中,我们讨论如何在胸部X光片上检测到COVID-19。

然后考虑我们的数据集。

然后,我将向您展示如何使用Keras和TensorFlow训练深度学习模型,以在我们的图像数据集中定义COVID-19。

我的任务是激发您的灵感,并表明对计算机视觉/深度学习的研究,然后将其应用于医学领域,会对世界产生重大影响。

简而言之:您不需要医学学位即可为医学做出贡献。与医生和医疗保健提供者紧密合作的深度学习专家可以解决复杂的问题,挽救生命,并使世界变得更美好。

我希望本指南能激发您这样做。

但是,尽管如此,科学期刊和专家评估系统充斥着具有可疑质量的COVID-19预测模型的资料。请不要使用本文中的代码/模型,也不要将其发送到期刊或将其放在科学站点的公共领域中-您只会增加一些噪音。

此外,如果您打算在自己的研究中使用本文(或Internet上的任何其他COVID-19文章),请确保检查TRIPOD规则以创建预测报告模型

您可能知道,在医学中使用AI会带来非常真实的后果。仅在与医学专家密切协商后才能发布或使用此类模型。


图。 1.来自患者的COXID-19呈阳性测试的荧光图示例。在Keras和TensorFlow的帮助下,可以训练分类器在此类图像中检测COVID-19,

目前很难找到 COVID-19测试-它们只是不够不能足够快地进行,从而引起恐慌。

当出现恐慌时,一些邪恶的人会利用这一优势并出售假冒的测试套件COVID-19,从而在社交网络和即时通讯工具上找到受害者

鉴于COVID-19测试套件的数量有限,您应该依靠其他诊断方法。

医生通常依靠胸部X光检查(通常称为透视图)来诊断肺炎,肺炎,脓肿和/或淋巴结肿大。

COVID-19攻击呼吸道上皮,X射线有助于检查患者的肺部状况。大多数医院都安装了X射线机,因此在不使用特殊测试套件的情况下,使用荧光检查法测试COVID-19是合乎逻辑的。缺点是这样的分析需要放射学专家并且花费大量时间。因此,开发自动化系统对于节省全球医疗专业人员的宝贵时间将非常有价值。

注意最近的一些出版物建议计算机断层扫描更适合诊断COVID-19,但是在本课程中,我们仅使用荧光检查。

资料集



图。2.左侧为阳性样本(来自感染患者),右侧为阴性。这些图像用于训练自动预测疾病存在的模型,

我们的数据集由蒙特利尔大学的研究生 Joseph Cohen博士编辑3月初,他开始收集COVID-19,MERS,SARS和SARS患者的荧光图,并将其发布在GitHub上存储库中

我们需要从存储库下载文件,metadata.csv并从其中选择指示行

  1. COVID-19的阳性结果。
  2. 肺的类型“后-前”(PA)。据我了解,这是“健康”图像中使用的图像类型。

COVID-19阳性病例共发现25片荧光图(图2,左)。

对于健康的患者,我使用了Cuggle数据集(肺炎)并选择了25位健康患者的图像(图2,右)。该数据集有很多问题,即标签嘈杂/不正确,但是将对COVID-19自动检测器进行概念检查。

项目结构


在我的网站的“下载”部分中,您可以输入您的电子邮件地址,并找到指向该项目的带有代码,脚本和其他文件的档案的链接。解压缩文件,您将看到目录结构:

$ tree --dirsfirst --filelimit 10
.
├── dataset
│   ├── covid [25 entries]
│   └── normal [25 entries]
├── build_covid_dataset.py
├── sample_kaggle_dataset.py
├── train_covid19.py
├── plot.png
└── covid19.model
3 directories, 5 files

荧光图位于目录中dataset/,其中两个数据类分为目录covid/normal/

这两个脚本都是为了建立数据集而提供的,但是我们今天不再考虑它们。相反,请考虑train_covid19.py教我们COVID-19检测器的脚本

实作


让我们继续建立卷积神经网络。打开文件train_covid19.py并粘贴以下代码:

# import the necessary packages
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import VGG16
from tensorflow.keras.layers import AveragePooling2D
from tensorflow.keras.layers import Dropout
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Input
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.utils import to_categorical
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from imutils import paths
import matplotlib.pyplot as plt
import numpy as np
import argparse
import cv2
import os

该脚本使用了TensorFlow 2.0和Keras的许多深度学习库。此外,我们使用scikit-learn,用于机器学习的标准Python库,用于绘图的matplotlib以及用于加载和处理图像的OpenCV

要安装TensorFlow 2.0(包括适当的scikit-learn,OpenCV和matplotlib库),请按照我对UbuntumacOS的说明进行操作

接下来,我们将分析命令行参数并初始化超参数:

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", required=True,
	help="path to input dataset")
ap.add_argument("-p", "--plot", type=str, default="plot.png",
	help="path to output loss/accuracy plot")
ap.add_argument("-m", "--model", type=str, default="covid19.model",
	help="path to output loss/accuracy plot")
args = vars(ap.parse_args())
# initialize the initial learning rate, number of epochs to train for,
# and batch size
INIT_LR = 1e-3
EPOCHS = 25
BS = 8

三个命令行参数

  • --dataset:输入数据集的路径
  • --plot:学习历史记录的退出时间表的可选路径。除非另有说明,否则默认值为plot.png
  • --model:输出模型的可选路径;默认covid19.model

接下来的几行将初始化初始学习速度,时代数和数据包大小的超参数。

现在,我们准备下载和预处理荧光图:

# grab the list of images in our dataset directory, then initialize
# the list of data (i.e., images) and class images
print("[INFO] loading images...")
imagePaths = list(paths.list_images(args["dataset"]))
data = []
labels = []
# loop over the image paths
for imagePath in imagePaths:
	# extract the class label from the filename
	label = imagePath.split(os.path.sep)[-2]
	# load the image, swap color channels, and resize it to be a fixed
	# 224x224 pixels while ignoring aspect ratio
	image = cv2.imread(imagePath)
	image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
	image = cv2.resize(image, (224, 224))
	# update the data and labels lists, respectively
	data.append(image)
	labels.append(label)
# convert the data and labels to NumPy arrays while scaling the pixel
# intensities to the range [0, 1]
data = np.array(data) / 255.0
labels = np.array(labels)

为了加载数据,我们捕获了目录中图像的所有路径--dataset然后每个imagePath

  • 我们从路径中检索类标签(covidnormal)。
  • 我们对其进行加载image和预处理,将其转换为RGB并重新调整为224×224像素,以便为神经网络做好准备。
  • 正在更新清单datalabels

然后将像素强度缩放到[0,1]范围,并将数据和标签转换为NumPy数组格式。

接下来,我们执行直接编码labels,将数据分为若干组进行训练/测试:

# perform one-hot encoding on the labels
lb = LabelBinarizer()
labels = lb.fit_transform(labels)
labels = to_categorical(labels)
# partition the data into training and testing splits using 80% of
# the data for training and the remaining 20% for testing
(trainX, testX, trainY, testY) = train_test_split(data, labels,
	test_size=0.20, stratify=labels, random_state=42)
# initialize the training data augmentation object
trainAug = ImageDataGenerator(
	rotation_range=15,
	fill_mode="nearest")

直接编码意味着将数据转换为以下格式:

[[0. 1.]
 [0. 1.]
 [0. 1.]
 ...
 [1. 0.]
 [1. 0.]
 [1. 0.]]

每个编码的标签均由具有两个元素的数组组成:“热”(1)或“非”(0)。

然后,以下几行将我们的数据分开,剩下的80%用于培训,而20%用于测试。

为了确保模型是通用的,我们通过将图像设置为顺时针或逆时针随机旋转15°来执行数据扩充。

最后三行初始化数据增强生成器对象。

现在初始化我们的VGGNet模型并对其进行微调

# load the VGG16 network, ensuring the head FC layer sets are left
# off
baseModel = VGG16(weights="imagenet", include_top=False,
	input_tensor=Input(shape=(224, 224, 3)))
# construct the head of the model that will be placed on top of the
# the base model
headModel = baseModel.output
headModel = AveragePooling2D(pool_size=(4, 4))(headModel)
headModel = Flatten(name="flatten")(headModel)
headModel = Dense(64, activation="relu")(headModel)
headModel = Dropout(0.5)(headModel)
headModel = Dense(2, activation="softmax")(headModel)
# place the head FC model on top of the base model (this will become
# the actual model we will train)
model = Model(inputs=baseModel.input, outputs=headModel)
# loop over all layers in the base model and freeze them so they will
# *not* be updated during the first training process
for layer in baseModel.layers:
	layer.trainable = False

前两行使用先前在ImageNet上训练的权重创建了VGG16网络的实例,而没有触及完全连接的层(FC)。

然后,我们构建一个新的完全连接的图层,该图层由layer组成POOL => FC = SOFTMAX,并将其添加到VGG16之上。

然后我们冻结CONVVGG16 的权重,因此训练FC层。这样就完成了设置。

现在,我们准备编译和训练用于COVID-19的深度学习模型:

# compile our model
print("[INFO] compiling model...")
opt = Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS)
model.compile(loss="binary_crossentropy", optimizer=opt,
	metrics=["accuracy"])
# train the head of the network
print("[INFO] training head...")
H = model.fit_generator(
	trainAug.flow(trainX, trainY, batch_size=BS),
	steps_per_epoch=len(trainX) // BS,
	validation_data=(testX, testY),
	validation_steps=len(testX) // BS,
	epochs=EPOCHS)

第一行编译神经网络,并带有降低学习速度和优化器的选项Adam考虑到这是一个两类问题,我们使用损失"binary_crossentropy"而不是交叉熵。

要开始学习过程,我们在Keras 调用fit_generator 方法,将荧光图通过我们的数据增强对象。

我们评估模型:

# make predictions on the testing set
print("[INFO] evaluating network...")
predIdxs = model.predict(testX, batch_size=BS)
# for each image in the testing set we need to find the index of the
# label with corresponding largest predicted probability
predIdxs = np.argmax(predIdxs, axis=1)
# show a nicely formatted classification report
print(classification_report(testY.argmax(axis=1), predIdxs,
	target_names=lb.classes_))

为了进行评估,我们首先对测试集进行预测,并保留预测指标。然后,我们使用scikit-learn创建并显示分类报告,其中包含此类辅助功能。

接下来,我们计算误差矩阵以进行进一步的统计评估:

# compute the confusion matrix and and use it to derive the raw
# accuracy, sensitivity, and specificity
cm = confusion_matrix(testY.argmax(axis=1), predIdxs)
total = sum(sum(cm))
acc = (cm[0, 0] + cm[1, 1]) / total
sensitivity = cm[0, 0] / (cm[0, 0] + cm[0, 1])
specificity = cm[1, 1] / (cm[1, 0] + cm[1, 1])
# show the confusion matrix, accuracy, sensitivity, and specificity
print(cm)
print("acc: {:.4f}".format(acc))
print("sensitivity: {:.4f}".format(sensitivity))
print("specificity: {:.4f}".format(specificity))

在这里,我们执行以下操作:

  • 我们生成了一个误差矩阵。
  • 在它的帮助下,我们通过打印所有这些指标来计算准确性,敏感性和特异性。

为了进行自我测试,我们生成了一张带有训练准确性和损失历史的图形,并将其输出到图形文件中:

# plot the training loss and accuracy
N = EPOCHS
plt.style.use("ggplot")
plt.figure()
plt.plot(np.arange(0, N), H.history["loss"], label="train_loss")
plt.plot(np.arange(0, N), H.history["val_loss"], label="val_loss")
plt.plot(np.arange(0, N), H.history["accuracy"], label="train_acc")
plt.plot(np.arange(0, N), H.history["val_accuracy"], label="val_acc")
plt.title("Training Loss and Accuracy on COVID-19 Dataset")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend(loc="lower left")
plt.savefig(args["plot"])

最后,将分类器模型保存tf.keras到磁盘:

# serialize the model to disk
print("[INFO] saving COVID-19 detector model...")
model.save(args["model"], save_format="h5")

侦探训练


使用上述源代码和脚本从归档文件下载所有文件后,打开控制台并运行以下命令来训练检测器:

$ python train_covid19.py --dataset dataset
[INFO] loading images...
[INFO] compiling model...
[INFO] training head...
Epoch 1/25
5/5 [==============================] - 20s 4s/step - loss: 0.7169 - accuracy: 0.6000 - val_loss: 0.6590 - val_accuracy: 0.5000
Epoch 2/25
5/5 [==============================] - 0s 86ms/step - loss: 0.8088 - accuracy: 0.4250 - val_loss: 0.6112 - val_accuracy: 0.9000
Epoch 3/25
5/5 [==============================] - 0s 99ms/step - loss: 0.6809 - accuracy: 0.5500 - val_loss: 0.6054 - val_accuracy: 0.5000
Epoch 4/25
5/5 [==============================] - 1s 100ms/step - loss: 0.6723 - accuracy: 0.6000 - val_loss: 0.5771 - val_accuracy: 0.6000
...
Epoch 22/25
5/5 [==============================] - 0s 99ms/step - loss: 0.3271 - accuracy: 0.9250 - val_loss: 0.2902 - val_accuracy: 0.9000
Epoch 23/25
5/5 [==============================] - 0s 99ms/step - loss: 0.3634 - accuracy: 0.9250 - val_loss: 0.2690 - val_accuracy: 0.9000
Epoch 24/25
5/5 [==============================] - 27s 5s/step - loss: 0.3175 - accuracy: 0.9250 - val_loss: 0.2395 - val_accuracy: 0.9000
Epoch 25/25
5/5 [==============================] - 1s 101ms/step - loss: 0.3655 - accuracy: 0.8250 - val_loss: 0.2522 - val_accuracy: 0.9000
[INFO] evaluating network...
              precision    recall  f1-score   support
       covid       0.83      1.00      0.91         5
      normal       1.00      0.80      0.89         5
    accuracy                           0.90        10
   macro avg       0.92      0.90      0.90        10
weighted avg       0.92      0.90      0.90        10
[[5 0]
 [1 4]]
acc: 0.9000
sensitivity: 1.0000
specificity: 0.8000
[INFO] saving COVID-19 detector model...

根据荧光检查结果自动诊断COVID-19


: , «» COVID-19. . , , , ( , ). , / COVID-19.

从以上结果可以看出,我们的自动检测器对现有样本集的准确度约为90-92%。该评级仅基于图像分析。在训练期间,不再使用任何数据,包括地理位置,人口密度等

。敏感性为100%,特异性为80%,这意味着:

  • 真正感染的患者在100%的病例中得到认可。
  • 健康的患者被认为是健康的,概率为80%。

如训练历史图所示,尽管数据集非常有限,但我们的网络并没有受到太大的训练



绝对准确地识别COVID-19 能力非常强,尽管误报率有点令人担忧,因为许多健康的人将被送往与真正感染的患者隔离。

在医疗应用中,尤其是在传染性疾病的情况下,平衡敏感性和特异性非常困难。

对于计算机视觉和医学的深入培训,您应该始终记住,我们的预测模型可能会产生非常实际的后果-错过诊断可能会丧生。

同样,收集这些结果仅出于教育目的。本文及其所附结果仅供参考,不适合在科学期刊上发表,也不符合TRIPOD建立预报报告模型的规则

局限性,改进和未来工作



图。 4.当前,人工智能和深度学习专家缺乏有效训练图像上COVID-19自动检测系统(图像源的高质量数据

,创建此类系统的主要限制之一是数据。我们只是没有足够的(可靠)数据来训练COVID-19检测器。医院挤满了COVID-19患者,但是鉴于他们的权利和隐私,及时收集高质量的医学图像变得更加困难

我想在接下来的12-18个月内这个问题将得到解决,但目前我们对自己所拥有的感到满意。我竭尽所能(考虑到我当前的心理和身体状况),为那些有兴趣在考虑到时间和资源限制的情况下,对使用计算机视觉和深度学习对抗COVID-19的人编写指南。但我必须提醒您,我不是医学专家。

真正的COVID-19检测器必须经过训练有素的医学专家与有经验的深度学习从业人员携手进行严格的测试。当然,此处描述的方法不适合实际使用,仅用于教育目的。

此外,我们必须怀疑该模型实际上可以“学习”什么。正如我所说上周Grad-CAM指南的指导下,我们的模型完全有可能研究与COVID-19不相关的模式,而仅仅是两个数据集之间的差异(即有和没有COVID-19的患者之间)。为了确认结果,需要彻底的测试和专家协助。

最后,未来(也是最好的)检测器将是多峰的。

现在我们考虑图像(例如X射线)。最好的COVID-19自动检测器应使用多个数据源,而不仅限于图像,包括患者生命指标,人口密度,地理位置等。仅图像本身通常不足以实现此类应用。

我希望本指南可以作为对使用计算机视觉和深度学习自动检测COVID-19感兴趣的任何人的起点。

下一步是什么?


我通常会在博客文章的结尾给出一本书或一门课程的推荐,以便您可以了解有关使用计算机视觉和深度学习的更多信息。出于对冠状病毒严重性的尊重,我不打算这样做-现在不是时间或地点。

相反,我要说的是,我们现在处于一个非常可怕的时期。像季节一样,一切都会过去,但是现在您需要蹲下并为寒冷的冬天做准备-最坏的情况可能还没有到来。

我收到了来自PyImageSearch读者的几封信,他们希望利用这段停机时间来研究计算机视觉和深度学习,而不是在家里疯了。这是一个有用的想法。

摘要


在本指南中,您学习了如何使用Keras和TensorFlow在荧光图上训练COVID-19自动检测器。

目前还没有高质量的,经过同行评审的COVID-19图像数据集,因此我们必须使用已有的东西,即GitHub上的Joseph Cohen的存储库


我们使用Keras和TensorFlow训练了COVID-19检测器,该检测器在测试集上证明了90-92%的准确度,100%的灵敏度和80%的特异性(鉴于我们有限的数据集)。

请记住,所描述的COVID-19检测器仅用于教育目的。

All Articles