訂閱
糾錯(cuò)
加入自媒體

使用Python+OpenCV+Tensorflow+Flask實(shí)現(xiàn)檢測X光中的新冠病毒

原始胸部X光圖像(A),逆時(shí)針旋轉(zhuǎn)45度后圖像(B),順時(shí)針旋轉(zhuǎn)45度后圖像,水平和垂直平移20%后圖像(D),放大10%后圖像(E)。使用TS/Keras圖像預(yù)處理庫(ImageDataGenerator),可以更改多個(gè)圖像參數(shù),例如: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')一開始,僅應(yīng)用圖像最大旋轉(zhuǎn)15度來評(píng)估結(jié)果。trainAug = ImageDataGenerator(rotation_range=ROTATION_DEG, fill_mode="nearest")此時(shí),我們已經(jīng)定義了模型和數(shù)據(jù),并準(zhǔn)備好進(jìn)行編譯和訓(xùn)練。模型構(gòu)建與訓(xùn)練編譯允許我們給模型添加額外的特性,比如loss函數(shù)、優(yōu)化器和度量。對(duì)于網(wǎng)絡(luò)訓(xùn)練,我們使用損失函數(shù)來計(jì)算網(wǎng)絡(luò)預(yù)測值與訓(xùn)練數(shù)據(jù)實(shí)際值之間的差異,伴隨著優(yōu)化器算法(如Adam)對(duì)網(wǎng)絡(luò)中的權(quán)重進(jìn)行更改,這些超參數(shù)有助于網(wǎng)絡(luò)訓(xùn)練的收斂,使損失值盡可能接近于零。我們還指定了優(yōu)化器(lr)的學(xué)習(xí)率,在這種情況下,lr被定義為1e-3。如果在訓(xùn)練過程中注意到“跳躍”的增加,即模型不能收斂,則應(yīng)降低學(xué)習(xí)率,以達(dá)到最小值。opt = Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS)model.compile(loss="binary_crossentropy", optimizer=opt, metrics=["accuracy"])讓我們來訓(xùn)練模型: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)

結(jié)果看起來已經(jīng)相當(dāng)有趣了,驗(yàn)證數(shù)據(jù)的精度達(dá)到了92%!繪制精度圖表:

評(píng)估訓(xùn)練模型:

看看混淆矩陣:[[27  0] [ 4 23]]acc: 0.9259sensitivity: 1.0000specificity: 0.8519從用最初選擇的超參數(shù)訓(xùn)練的模型中,我們得到:100%的sensitivity(敏感度),也就是說,對(duì)于COVID-19陽性(即真正例)的患者,我們可以100%準(zhǔn)確地將其識(shí)別為“COVID-19陽性”。85%的specificity(特異性)意味著在沒有COVID-19(即真反例)的患者中,我們只能85%準(zhǔn)確地將其識(shí)別為“COVID-19陰性”。結(jié)果并不令人滿意,因?yàn)?5%沒有Covid的患者會(huì)被誤診。我們先對(duì)模型進(jìn)行微調(diào),更改一些超參數(shù):因此,我們有:INIT_LR = 0.0001       # 曾經(jīng)是 1e-3  EPOCHS = 20            # 曾經(jīng)是 10       BS = 16                # 曾經(jīng)是 8 NODES_DENSE0 = 128     # 曾經(jīng)是 64DROPOUT = 0.5          MAXPOOL_SIZE = (2, 2)  # 曾經(jīng)是 (4, 4)ROTATION_DEG = 15     SPLIT = 0.2結(jié)果

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結(jié)果好多了!現(xiàn)在具有93%的特異性,這意味著在沒有COVID-19(即真反例)的患者中,在93%到100%的范圍內(nèi)我們可以準(zhǔn)確地將他們識(shí)別為“COVID-19陰性”。目前看來,這個(gè)結(jié)果很有希望。讓我們保存這個(gè)模型,在那些沒有經(jīng)過訓(xùn)練的圖像上測試(Covid-19的8個(gè)圖像和從輸入數(shù)據(jù)集中隨機(jī)選擇的20個(gè)圖像)。model.save("../model/covid_normal_model.h5")在真實(shí)圖像中測試模型(驗(yàn)證)首先,讓我們檢索模型并顯示最終的體系結(jié)構(gòu),以檢查一切是否正常:new_model = load_model('../model/covid_normal_model.h5')# 展示模型架構(gòu)new_model.summary()

