訂閱
糾錯
加入自媒體

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

原始胸部X光圖像(A),逆時針旋轉(zhuǎn)45度后圖像(B),順時針旋轉(zhuǎn)45度后圖像,水平和垂直平移20%后圖像(D),放大10%后圖像(E)。使用TS/Keras圖像預(yù)處理庫(ImageDataGenerator),可以更改多個圖像參數(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度來評估結(jié)果。trainAug = ImageDataGenerator(rotation_range=ROTATION_DEG, fill_mode="nearest")此時,我們已經(jīng)定義了模型和數(shù)據(jù),并準(zhǔn)備好進(jìn)行編譯和訓(xùn)練。模型構(gòu)建與訓(xùn)練編譯允許我們給模型添加額外的特性,比如loss函數(shù)、優(yōu)化器和度量。對于網(wǎng)絡(luò)訓(xùn)練,我們使用損失函數(shù)來計算網(wǎng)絡(luò)預(yù)測值與訓(xùn)練數(shù)據(jù)實際值之間的差異,伴隨著優(yōu)化器算法(如Adam)對網(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)有趣了,驗證數(shù)據(jù)的精度達(dá)到了92%!繪制精度圖表:

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

看看混淆矩陣:[[27  0] [ 4 23]]acc: 0.9259sensitivity: 1.0000specificity: 0.8519從用最初選擇的超參數(shù)訓(xùn)練的模型中,我們得到:100%的sensitivity(敏感度),也就是說,對于COVID-19陽性(即真正例)的患者,我們可以100%準(zhǔn)確地將其識別為“COVID-19陽性”。85%的specificity(特異性)意味著在沒有COVID-19(即真反例)的患者中,我們只能85%準(zhǔn)確地將其識別為“COVID-19陰性”。結(jié)果并不令人滿意,因為15%沒有Covid的患者會被誤診。我們先對模型進(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)確地將他們識別為“COVID-19陰性”。目前看來,這個結(jié)果很有希望。讓我們保存這個模型,在那些沒有經(jīng)過訓(xùn)練的圖像上測試(Covid-19的8個圖像和從輸入數(shù)據(jù)集中隨機選擇的20個圖像)。model.save("../model/covid_normal_model.h5")在真實圖像中測試模型(驗證)首先,讓我們檢索模型并顯示最終的體系結(jié)構(gòu),以檢查一切是否正常:new_model = load_model('../model/covid_normal_model.h5')# 展示模型架構(gòu)new_model.summary()

這個模型看起來不錯,是VGG16的16層結(jié)構(gòu)。請注意,可訓(xùn)練參數(shù)為590210,這是最后兩層的總和,它們被添加到參數(shù)為14.7M的預(yù)訓(xù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個Covid圖像驗證模型,為此,我們創(chuàng)建了另外一個函數(shù),它是為單個圖像測試開發(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個圖像的imagePath值,我們獲得以下結(jié)果:所有圖像均呈陽性,確認(rèn)100%靈敏度。

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

一個接一個的測試可以確認(rèn)預(yù)測,但是由于我們有更多的圖像,讓我們使用另一個函數(shù)來測試一組圖像,一次完成:test_rx_image_for_Covid19_batch (img_lst) 。批處理測試圖像讓我們創(chuàng)建包含在驗證文件夾中的圖像列表: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例圖像的評估(1-準(zhǔn)確度)低于90%(0.26和0.16)。請記住,輸入數(shù)據(jù)集/input/20_Chest_Xray/有兩個文件夾,/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然后,我們可以利用這個文件夾測試所有圖像。首先,我們創(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張診斷為正常的“未公開”圖片(還有390張不是由Covid-19引起的肺炎)。應(yīng)用批處理函數(shù),我們觀察到24幅圖像出現(xiàn)假陽性(約10%)。讓我們看看模型輸出值是如何分布的,記住函數(shù)返回的值計算如下:pred = new_model.predict(image)pred_pos = round(pred[0][0] * 100)我們觀察到,預(yù)測精度的平均值為0.15,并且非常集中于接近于零的值(中值僅為0.043),有趣的是,大多數(shù)誤報率接近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)有一個峰值接近80%,也就是說,這是非常錯誤的!回顧這一結(jié)果在技術(shù)上并不令人驚訝,因為該模型沒有經(jīng)過普通肺炎患者圖像的訓(xùn)練。不管怎樣,這是一個大問題,因為我認(rèn)為專家可以用肉眼區(qū)分病人是否患有肺炎,然而也許更難區(qū)分這種肺炎是由Covid-19(SARS-CoV-2)、任何其他病毒,甚至是細(xì)菌引起的。將Covid-19引起的肺炎患者與其他類型的病毒或細(xì)菌區(qū)分開來的模型是更有用,為此,另一個模型將被訓(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)入使用的庫并運行。模型2中使用的Covid圖像數(shù)據(jù)集與模型1中使用的相同,只是現(xiàn)在它存儲在不同的文件夾中。dataset_path = '../20_dataset'肺炎圖像將從文件夾/input/20_Chest_Xray/train/PNEUMONIA/下載并存儲在/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  下一頁>  余下全文
聲明: 本文由入駐維科號的作者撰寫,觀點僅代表作者本人,不代表OFweek立場。如有侵權(quán)或其他問題,請聯(lián)系舉報。

發(fā)表評論

0條評論,0人參與

請輸入評論內(nèi)容...

請輸入評論/評論長度6~500個字

您提交的評論過于頻繁,請輸入驗證碼繼續(xù)

暫無評論

暫無評論

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

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