订阅
纠错
加入自媒体

使用Python+OpenCV+Tensorflow+Flask实现检测X光中的新冠病毒

2020-08-18 10:38
磐创AI
关注

原始胸部X光图像(A),逆时针旋转45度后图像(B),顺时针旋转45度后图像,水平和垂直平移20%后图像(D),放大10%后图像(E)。使用TS/Keras图像预处理库(ImageDataGenerator),可以更改多个图像参数,例如:trainAug = ImageDataGenerator(        rotation_range=15,        width_shift_range=0.2,        height_shift_range=0.2,        rescale=1./255,        shear_range=0.2,        zoom_range=0.2,        horizontal_flip=True,        fill_mode='nearest')一开始,仅应用图像最大旋转15度来评估结果。trainAug = ImageDataGenerator(rotation_range=ROTATION_DEG, fill_mode="nearest")此时,我们已经定义了模型和数据,并准备好进行编译和训练。模型构建与训练编译允许我们给模型添加额外的特性,比如loss函数、优化器和度量。对于网络训练,我们使用损失函数来计算网络预测值与训练数据实际值之间的差异,伴随着优化器算法(如Adam)对网络中的权重进行更改,这些超参数有助于网络训练的收敛,使损失值尽可能接近于零。我们还指定了优化器(lr)的学习率,在这种情况下,lr被定义为1e-3。如果在训练过程中注意到“跳跃”的增加,即模型不能收敛,则应降低学习率,以达到最小值。opt = Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS)model.compile(loss="binary_crossentropy", optimizer=opt, metrics=["accuracy"])让我们来训练模型:H = model.fit(    trainAug.flow(trainX, trainY, batch_size=BS),    steps_per_epoch=len(trainX) // BS,    validation_data=(testX, testY),    validation_steps=len(testX) // BS,    epochs=EPOCHS)

结果看起来已经相当有趣了,验证数据的精度达到了92%!绘制精度图表:

评估训练模型:

看看混淆矩阵:[[27  0] [ 4 23]]acc: 0.9259sensitivity: 1.0000specificity: 0.8519从用最初选择的超参数训练的模型中,我们得到:100%的sensitivity(敏感度),也就是说,对于COVID-19阳性(即真正例)的患者,我们可以100%准确地将其识别为“COVID-19阳性”。85%的specificity(特异性)意味着在没有COVID-19(即真反例)的患者中,我们只能85%准确地将其识别为“COVID-19阴性”。结果并不令人满意,因为15%没有Covid的患者会被误诊。我们先对模型进行微调,更改一些超参数:因此,我们有:INIT_LR = 0.0001       # 曾经是 1e-3  EPOCHS = 20            # 曾经是 10       BS = 16                # 曾经是 8 NODES_DENSE0 = 128     # 曾经是 64DROPOUT = 0.5          MAXPOOL_SIZE = (2, 2)  # 曾经是 (4, 4)ROTATION_DEG = 15     SPLIT = 0.2结果

precision    recall  f1-score   support       covid       0.93      1.00      0.96        27      normal       1.00      0.93      0.96        27    accuracy                           0.96        54   macro avg       0.97      0.96      0.96        54weighted avg       0.97      0.96      0.96        54以及混淆矩阵:[[27  0] [ 2 25]]acc: 0.9630sensitivity: 1.0000specificity: 0.9259结果好多了!现在具有93%的特异性,这意味着在没有COVID-19(即真反例)的患者中,在93%到100%的范围内我们可以准确地将他们识别为“COVID-19阴性”。目前看来,这个结果很有希望。让我们保存这个模型,在那些没有经过训练的图像上测试(Covid-19的8个图像和从输入数据集中随机选择的20个图像)。model.save("../model/covid_normal_model.h5")在真实图像中测试模型(验证)首先,让我们检索模型并显示最终的体系结构,以检查一切是否正常:new_model = load_model('../model/covid_normal_model.h5')# 展示模型架构new_model.summary()

这个模型看起来不错,是VGG16的16层结构。请注意,可训练参数为590210,这是最后两层的总和,它们被添加到参数为14.7M的预训练模型中。让我们验证测试数据集中加载的模型:[INFO] evaluating network...              precision    recall  f1-score   support       covid       0.93      1.00      0.96        27      normal       1.00      0.93      0.96        27    accuracy                           0.96        54   macro avg       0.97      0.96      0.96        54weighted avg       0.97      0.96      0.96        54很好,我们得到了与之前相同的结果,这意味着训练的模型被正确地保存和加载。现在让我们用之前保存的8个Covid图像验证模型,为此,我们创建了另外一个函数,它是为单个图像测试开发的def test_rx_image_for_Covid19(imagePath):    img = cv2.imread(imagePath)    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)    img = cv2.resize(img, (224, 224))    img = np.expand_dims(img, axis=0)    img = np.array(img) / 255.0    pred = new_model.predict(img)    pred_neg = round(pred[0][1]*100)    pred_pos = round(pred[0][0]*100)    print(' X-Ray Covid-19 Detection using AI - MJRovai')    print('    [WARNING] - Only for didactic purposes')    if np.argmax(pred, axis=1)[0] == 1:        plt.title('Prediction: [NEGATIVE] with prob: {}% No Covid-19'.format(            pred_neg), fontsize=12)    else:        plt.title('Prediction: [POSITIVE] with prob: {}% Pneumonia by Covid-19 Detected'.format(            pred_pos), fontsize=12)    img_out = plt.imread(imagePath)    plt.imshow(img_out)    plt.savefig('../Image_Prediction/Image_Prediction.png')    return pred_pos在Notebook上,此函数将显示以下结果:

