'健康就是財富',這是一個老生常談的話題,但不得不說這是一個真理。在這篇文章中,我們將研究如何利用AI技術來檢測一種致命的疾病——瘧疾。本文將提出一個低成本、高效率和高準確率的開源解決方案。本文有兩個目的:1.了解瘧疾的傳染原因和其致命性;2、介紹如何運用深度學習有效檢測瘧疾。本章的主要內(nèi)容如下:
開展本項目的動機
瘧疾檢測的方法
用深度學習檢測瘧疾
從頭開始訓練卷積神經(jīng)網(wǎng)絡(CNN)
利用預訓練模型進行遷移學習
本文不是為了宣揚 AI 將要取代人類的工作,或者接管世界等論調(diào),而是僅僅展示 AI 是如何用一種低成本、高效率和高準確率的方案,來幫助人類去檢測和診斷瘧疾,并盡量減少人工操作。
Python and TensorFlow?—?A great combo to build open-source deep learning solutions
在本文中,我們將使用 Python 和 tensorflow ,來構(gòu)建一個強大的、可擴展的、有效的深度學習解決方案。這些工具都是免費并且開源的,這使得我們能夠構(gòu)建一個真正低成本、高效精準的解決方案,而且可以讓每個人都可以輕松使用。讓我們開始吧!
動機
瘧疾是經(jīng)瘧蚊叮咬而感染瘧原蟲所引起的蟲媒傳染病,瘧疾最常通過受感染的雌性瘧蚊來傳播。雖然我們不必詳細了解這種疾病,但是我們需要知道瘧疾有五種常見的類型。下圖展示了這種疾病的致死性在全球的分布情況。
Malaria Estimated Risk Heath Map (Source: treated.
從上圖中可以明顯看到,瘧疾遍布全球,尤其是在熱帶區(qū)域分布密集。本項目就是基于這種疾病的特性和致命性來開展的,下面我們舉個例子來說明。起初,如果你被一只受感染的蚊子叮咬了,那么蚊子所攜帶的寄生蟲就會進入你的血液,并且開始摧毀你體內(nèi)的攜氧紅細胞。通常來講,你會在被瘧蚊叮咬后的幾天或幾周內(nèi)感到不適,一般會首先出現(xiàn)類似流感或者病毒感染的癥狀。然而,這些致命的寄生蟲可以在你身體里完好地存活超過一年的時間,并且不產(chǎn)生任何其他癥狀!延遲接受正確的治療,可能會導致并發(fā)癥甚至死亡。因此,早期并有效的瘧疾檢測和排查可以挽救這些生命。
世界衛(wèi)生組織(WHO)發(fā)布了幾個關于瘧疾的重要事實,詳情見此。簡而言之,世界上將近一半的人口面臨瘧疾風險,每年有超過2億的瘧疾病例,以及有大約40萬人死于瘧疾。這些事實讓我們認識到,快速簡單高效的瘧疾檢查是多么重要,這也是本文的動機所在。
瘧疾檢查的方法
文章《 Pre-trained convolutional neural networks as feature extractors toward improved Malaria parasite detection in thin blood smear images》(本文的數(shù)據(jù)和分析也是基于這篇文章)簡要介紹了瘧疾檢測的幾種方法,這些方法包括但是不限于厚薄血涂片檢查、聚合酶鏈式反應(PCR)和快速診斷測試(RDT)。在本文中,我們沒有對這些方法進行詳細介紹,但是需要注意的一點是,后兩種方法常常作為替代方案使用,尤其是在缺乏高質(zhì)量顯微鏡服務的情況下。
我們將簡要討論基于血液涂片檢測流程的標準瘧疾診斷方法,首先感謝 Carlos Ariza 的博文,以及 Adrian Rosebrock 關于瘧疾檢查的文章,這兩篇文章讓我們對瘧疾檢查領域有了更為深入的了解。
A blood smear workflow for Malaria detection (Sour
根據(jù)上圖所示的 WHO 的血液涂片檢測流程,該工作包括在100倍放大倍數(shù)下對血涂片進行深入檢查,其中人們需要從5000個細胞中,手動檢測出含有寄生蟲的紅細胞。Rajaraman 等人的論文中更加詳細的給出了相關的描述,如下所示:
厚血涂片有助于檢測寄生蟲的存在,而薄血涂片有助于識別引起感染的寄生蟲種類(Centers for Disease Control and Prevention, 2012)。診斷準確性在很大程度上取決于人類的專業(yè)知識,并且可能受到觀察者間的差異和觀察者的可靠性所帶來的不利影響,以及受到在疾病流行或資源受限的區(qū)域內(nèi)的大規(guī)模診斷造成的負擔所帶來的不利影響(Mitiku,Mengistu&Gelaw,2003)。替代技術,例如聚合酶鏈式反應(PCR)和快速診斷測試(RDT),也會被使用;但是PCR分析受到其性能的限制(Hommelsheim等,2014),而RDT在疾病流行地區(qū)的成本效益較低(Hawkes,Katsuva&Masumbuko,2009)。
因此,傳統(tǒng)的瘧疾檢測絕對是一個密集的手工過程,或許深度學習技術可以幫助它完成自動化。上文提到的這些內(nèi)容為后文打下了基礎。
用深度學習檢測瘧疾
手工診斷血液涂片,是一項重復且規(guī)律的工作,而且需要一定的專業(yè)知識來區(qū)分和統(tǒng)計被寄生的和未感染的細胞。如果某些地區(qū)的工作人員沒有正確的專業(yè)知識,那么這種方法就不能很好地推廣,并且會導致一些問題?,F(xiàn)有工作已經(jīng)取得了一些進展,包括利用最先進的圖像處理和分析技術來提取手工設計的特征,并利用這些特性構(gòu)建基于機器學習的分類模型。但是,由于手工設計的部分需要花費大量的時間,當有更多的數(shù)據(jù)可供訓練時,模型卻無法及時的進行擴展。
深度學習模型,或更具體地說,卷積神經(jīng)網(wǎng)絡(CNN)在各種計算機視覺任務中獲得了非常好的效果。本文假設您已經(jīng)對 CNN 有一定的了解,但是如果您并不了解 CNN ,可以通過這篇文章進行深入了解。簡單來講,CNN 最關鍵的層主要包括卷積層和池化層,如下圖所示。
A typical CNN architeture (Source: deeplearning.net)
卷積層從數(shù)據(jù)中學習空間層級模式,這些模式具有平移不變性,因此卷積層能夠?qū)W習圖像的不同方面。例如,第一卷積層將學習諸如邊緣和角落的微型局部模式,第二卷積層將基于第一層所提取的特征,來學習更大的圖像模式,如此循序漸進。這使得 CNN 能夠自動進行特征工程,并且學習有效的特征,這些特征對新的數(shù)據(jù)具有很好的泛化能力。池化層常用于下采樣和降維。
因此,CNN 能夠幫助我們實現(xiàn)自動化的和可擴展的特征工程。此外,在模型的末端接入密集層,能夠使我們執(zhí)行圖像分類等任務。使用像CNN這樣的深度學習模型,進行自動化的瘧疾檢測,可能是一個高效、低成本、可擴展的方案。特別是隨著遷移學習的發(fā)展和預訓練模型的共享,在數(shù)據(jù)量較少等限制條件下,深度學習模型也能取得很好的效果。
Rajaraman 等人的論文 《Pre-trained convolutional neural networks as feature extractors toward improved parasite detection in thin blood smear images》利用 6 個預訓練模型,在進行瘧疾檢測時取得了 95.9% 的準確率。本文的重點是從頭開始嘗試一些簡單的 CNN 模型和一些預先訓練的模型,并利用遷移學習來檢驗我們在同一數(shù)據(jù)集下得到的結(jié)果。本文將使用 Python 和 TensorFlow 框架來構(gòu)建模型。
數(shù)據(jù)集的詳情
首先感謝 Lister Hill 國家生物醫(yī)學通信中心(LHNCBC)的研究人員(國家醫(yī)學圖書館(NLM)的部門),他們仔細收集并注釋了這個血涂片圖像的數(shù)據(jù)集,數(shù)據(jù)中包含健康和感染這兩種類型的血涂片圖像。您可以從官方網(wǎng)站上下載這些圖像。
實際上,他們開發(fā)了一款可以運行在標準安卓智能手機上的應用程序,該程序可以連接傳統(tǒng)的光學顯微鏡 (Poostchi et al., 2018) 。他們從孟加拉國吉大港醫(yī)學院附屬醫(yī)院進行拍照記錄了樣本集,其中包括150個惡性瘧原蟲感染的樣本和 50 個健康的樣本,每個樣本都是經(jīng)過 Giemsa 染色的薄血涂片。智能手機的內(nèi)置攝像頭可以捕獲樣本的每一個局部微觀視圖。來自泰國曼谷的瑪希隆-牛津熱帶醫(yī)學研究所的專業(yè)人員為這些圖像進行了手動注釋。讓我們簡要地看一下數(shù)據(jù)集結(jié)構(gòu)。首先根據(jù)本文所使用的操作系統(tǒng),我們需要安裝一些基本的依賴項。
本文所使用的系統(tǒng)是云上的 Debian 系統(tǒng),該系統(tǒng)配置有 GPU ,這能夠加速我們模型的訓練。首先安裝依賴樹,這能夠方便我們查看目錄結(jié)構(gòu)。(sudo apt install tree)
從上圖所示的目錄結(jié)構(gòu)中可以看到,我們的文件里包含兩個文件夾,分別包含受感染的和健康的細胞圖像。利用以下代碼,我們可以進一步了解圖像的總數(shù)是多少。
從上述結(jié)果可以看到, 瘧疾和非瘧疾(未感染)的細胞圖像的數(shù)據(jù)集均包含13779張圖片,兩個數(shù)據(jù)集的大小是相對平衡的。接下來我們將利用這些數(shù)據(jù)構(gòu)建一個基于pandas的dataframe類型的數(shù)據(jù),這對我們后續(xù)構(gòu)建數(shù)據(jù)集很有幫助。
import numpy as npimport pandas as pdnp.random.seed(42)files_df = pd.DataFrame({ 'filename': infected_files + healthy_files, 'label': ['malaria'] * len(infected_files) + ['healthy'] * len(healthy_files)}).sample(frac=1, random_state=42).reset_index(drop=True)files_df.head()
構(gòu)建和探索圖像數(shù)據(jù)集
在構(gòu)建深度學習模型之前,我們不僅需要訓練數(shù)據(jù),還需要未用于訓練的數(shù)據(jù)來驗證和測試模型的性能。本文采用 60:10:30 的比例來劃分訓練集、驗證集和測試集。我們將使用訓練集和驗證集來訓練模型,并利用測試集來檢驗模型的性能。
可以發(fā)現(xiàn),由于血液來源、測試方法以及圖像拍攝的方向不同,血液涂片和細胞的圖像尺寸不盡相同。我們需要獲取一些訓練數(shù)據(jù)的統(tǒng)計信息,從而確定最優(yōu)的圖像尺寸(請注意,在這里我們完全沒用到測試集!)。
import cv2from concurrent import futuresimport threadingdef get_img_shape_parallel(idx, img, total_imgs): if idx % 5000 == 0 or idx == (total_imgs - 1): print('{}: working on img num:{}'.format(threading.current_thread().name,idx)) return cv2.imread(img).shape ex = futures.ThreadPoolExecutor(max_workers=None)data_inp = [(idx, img, len(train_files)) for idx, img in enumerate(train_files)]print('Starting Img shape computation:')train_img_dims_map = ex.map(get_img_shape_parallel, [record[0] for record in data_inp], [record[1] for record in data_inp], [record[2] for record in data_inp])train_img_dims = list(train_img_dims_map)print('Min Dimensions:', np.min(train_img_dims, axis=0)) print('Avg Dimensions:', np.mean(train_img_dims, axis=0))print('Median Dimensions:', np.median(train_img_dims, axis=0))print('Max Dimensions:', np.max(train_img_dims, axis=0))# OutputStarting Img shape computation:ThreadPoolExecutor-0_0: working on img num: 0ThreadPoolExecutor-0_17: working on img num: 5000ThreadPoolExecutor-0_15: working on img num: 10000ThreadPoolExecutor-0_1: working on img num: 15000ThreadPoolExecutor-0_7: working on img num: 17360Min Dimensions: [46 46 3]Avg Dimensions: [132.77311215 132.45757733 3.]Median Dimensions: [130. 130. 3.]Max Dimensions: [385 394 3]
我們采用了并行處理的策略來加速圖像讀取操作?;趨R總的統(tǒng)計信息,我們決定將每張圖像的大小調(diào)整為125x125?,F(xiàn)在讓我們加載所有的圖像,并把他們的大小都調(diào)整為上述固定的尺寸。
我們再次運用了并行處理策略來加速圖像加載和尺寸調(diào)整的計算,如上面輸出結(jié)果中展示的,我們最終得到了所需尺寸的圖像張量?,F(xiàn)在我們可以查看一些樣本的細胞圖像,從而從直觀上認識一下我們的數(shù)據(jù)的情況。
import matplotlib.pyplot as plt%matplotlib inlineplt.figure(1 , figsize = (8 , 8))n = 0 for i in range(16): n += 1 r = np.random.randint(0 , train_data.shape[0] , 1) plt.subplot(4 , 4 , n) plt.subplots_adjust(hspace = 0.5 , wspace = 0.5) plt.imshow(train_data[r[0]]/255.) plt.title('{}'.format(train_labels[r[0]])) plt.xticks([]) , plt.yticks([])
從上面的樣本圖像可以看出,瘧疾和健康細胞圖像之間存在一些細微差別。我們將構(gòu)建深度學習模型,通過不斷訓練來使模型嘗試學習這些模式。在開始訓練模型之前,我們先對模型的參數(shù)進行一些基本的設置。
上面的代碼設定了圖像的維度,批尺寸,epoch 的次數(shù),并且對我們的類別標簽進行了編碼。TensorFLow 2.0 alpha 版本在2019年3月發(fā)布,它為我們項目的實施提供了一個完美的接口。
import tensorflow as tf# Load the TensorBoard notebook extension (optional)%load_ext tensorboard.notebooktf.random.set_seed(42)tf.__version__# Output'2.0.0-alpha0'
在模型訓練階段,我們將構(gòu)建幾個深度學習模型,利用前面構(gòu)建的訓練集進行訓練,并在驗證集上比較它們的性能。然后,我們將保存這些模型,并在模型評估階段再次使用它們。
模型1:從頭開始訓練CNN
對于本文的第一個瘧疾檢測模型,我們將構(gòu)建并從頭開始訓練一個基本的卷積神經(jīng)網(wǎng)絡(CNN)。首先,我們需要定義模型的結(jié)構(gòu)。
上述代碼所構(gòu)建的 CNN 模型,包含3個卷積層、1個池化層以及2個全連接層,并對全連接層設置 dropout 參數(shù)用于正則化?,F(xiàn)在讓我們開始訓練模型吧!
import datetimelogdir = os.path.join('/home/dipanzan_sarkar/projects/tensorboard_logs', datetime.datetime.now().strftime('%Y%m%d-%H%M%S'))tensorboard_callback = tf.keras.callbacks.TensorBoard(logdir,histogram_freq=1)reduce_lr = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss',factor=0.5,patience=2, min_lr=0.000001)callbacks = [reduce_lr, tensorboard_callback]history = model.fit(x=train_imgs_scaled, y=train_labels_enc, batch_size=BATCH_SIZE, epochs=EPOCHS, validation_data=(val_imgs_scaled, val_labels_enc), callbacks=callbacks, verbose=1) # OutputTrain on 17361 samples, validate on 1929 samplesEpoch 1/2517361/17361 [====] - 32s 2ms/sample - loss: 0.4373 - accuracy: 0.7814 - val_loss: 0.1834 - val_accuracy: 0.9393Epoch 2/2517361/17361 [====] - 30s 2ms/sample - loss: 0.1725 - accuracy: 0.9434 - val_loss: 0.1567 - val_accuracy: 0.9513......Epoch 24/2517361/17361 [====] - 30s 2ms/sample - loss: 0.0036 - accuracy: 0.9993 - val_loss: 0.3693 - val_accuracy: 0.9565Epoch 25/2517361/17361 [====] - 30s 2ms/sample - loss: 0.0034 - accuracy: 0.9994 - val_loss: 0.3699 - val_accuracy: 0.9559
從上面的結(jié)果可以看到,我們的模型在驗證集上的準確率為 95.6% ,這是非常好的。我們注意到模型在訓練集上的準確率為 99.9% ,這看起來有一些過擬合。為了更加清晰地查看這個問題,我們可以分別繪制在訓練和驗證階段的準確度曲線和損失曲線。
Learning Curves for Basic CNN
從圖中可以看出,在第5個 epoch 之后,在驗證集上的精度似乎不再提高。我們先將這個模型保存,在后面我們會再次用到它。
model.save('basic_cnn.h5')
就像人類能夠運用知識完成跨任務工作一樣,遷移學習使得我們能夠利用在先前任務中學習到的知識,來處理新的任務,在機器學習和深度學習的環(huán)境下也是如此。這些文章涵蓋了遷移學習的詳細介紹和討論,有興趣的讀者可以參考學習。
Ideas for deep transfer learning
我們能否采用遷移學習的思想,將預訓練的深度學習模型(已在大型數(shù)據(jù)集上進行過訓練的模型——例如 ImageNet)的知識應用到我們的問題——進行瘧疾檢測上呢?我們將采用兩種目前最主流的遷移學習策略。
將預訓練模型作為特征提取器
對預訓練模型進行微調(diào)
我們將使用由牛津大學視覺幾何組(VGG)所開發(fā)的預訓練模型 VGG-19 進行實驗。像 VGG-19 這樣的預訓練模型,一般已經(jīng)在大型數(shù)據(jù)集上進行過訓練,這些數(shù)據(jù)集涵蓋多種類別的圖像。基于此,這些預訓練模型應該已經(jīng)使用CNN模型學習到了一個具有高度魯棒性的特征的層次結(jié)構(gòu),并且其應具有尺度、旋轉(zhuǎn)和平移不變性。因此,這個已經(jīng)學習了超過一百萬個圖像的具有良好特征表示的模型,可以作為一個很棒的圖像特征提取器,為包括瘧疾檢測問題在內(nèi)的其他計算機視覺問題服務。在引入強大的遷移學習之前,我們先簡要討論一下 VGG-19 的結(jié)構(gòu)。
理解VGG-19模型
VGG-19 是一個具有 19 個層(包括卷積層和全連接層)的深度學習網(wǎng)絡,該模型基于 ImageNet 數(shù)據(jù)集進行訓練,該數(shù)據(jù)集是專門為圖像識別和分類所構(gòu)建的。VGG-19 是由 Karen Simonyan 和 Andrew Zisserman 提出的,該模型在他們的論文《Very Deep Convolutional Networks for Large-Scale Image Recognition》中有詳細介紹,建議有興趣的讀者可以去讀一讀這篇優(yōu)秀的論文。VGG-19 模型的結(jié)構(gòu)如下圖所示。
VGG-19 Model Architecture
從上圖可以清楚地看到,該模型具有 16 個使用 3x3 卷積核的卷積層,其中部分卷積層后面接了一個最大池化層,用于下采樣;隨后依次連接了兩個具有 4096 個隱層神經(jīng)元的全連接層,接著連接了一個具有 1000 個隱層神經(jīng)元的全連接層, 最后一個全連接層的每個神經(jīng)元都代表 ImageNet 數(shù)據(jù)集中的一個圖像類別。由于我們需要使用新的全連接層來分類瘧疾,因此我們不需要最后的三個全連接層。我們更關心的是前五個塊,以便我們可以利用 VGG 模型作為有效的特征提取器。
前文提到有兩種遷移學習的策略,對于第一種策略,我們將把 VGG 模型當做一個特征提取器,這可以通過凍結(jié)前五個卷積塊,使得它們的權重參數(shù)不會隨著新的訓練過程而更新來實現(xiàn)。對于第二種策略,我們將會解凍最后的兩個卷積塊(模塊4和模塊5),從而使得它們的參數(shù)會隨著新的訓練過程而不斷更新。
模型2:將預訓練模型作為特征提取機
為了構(gòu)建這個模型,我們將利用 TensorFlow 加載 VGG-19 模型,并凍結(jié)它的卷積塊,以便我們可以將其用作圖像特征提取器。我們將在該模型的末尾插入自己的全連接層,用于執(zhí)行本文的分類任務。
從上面代碼的輸出可以看到,我們的模型有很多層,并且我們僅僅只利用了 VGG-19 的凍結(jié)層來提取特征。下面的代碼可以驗證本模型中有多少層用于訓練,以及檢驗本模型中一共有多少層。
print('Total Layers:', len(model.layers))print('Total trainable layers:',sum([1 for l in model.layers if l.trainable]))# OutputTotal Layers: 28Total trainable layers: 6
現(xiàn)在我們將訓練該模型,在訓練過程中所用到的配置和回調(diào)函數(shù)與模型1中的類似,完整的代碼可以參考github鏈接。下圖展示了在訓練過程中,模型的準確度曲線和損失曲線。
Learning Curves for frozen pre-trained CNN
從上圖可以看出,該模型不像模型1中基本的 CNN 模型那樣存在過擬合的現(xiàn)象,但是性能并不是很好。事實上,它的性能還沒有基本的 CNN 模型好?,F(xiàn)在我們將模型保存,用于后續(xù)的評估。
模型3:具有圖像增廣的微調(diào)的預訓練模型
在這個模型中,我們將微調(diào)預訓練 VGG-19 模型的最后兩個區(qū)塊中層的權重。除此之外,我們還將介紹圖像增廣的概念。圖像增廣背后的原理與它的名稱聽起來完全一樣。我們首先從訓練數(shù)據(jù)集中加載現(xiàn)有的圖像,然后對它們進行一些圖像變換的操作,例如旋轉(zhuǎn),剪切,平移,縮放等,從而生成現(xiàn)有圖像的新的、變化的版本。由于這些隨機變換的操作,我們每次都會得到不同的圖像。我們將使用 tf.keras 中的 ImageDataGenerator 工具,它能夠幫助我們實現(xiàn)圖像增廣。
train_datagen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255, zoom_range=0.05, rotation_range=25, width_shift_range=0.05, height_shift_range=0.05, shear_range=0.05, horizontal_flip=True, fill_mode='nearest')val_datagen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255)# build image augmentation generatorstrain_generator = train_datagen.flow(train_data, train_labels_enc, batch_size=BATCH_SIZE, shuffle=True)val_generator = val_datagen.flow(val_data, val_labels_enc, batch_size=BATCH_SIZE, shuffle=False)
在驗證集上,我們只會對圖像進行縮放操作,而不進行其他的轉(zhuǎn)換,這是因為我們需要在每個訓練的 epoch 結(jié)束后,用驗證集來評估我們的模型。有關圖像增廣的詳細說明,可以參考這篇文章。讓我們來看看進行圖像增廣變換后的一些樣本結(jié)果。
Sample Augmented Images
從上圖可以清楚的看到圖像發(fā)生了輕微的變化?,F(xiàn)在我們將構(gòu)建新的深度模型,該模型需要確保 VGG-19 模型的最后兩個塊可以進行訓練。
vgg = tf.keras.applications.vgg19.VGG19(include_top=False, weights='imagenet',input_shape=INPUT_SHAPE)# Freeze the layersvgg.trainable = Trueset_trainable = Falsefor layer in vgg.layers: if layer.name in ['block5_conv1', 'block4_conv1']: set_trainable = True if set_trainable: layer.trainable = True else: layer.trainable = False base_vgg = vggbase_out = base_vgg.outputpool_out = tf.keras.layers.Flatten()(base_out)hidden1 = tf.keras.layers.Dense(512, activation='relu')(pool_out)drop1 = tf.keras.layers.Dropout(rate=0.3)(hidden1)hidden2 = tf.keras.layers.Dense(512, activation='relu')(drop1)drop2 = tf.keras.layers.Dropout(rate=0.3)(hidden2)out = tf.keras.layers.Dense(1, activation='sigmoid')(drop2)model = tf.keras.Model(inputs=base_vgg.input, outputs=out)model.compile(optimizer=tf.keras.optimizers.RMSprop(lr=1e-5),loss='binary_crossentropy',metrics=['accuracy'])print('Total Layers:', len(model.layers))print('Total trainable layers:', sum([1 for l in model.layers if l.trainable]))# OutputTotal Layers: 28Total trainable layers: 16
由于我們不希望在微調(diào)過程中,對預訓練的層進行較大的權重更新,我們降低了模型的學習率。由于我們使用數(shù)據(jù)生成器來加載數(shù)據(jù),本模型的訓練過程會和之前稍稍不同,在這里,我們需要用到函數(shù) fit_generator(…) 。
下圖展示了該模型的訓練曲線,可以看出該模型是這三個模型中最好的模型,其驗證準確度幾乎達到了 96.5% ,而且從訓練準確度上看,我們的模型也沒有像第一個模型那樣出現(xiàn)過擬合。
Learning Curves for fine-tuned pre-trained CNN
現(xiàn)在讓我們保存這個模型,很快我們將在測試集上用到它進行性能評估。
model.save( 'vgg_finetuned.h5')
至此,模型訓練階段告一段落,我們即將在真實的測試集上去測試這些模型的性能。
深度學習模型的性能評估階段
現(xiàn)在,我們將對之前訓練好的三個模型進行評估。僅僅使用驗證集來評估模型的好壞是不夠的, 因此,我們將使用測試集來進一步評估模型的性能。我們構(gòu)建了一個實用的模塊 model_evaluation_utils,該模塊采用相關的分類指標,用于評估深度學習模型的性能。首先我們需要將測試數(shù)據(jù)進行縮放。
第二步是加載之前所保存的深度學習模型,然后在測試集上進行預測。
# Load Saved Deep Learning Modelsbasic_cnn = tf.keras.models.load_model('./basic_cnn.h5')vgg_frz = tf.keras.models.load_model('./vgg_frozen.h5')vgg_ft = tf.keras.models.load_model('./vgg_finetuned.h5')# Make Predictions on Test Databasic_cnn_preds = basic_cnn.predict(test_imgs_scaled, batch_size=512)vgg_frz_preds = vgg_frz.predict(test_imgs_scaled, batch_size=512)vgg_ft_preds = vgg_ft.predict(test_imgs_scaled, batch_size=512)basic_cnn_pred_labels = le.inverse_transform([1 if pred > 0.5 else 0 for pred in basic_cnn_preds.ravel()])vgg_frz_pred_labels = le.inverse_transform([1 if pred > 0.5 else 0 for pred in vgg_frz_preds.ravel()])vgg_ft_pred_labels = le.inverse_transform([1 if pred > 0.5 else 0 for pred in vgg_ft_preds.ravel()])
最后一步是利用 model_evaluation_utils 模塊,根據(jù)不同的分類評價指標,來評估每個模型的性能。
從圖中可以看到,第三個模型在測試集上的性能是最好的,其準確度和 f1-score 都達到了96%,這是一個非常好的結(jié)果,而且這個結(jié)果和論文中提到的更為復雜的模型所得到的結(jié)果具有相當?shù)?可比性!
本文研究了一個有趣的醫(yī)學影像案例——瘧疾檢測。瘧疾檢測是一個復雜的過程,而且能夠進行正確操作的醫(yī)療人員也很少,這是一個很嚴重的問題。本文利用 AI 技術構(gòu)建了一個開源的項目,該項目在瘧疾檢測問題上具有最高的準確率,并使AI技術為社會帶來了效益。