使用tensorflow 与keras 进行新冠肺炎的检测

新冠肺炎X-RAY 图片

2019年的新冠肺炎,牵动了亿万家庭的心,特别是最近美国超过100万的感染人数的i情况下,新冠肺炎的检测与救助工作仍然是当前十分重要的任务,我们也希望这次瘟疫早点过去,希望人类能够早一点恢复到正常的生活。

本期文章,我们通过神经网络来进行新冠(COVID-19)的训练与检测。

神经网络的模型训练

模型数据图片

首先我们收集了部分新冠的图片来进行神经网络的模型训练,搜集2类新冠的图片,一类是正常的图片,一类是呈阳性的图片,本期使用tensorflow 的keras模型来进行神经网络的模型训练以及检测。

建立CNN卷积神经网络来进行图片的训练

此部分需要建立神经网络对图片进行分类,一类是新冠阳性,一类是新冠阴性。首先导入需要使用到的库

from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import VGG16
from tensorflow.keras.layers import AveragePooling2D,Dropout, Flatten,Dense,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, confusion_matrix
import numpy as np
import cv2
import os

从以上导入的库,可以看出,我们的神经网络基于Sk-learn模型来建立,利用VGG16模型进行CNN卷积神经网络

INIT_LR = 1e-3 
EPOCHS = 25
BS = 8
imagePaths =[]
data = [] 
labels = []
for root, dirs, files in os.walk("dataset"):
	for file in files:
		imagePaths.append(os.path.join(root, file))

INIT_LR:学习效率

EPOCHS:每步需要学习的数量

BS:学习的总步数

imagePaths:获取dataset 下面的所有图片的路径

初始化一个data 数组来保存图片 数据,一个labels 数组来保存图片的分类类型(阳性 或者 阴性)

for imagePath in imagePaths:
	label = imagePath.split(os.path.sep)[-2]
	image = cv2.imread(imagePath)
	image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
	image = cv2.resize(image, (224, 224))
	data.append(image)
	labels.append(label)

通过一个for循环来遍历所有图片的路径

label 来获取每个图片的标签

cv2.imread是CV2中独有的来读取图片的代码格式,但是cv2默认的颜色空间是BGR,所以使用cv2.COLOR_BGR2RGB来把cv2的默认颜色空间BGR转换到RGB空间

resize图片到224*224 上,此步骤的目的是在保存图片特征的基础上,尽量减少图片的数据,以便神经网络进行计算

最后使用append把图片 的数据与标签分别存入事前初始化的data 与 labels数组中。

data = np.array(data) / 255.0
labels = np.array(labels)
lb = LabelBinarizer()
labels = lb.fit_transform(labels)
labels = to_categorical(labels) # 多类训练,删除此行
(trainX, testX, trainY, testY) = train_test_split(data, labels,	test_size=0.20, stratify=labels, random_state=42)
trainAug = ImageDataGenerator(rotation_range=15,fill_mode="nearest")

把图片的data labels 数据转换成NumPy数组,并把图片的data数据的像素转换成[0,1]空间

神经网络处理的数据需要连续的数据,由于labels数据是独立的不连续的数据(2个标签,阴性或者阳性),需要转换为one-hot 编码数据

数据处理完成后,把数据分成测试集与训练集

然后初始化训练数据增强对象

数据准备完成后,开始搭建CNN 卷积神经网络

baseModel = VGG16(weights="imagenet", include_top=False,input_tensor=Input(shape=(224, 224, 3)))
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)
model = Model(inputs=baseModel.input, outputs=headModel)

使用VGG16模型来搭建CNN 卷积神经网络,输入图片的的尺寸为244*244*3 ,3 为RGB的三维

baseModel.output 输出层便是下层神经网络的输入

AveragePooling2D pooling的尺寸为4*4

Flatten 是指将多维的矩阵拉开,变成一维向量来表示

使用relu激励函数激活神经网络

设置神经网络的dropout值为0.5

最后使用soft max 函数进行神经网络的分类

CNN 神经网络搭建完成后,使用Model 来建立一个神经网络model

以上便是完整的CNN 卷积神经网络的搭建过程,其中的pooling relu 以及全连接的含义可以参考

小编以前的文章,顺便在这里介绍一下由人工智能研究所出品的专栏,人工智能目标检测与目标追踪

有兴趣的小伙伴们可以一起探讨学习

通过以上的步骤,我们建立了VGG16的神经网络,然后我们需要对神经网络进行训练

for layer in baseModel.layers:
	layer.trainable = False
opt = Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS)
model.compile(loss="categorical_crossentropy", optimizer=opt,metrics=["accuracy"])
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)
  '''
语法结构:model.compile(loss='目标函数', optimizer=optimizer, metrics=['accuracy'])
目标函数,也叫损失函数,是网络中的性能函数,它是一个模型必备的两个参数之一。
目标函数由mse、mae、mape、msle、squared_hinge、hinge、binary_crossentropy、
categorical_crossentrop、sparse_categorical_crossentrop等
mse:均方根误差
categorical_crossentropy:亦称作多类的对数损失
使用该目标函数时,需要将标签转化为形如(nb_samples, nb_classes)的二值序列
sparse_categorical_crossentrop:如上,但接受稀疏标签
使用该函数时仍然需要你的标签与输出值的维度相同,你可能需要在标签数据上增加一个维度:np.expand_dims(y,-1)
'''

在进行神经网络的训练前,首先把基础网络模型中的层给屏蔽掉,避免神经网络第一次训练过程中自动更新

设置一个Adam 神经网络优化器

使用compile函数对神经网络进行编译

然后使用fit_generator进行神经网络的训练

最后我们需要对神经网络进行评估预测

predIdxs = model.predict(testX, batch_size=BS)
predIdxs = np.argmax(predIdxs, axis=1)
print(classification_report(testY.argmax(axis=1), predIdxs,	target_names=lb.classes_))

通过sklearn的classification_report来查看模型的训练效果

我们计算一个confusion_matrix,以便进一步的统计评估

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])
print(cm, acc, sensitivity, specificity)

result

最后保存训练的模型,以便后期进行检测时使用

model.save("123.model")

由于本期的训练数据较少,模型的准确性还待继续完善,如何使用预训练模型进行新冠的检测,我们不再分享,其中涉及的代码,小伙伴们可以参考往期的文章来进行图片的检测方面的学习

人工智能Keras图像分类器(CNN卷积神经网络的图片识别篇)

对opencv感兴趣的小伙伴们可以买本属于自己的书籍进行参考学习

当然,网络上很多作者写的专栏也不错,大家也可以进行学习

本期文章,只是从技术角度来对新冠肺炎做一个简单的检测,由于我们对新冠的了解还很少,本期涉及的技术并不能完全使用在医学检测判断上,希望后期人类能够早日战胜疫情,重新恢复正常的生活。