通过更改其余7个图像的imagePath值,我们获得以下结果:所有图像均呈阳性,确认100%灵敏度。

现在让我们测试20个单独的图像,以验证标记为NORMAL的有效性。Notebook上的第一个应该是:

一个接一个的测试可以确认预测,但是由于我们有更多的图像,让我们使用另一个函数来测试一组图像,一次完成:test_rx_image_for_Covid19_batch (img_lst) 。批处理测试图像让我们创建包含在验证文件夹中的图像列表:validation_path = '../dataset_validation'normal_val_images = list(paths.list_images(    f"{validation_path}/normal_validation"))non_covid_pneumonia_validation_images = list(paths.list_images(    f"{validation_path}/non_covid_pneumonia_validation"))covid_val_images = list(paths.list_images(    f"{validation_path}/covid_validation"))test_rx_image_for_Covid19_batch (img_lst) 函数如下:def test_rx_image_for_Covid19_batch(img_lst):    neg_cnt = 0    pos_cnt = 0    predictions_score = []    for img in img_lst:        pred, neg_cnt, pos_cnt = test_rx_image_for_Covid19_2(img, neg_cnt, pos_cnt)        predictions_score.append(pred)    print ('{} positive detected in a total of {} images'.format(pos_cnt, (pos_cnt+neg_cnt)))    return  predictions_score, neg_cnt, pos_cnt将该函数应用于我们先前分离的20幅图像:img_lst = normal_val_imagesnormal_predictions_score, normal_neg_cnt, normal_pos_cnt = test_rx_image_for_Covid19_batch(img_lst)normal_predictions_score我们观察到,所有20人被诊断为阴性,得分如下(记住,接近“1”代表“阳性”):0.25851375, 0.025379542, 0.005824779, 0.0047603976, 0.042225637, 0.025087152, 0.035508618, 0.009078974, 0.014746706, 0.06489486, 0.003134642, 0.004970203, 0.15801577, 0.006775451, 0.0032735346, 0.007105667, 0.001369465, 0.005155371, 0.029973848, 0.014993184只有2例图像的评估(1-准确度)低于90%(0.26和0.16)。请记住,输入数据集/input/20_Chest_Xray/有两个文件夹,/train和/test,只有/train中的一部分图像用于训练,并且模型从未看到测试图像:input -       |_ 10_Covid_Imagens _       |                   |_ metadata.csv      |                   |_ images [used train model 1]      |_ 20_Chest_Xray -                       |_ test _                               |_ NORMAL                               |_ PNEUMONIA                        |_ train _                                |_ NORMAL   [used train model 1]                                |_ PNEUMONIA然后,我们可以利用这个文件夹测试所有图像。首先,我们创建了图像列表:validation_path = '../input/20_Chest_Xray/test'normal_test_val_images = list(paths.list_images(f"{validation_path}/NORMAL"))print("Normal Xray Images: ", len(normal_test_val_images))pneumo_test_val_images = list(paths.list_images(f"{validation_path}/PNEUMONIA"))print("Pneumo Xray Images: ", len(pneumo_test_val_images))我们观察了234张诊断为正常的“未公开”图片(还有390张不是由Covid-19引起的肺炎)。应用批处理函数,我们观察到24幅图像出现假阳性(约10%)。让我们看看模型输出值是如何分布的,记住函数返回的值计算如下:pred = new_model.predict(image)pred_pos = round(pred[0][0] * 100)我们观察到,预测精度的平均值为0.15,并且非常集中于接近于零的值(中值仅为0.043),有趣的是,大多数误报率接近0.5,少数异常值高于0.6。