這個(gè)模型看起來不錯(cuò),是VGG16的16層結(jié)構(gòu)。請(qǐng)注意,可訓(xùn)練參數(shù)為590210,這是最后兩層的總和,它們被添加到參數(shù)為14.7M的預(yù)訓(xùn)練模型中。讓我們驗(yàn)證測試數(shù)據(jù)集中加載的模型:[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很好,我們得到了與之前相同的結(jié)果,這意味著訓(xùn)練的模型被正確地保存和加載,F(xiàn)在讓我們用之前保存的8個(gè)Covid圖像驗(yàn)證模型,為此,我們創(chuàng)建了另外一個(gè)函數(shù),它是為單個(gè)圖像測試開發(fā)的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.a(chǎn)rray(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.a(chǎn)rgmax(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上,此函數(shù)將顯示以下結(jié)果:

通過更改其余7個(gè)圖像的imagePath值,我們獲得以下結(jié)果:所有圖像均呈陽性,確認(rèn)100%靈敏度。

現(xiàn)在讓我們測試20個(gè)單獨(dú)的圖像,以驗(yàn)證標(biāo)記為NORMAL的有效性。Notebook上的第一個(gè)應(yīng)該是:

一個(gè)接一個(gè)的測試可以確認(rèn)預(yù)測,但是由于我們有更多的圖像,讓我們使用另一個(gè)函數(shù)來測試一組圖像,一次完成:test_rx_image_for_Covid19_batch (img_lst) 。批處理測試圖像讓我們創(chuàng)建包含在驗(yàn)證文件夾中的圖像列表: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) 函數(shù)如下: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.a(chǎn)ppend(pred)    print ('{} positive detected in a total of {} images'.format(pos_cnt, (pos_cnt+neg_cnt)))    return  predictions_score, neg_cnt, pos_cnt將該函數(shù)應(yīng)用于我們先前分離的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例圖像的評(píng)估(1-準(zhǔn)確度)低于90%(0.26和0.16)。請(qǐng)記住,輸入數(shù)據(jù)集/input/20_Chest_Xray/有兩個(gè)文件夾,/train和/test,只有/train中的一部分圖像用于訓(xùn)練,并且模型從未看到測試圖像:input -       |_ 10_Covid_Imagens _       |                   |_ metadata.csv      |                   |_ images [used train model 1]      |_ 20_Chest_Xray -                       |_ test _                               |_ NORMAL                               |_ PNEUMONIA                        |_ train _                                |_ NORMAL   [used train model 1]                                |_ PNEUMONIA然后,我們可以利用這個(gè)文件夾測試所有圖像。首先,我們創(chuàng)建了圖像列表: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張?jiān)\斷為正常的“未公開”圖片(還有390張不是由Covid-19引起的肺炎)。應(yīng)用批處理函數(shù),我們觀察到24幅圖像出現(xiàn)假陽性(約10%)。讓我們看看模型輸出值是如何分布的,記住函數(shù)返回的值計(jì)算如下:pred = new_model.predict(image)pred_pos = round(pred[0][0] * 100)我們觀察到,預(yù)測精度的平均值為0.15,并且非常集中于接近于零的值(中值僅為0.043),有趣的是,大多數(shù)誤報(bào)率接近0.5,少數(shù)異常值高于0.6。

除了改進(jìn)模型外,研究產(chǎn)生假陽性的圖像也是很有意義的。測試不是由Covid引起的肺炎圖像由于輸入數(shù)據(jù)集也有肺炎患者的X光圖像,但不是由Covid引起的,所以讓我們應(yīng)用模型1(Covid/Normal)來查看結(jié)果是什么:

結(jié)果非常糟糕,在390張圖片中,185張有假陽性,而觀察結(jié)果的分布,發(fā)現(xiàn)有一個(gè)峰值接近80%,也就是說,這是非常錯(cuò)誤的!回顧這一結(jié)果在技術(shù)上并不令人驚訝,因?yàn)樵撃P蜎]有經(jīng)過普通肺炎患者圖像的訓(xùn)練。不管怎樣,這是一個(gè)大問題,因?yàn)槲艺J(rèn)為專家可以用肉眼區(qū)分病人是否患有肺炎,然而也許更難區(qū)分這種肺炎是由Covid-19(SARS-CoV-2)、任何其他病毒,甚至是細(xì)菌引起的。將Covid-19引起的肺炎患者與其他類型的病毒或細(xì)菌區(qū)分開來的模型是更有用,為此,另一個(gè)模型將被訓(xùn)練,現(xiàn)在我們有感染Covid-19的病人和感染肺炎但不是由Covid-19病毒引起的病人的圖像。第3部分-模型2-Covid/普通肺炎數(shù)據(jù)準(zhǔn)備從我的GitHub下載Notebook放入subdirectory /notebooks目錄:https://github.com/Mjrovai/covid19Xray/blob/master/10_X-Ray_Covid_development/notebooks/20_Xray_Pneumo_Covid19_M(jìn)odel_2_Training_Tests.ipynb。導(dǎo)入使用的庫并運(yùn)行。模型2中使用的Covid圖像數(shù)據(jù)集與模型1中使用的相同,只是現(xiàn)在它存儲(chǔ)在不同的文件夾中。dataset_path = '../20_dataset'肺炎圖像將從文件夾/input/20_Chest_Xray/train/PNEUMONIA/下載并存儲(chǔ)在/20_dataset/pneumo/中。使用的函數(shù)與之前相同:input_dataset_path = '../input/20_Chest_Xray/train/PNEUMONIA'output_dataset_path = '../20_dataset/pneumo'img_num_select = len(xray_cv_train) # 樣本數(shù)量與Covid數(shù)據(jù)相同這樣,我們調(diào)用可視化支持函數(shù),檢查得到的結(jié)果: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  下一頁>  余下全文
聲明: 本文由入駐維科號(hào)的作者撰寫,觀點(diǎn)僅代表作者本人,不代表OFweek立場。如有侵權(quán)或其他問題,請(qǐng)聯(lián)系舉報(bào)。

發(fā)表評(píng)論

0條評(píng)論,0人參與

請(qǐng)輸入評(píng)論內(nèi)容...

請(qǐng)輸入評(píng)論/評(píng)論長度6~500個(gè)字

您提交的評(píng)論過于頻繁,請(qǐng)輸入驗(yàn)證碼繼續(xù)

  • 看不清,點(diǎn)擊換一張  刷新

暫無評(píng)論

暫無評(píng)論

    掃碼關(guān)注公眾號(hào)
    OFweek人工智能網(wǎng)
    獲取更多精彩內(nèi)容
    文章糾錯(cuò)
    x
    *文字標(biāo)題:
    *糾錯(cuò)內(nèi)容:
    聯(lián)系郵箱:
    *驗(yàn) 證 碼:

    粵公網(wǎng)安備 44030502002758號(hào)