除了改进模型外,研究产生假阳性的图像也是很有意义的。测试不是由Covid引起的肺炎图像由于输入数据集也有肺炎患者的X光图像,但不是由Covid引起的,所以让我们应用模型1(Covid/Normal)来查看结果是什么:

结果非常糟糕,在390张图片中,185张有假阳性,而观察结果的分布,发现有一个峰值接近80%,也就是说,这是非常错误的!回顾这一结果在技术上并不令人惊讶,因为该模型没有经过普通肺炎患者图像的训练。不管怎样,这是一个大问题,因为我认为专家可以用肉眼区分病人是否患有肺炎,然而也许更难区分这种肺炎是由Covid-19(SARS-CoV-2)、任何其他病毒,甚至是细菌引起的。将Covid-19引起的肺炎患者与其他类型的病毒或细菌区分开来的模型是更有用,为此,另一个模型将被训练,现在我们有感染Covid-19的病人和感染肺炎但不是由Covid-19病毒引起的病人的图像。第3部分-模型2-Covid/普通肺炎数据准备从我的GitHub下载Notebook放入subdirectory /notebooks目录:https://github.com/Mjrovai/covid19Xray/blob/master/10_X-Ray_Covid_development/notebooks/20_Xray_Pneumo_Covid19_Model_2_Training_Tests.ipynb。导入使用的库并运行。模型2中使用的Covid图像数据集与模型1中使用的相同,只是现在它存储在不同的文件夹中。dataset_path = '../20_dataset'肺炎图像将从文件夹/input/20_Chest_Xray/train/PNEUMONIA/下载并存储在/20_dataset/pneumo/中。使用的函数与之前相同:input_dataset_path = '../input/20_Chest_Xray/train/PNEUMONIA'output_dataset_path = '../20_dataset/pneumo'img_num_select = len(xray_cv_train) # 样本数量与Covid数据相同这样,我们调用可视化支持函数,检查得到的结果:pneumo_images = list(paths.list_images(f"{dataset_path}/pneumo"))covid_images = list(paths.list_images(f"{dataset_path}/covid"))plots_from_files(covid_images, rows=10, maintitle="Covid-19 X-ray images")

plots_from_files(pneumo_images, rows=10, maintitle="Pneumony X-ray images"

<上一页  1  2  3  4  下一页>  余下全文
声明: 本文由入驻维科号的作者撰写,观点仅代表作者本人,不代表OFweek立场。如有侵权或其他问题,请联系举报。

发表评论

0条评论,0人参与

请输入评论内容...

请输入评论/评论长度6~500个字

您提交的评论过于频繁,请输入验证码继续

暂无评论

暂无评论

人工智能 猎头职位 更多
扫码关注公众号
OFweek人工智能网
获取更多精彩内容
文章纠错
x
*文字标题:
*纠错内容:
联系邮箱:
*验 证 码:

粤公网安备 44030502002758号