在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于深度學習和遷移學習方法,對瘧疾等傳染病檢測問題進行了研究

電子工程師 ? 來源:lq ? 2019-05-05 11:21 ? 次閱讀

文本基于深度學習和遷移學習方法,對瘧疾等傳染病檢測問題進行了研究。作者對瘧疾的檢測原理以及遷移學習理論進行了介紹,并使用VGG-19預訓練模型,進行了基于特征提取和基于參數微調的遷移學習實踐。

前言

"健康就是財富",這是一個老生常談的話題,但不得不說這是一個真理。在這篇文章中,我們將研究如何利用AI技術來檢測一種致命的疾病——瘧疾。本文將提出一個低成本、高效率和高準確率的開源解決方案。本文有兩個目的:1.了解瘧疾的傳染原因和其致命性;2、介紹如何運用深度學習有效檢測瘧疾。本章的主要內容如下:

開展本項目的動機

瘧疾檢測的方法

用深度學習檢測瘧疾

從頭開始訓練卷積神經網絡(CNN)

利用預訓練模型進行遷移學習

本文不是為了宣揚 AI 將要取代人類的工作,或者接管世界等論調,而是僅僅展示 AI 是如何用一種低成本、高效率和高準確率的方案,來幫助人類去檢測和診斷瘧疾,并盡量減少人工操作。

Python and TensorFlow?—?A great combo to build open-source deep learning solutions

在本文中,我們將使用 Python 和 tensorflow ,來構建一個強大的、可擴展的、有效的深度學習解決方案。這些工具都是免費并且開源的,這使得我們能夠構建一個真正低成本、高效精準的解決方案,而且可以讓每個人都可以輕松使用。讓我們開始吧!

動機

瘧疾是經瘧蚊叮咬而感染瘧原蟲所引起的蟲媒傳染病,瘧疾最常通過受感染的雌性瘧蚊來傳播。雖然我們不必詳細了解這種疾病,但是我們需要知道瘧疾有五種常見的類型。下圖展示了這種疾病的致死性在全球的分布情況。

Malaria Estimated Risk Heath Map (Source: treated.com)

從上圖中可以明顯看到,瘧疾遍布全球,尤其是在熱帶區域分布密集。本項目就是基于這種疾病的特性和致命性來開展的,下面我們舉個例子來說明。起初,如果你被一只受感染的蚊子叮咬了,那么蚊子所攜帶的寄生蟲就會進入你的血液,并且開始摧毀你體內的攜氧紅細胞。通常來講,你會在被瘧蚊叮咬后的幾天或幾周內感到不適,一般會首先出現類似流感或者病毒感染的癥狀。然而,這些致命的寄生蟲可以在你身體里完好地存活超過一年的時間,并且不產生任何其他癥狀!延遲接受正確的治療,可能會導致并發癥甚至死亡。因此,早期并有效的瘧疾檢測和排查可以挽救這些生命。

世界衛生組織(WHO)發布了幾個關于瘧疾的重要事實,詳情見此。簡而言之,世界上將近一半的人口面臨瘧疾風險,每年有超過2億的瘧疾病例,以及有大約40萬人死于瘧疾。這些事實讓我們認識到,快速簡單高效的瘧疾檢查是多么重要,這也是本文的動機所在。

瘧疾檢查的方法

文章《 Pre-trained convolutional neural networks as feature extractors toward improved Malaria parasite detection in thin blood smear images》(本文的數據和分析也是基于這篇文章)簡要介紹了瘧疾檢測的幾種方法,這些方法包括但是不限于厚薄血涂片檢查、聚合酶鏈式反應(PCR)和快速診斷測試(RDT)。在本文中,我們沒有對這些方法進行詳細介紹,但是需要注意的一點是,后兩種方法常常作為替代方案使用,尤其是在缺乏高質量顯微鏡服務的情況下。

我們將簡要討論基于血液涂片檢測流程的標準瘧疾診斷方法,首先感謝 Carlos Ariza 的博文,以及 Adrian Rosebrock 關于瘧疾檢查的文章,這兩篇文章讓我們對瘧疾檢查領域有了更為深入的了解。

A blood smear workflow for Malaria detection (Source)

根據上圖所示的 WHO 的血液涂片檢測流程,該工作包括在100倍放大倍數下對血涂片進行深入檢查,其中人們需要從5000個細胞中,手動檢測出含有寄生蟲的紅細胞。Rajaraman 等人的論文中更加詳細的給出了相關的描述,如下所示:

厚血涂片有助于檢測寄生蟲的存在,而薄血涂片有助于識別引起感染的寄生蟲種類(Centers for Disease Control and Prevention, 2012)。診斷準確性在很大程度上取決于人類的專業知識,并且可能受到觀察者間的差異和觀察者的可靠性所帶來的不利影響,以及受到在疾病流行或資源受限的區域內的大規模診斷造成的負擔所帶來的不利影響(Mitiku,Mengistu&Gelaw,2003)。替代技術,例如聚合酶鏈式反應(PCR)和快速診斷測試(RDT),也會被使用;但是PCR分析受到其性能的限制(Hommelsheim等,2014),而RDT在疾病流行地區的成本效益較低(Hawkes,Katsuva&Masumbuko,2009)。

因此,傳統的瘧疾檢測絕對是一個密集的手工過程,或許深度學習技術可以幫助它完成自動化。上文提到的這些內容為后文打下了基礎。

用深度學習檢測瘧疾

手工診斷血液涂片,是一項重復且規律的工作,而且需要一定的專業知識來區分和統計被寄生的和未感染的細胞。如果某些地區的工作人員沒有正確的專業知識,那么這種方法就不能很好地推廣,并且會導致一些問題。現有工作已經取得了一些進展,包括利用最先進的圖像處理和分析技術來提取手工設計的特征,并利用這些特性構建基于機器學習的分類模型。但是,由于手工設計的部分需要花費大量的時間,當有更多的數據可供訓練時,模型卻無法及時的進行擴展。

深度學習模型,或更具體地說,卷積神經網絡(CNN)在各種計算機視覺任務中獲得了非常好的效果。本文假設您已經對 CNN 有一定的了解,但是如果您并不了解 CNN ,可以通過這篇文章進行深入了解。簡單來講,CNN 最關鍵的層主要包括卷積層和池化層,如下圖所示。

A typical CNN architeture (Source: deeplearning.net)

卷積層從數據中學習空間層級模式,這些模式具有平移不變性,因此卷積層能夠學習圖像的不同方面。例如,第一卷積層將學習諸如邊緣和角落的微型局部模式,第二卷積層將基于第一層所提取的特征,來學習更大的圖像模式,如此循序漸進。這使得 CNN 能夠自動進行特征工程,并且學習有效的特征,這些特征對新的數據具有很好的泛化能力。池化層常用于下采樣和降維。

因此,CNN 能夠幫助我們實現自動化的和可擴展的特征工程。此外,在模型的末端接入密集層,能夠使我們執行圖像分類等任務。使用像CNN這樣的深度學習模型,進行自動化的瘧疾檢測,可能是一個高效、低成本、可擴展的方案。特別是隨著遷移學習的發展和預訓練模型的共享,在數據量較少等限制條件下,深度學習模型也能取得很好的效果。

Rajaraman 等人的論文《Pre-trained convolutional neural networks as feature extractors toward improved parasite detection in thin blood smear images》利用 6 個預訓練模型,在進行瘧疾檢測時取得了 95.9% 的準確率。本文的重點是從頭開始嘗試一些簡單的 CNN 模型和一些預先訓練的模型,并利用遷移學習來檢驗我們在同一數據集下得到的結果。本文將使用 Python 和 TensorFlow 框架來構建模型。

數據集的詳情

首先感謝 Lister Hill 國家生物醫學通信中心(LHNCBC)的研究人員(國家醫學圖書館(NLM)的部門),他們仔細收集并注釋了這個血涂片圖像的數據集,數據中包含健康和感染這兩種類型的血涂片圖像。您可以從官方網站上下載這些圖像。

實際上,他們開發了一款可以運行在標準安卓智能手機上的應用程序,該程序可以連接傳統的光學顯微鏡 (Poostchi et al., 2018) 。他們從孟加拉國吉大港醫學院附屬醫院進行拍照記錄了樣本集,其中包括150個惡性瘧原蟲感染的樣本和 50 個健康的樣本,每個樣本都是經過 Giemsa 染色的薄血涂片。智能手機的內置攝像頭可以捕獲樣本的每一個局部微觀視圖。來自泰國曼谷的瑪希隆-牛津熱帶醫學研究所的專業人員為這些圖像進行了手動注釋。讓我們簡要地看一下數據集結構。首先根據本文所使用的操作系統,我們需要安裝一些基本的依賴項。

本文所使用的系統是云上的 Debian 系統,該系統配置有 GPU ,這能夠加速我們模型的訓練。首先安裝依賴樹,這能夠方便我們查看目錄結構。(sudo apt install tree)

從上圖所示的目錄結構中可以看到,我們的文件里包含兩個文件夾,分別包含受感染的和健康的細胞圖像。利用以下代碼,我們可以進一步了解圖像的總數是多少。

import osimport globbase_dir = os.path.join('./cell_images')infected_dir = os.path.join(base_dir,'Parasitized')healthy_dir = os.path.join(base_dir,'Uninfected')infected_files = glob.glob(infected_dir+'/*.png')healthy_files = glob.glob(healthy_dir+'/*.png')len(infected_files), len(healthy_files)# Output(13779, 13779)

從上述結果可以看到, 瘧疾和非瘧疾(未感染)的細胞圖像的數據集均包含13779張圖片,兩個數據集的大小是相對平衡的。接下來我們將利用這些數據構建一個基于pandas的dataframe類型的數據,這對我們后續構建數據集很有幫助。

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()

構建和探索圖像數據集

在構建深度學習模型之前,我們不僅需要訓練數據,還需要未用于訓練的數據來驗證和測試模型的性能。本文采用 60:10:30 的比例來劃分訓練集、驗證集和測試集。我們將使用訓練集和驗證集來訓練模型,并利用測試集來檢驗模型的性能。

from sklearn.model_selection import train_test_splitfrom collections import Countertrain_files, test_files, train_labels, test_labels = train_test_split(files_df['filename'].values, files_df['label'].values, test_size=0.3, random_state=42)train_files, val_files, train_labels, val_labels = train_test_split(train_files, train_labels, test_size=0.1, random_state=42)print(train_files.shape, val_files.shape, test_files.shape)print('Train:', Counter(train_labels), ' Val:', Counter(val_labels), ' Test:', Counter(test_labels))# Output(17361,) (1929,) (8268,)Train: Counter({'healthy': 8734, 'malaria': 8627}) Val: Counter({'healthy': 970, 'malaria': 959}) Test: Counter({'malaria': 4193, 'healthy': 4075})

可以發現,由于血液來源、測試方法以及圖像拍攝的方向不同,血液涂片和細胞的圖像尺寸不盡相同。我們需要獲取一些訓練數據的統計信息,從而確定最優的圖像尺寸(請注意,在這里我們完全沒用到測試集!)。

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).shapeex = 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]

我們采用了并行處理的策略來加速圖像讀取操作。基于匯總的統計信息,我們決定將每張圖像的大小調整為125x125。現在讓我們加載所有的圖像,并把他們的大小都調整為上述固定的尺寸。

IMG_DIMS = (125, 125)def get_img_data_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)) img = cv2.imread(img) img = cv2.resize(img, dsize=IMG_DIMS, interpolation=cv2.INTER_CUBIC) img = np.array(img, dtype=np.float32) return imgex = futures.ThreadPoolExecutor(max_workers=None)train_data_inp = [(idx, img, len(train_files)) for idx, img in enumerate(train_files)]val_data_inp = [(idx, img, len(val_files)) for idx, img in enumerate(val_files)]test_data_inp = [(idx, img, len(test_files)) for idx, img in enumerate(test_files)]print('Loading Train Images:')train_data_map = ex.map(get_img_data_parallel, [record[0] for record in train_data_inp], [record[1] for record in train_data_inp], [record[2] for record in train_data_inp])train_data = np.array(list(train_data_map))print(' Loading Validation Images:')val_data_map = ex.map(get_img_data_parallel, [record[0] for record in val_data_inp], [record[1] for record in val_data_inp], [record[2] for record in val_data_inp])val_data = np.array(list(val_data_map))print(' Loading Test Images:')test_data_map = ex.map(get_img_data_parallel, [record[0] for record in test_data_inp], [record[1] for record in test_data_inp], [record[2] for record in test_data_inp])test_data = np.array(list(test_data_map))train_data.shape, val_data.shape, test_data.shape # OutputLoading Train Images:ThreadPoolExecutor-1_0: working on img num: 0ThreadPoolExecutor-1_12: working on img num: 5000ThreadPoolExecutor-1_6: working on img num: 10000ThreadPoolExecutor-1_10: working on img num: 15000ThreadPoolExecutor-1_3: working on img num: 17360Loading Validation Images:ThreadPoolExecutor-1_13: working on img num: 0ThreadPoolExecutor-1_18: working on img num: 1928Loading Test Images:ThreadPoolExecutor-1_5: working on img num: 0ThreadPoolExecutor-1_19: working on img num: 5000ThreadPoolExecutor-1_8: working on img num: 8267((17361, 125, 125, 3), (1929, 125, 125, 3), (8268, 125, 125, 3))

我們再次運用了并行處理策略來加速圖像加載和尺寸調整的計算,如上面輸出結果中展示的,我們最終得到了所需尺寸的圖像張量。現在我們可以查看一些樣本的細胞圖像,從而從直觀上認識一下我們的數據的情況。

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([])

從上面的樣本圖像可以看出,瘧疾和健康細胞圖像之間存在一些細微差別。我們將構建深度學習模型,通過不斷訓練來使模型嘗試學習這些模式。在開始訓練模型之前,我們先對模型的參數進行一些基本的設置。

BATCH_SIZE = 64NUM_CLASSES = 2EPOCHS = 25INPUT_SHAPE = (125, 125, 3)train_imgs_scaled = train_data / 255.val_imgs_scaled = val_data / 255.# encode text category labelsfrom sklearn.preprocessing import LabelEncoderle = LabelEncoder()le.fit(train_labels)train_labels_enc = le.transform(train_labels)val_labels_enc = le.transform(val_labels)print(train_labels[:6], train_labels_enc[:6])# Output['malaria' 'malaria' 'malaria' 'healthy' 'healthy' 'malaria'][1 1 1 0 0 1]

上面的代碼設定了圖像的維度,批尺寸,epoch 的次數,并且對我們的類別標簽進行了編碼。TensorFLow 2.0 alpha 版本在2019年3月發布,它為我們項目的實施提供了一個完美的接口

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'

深度學習模型的訓練階段

在模型訓練階段,我們將構建幾個深度學習模型,利用前面構建的訓練集進行訓練,并在驗證集上比較它們的性能。然后,我們將保存這些模型,并在模型評估階段再次使用它們。

模型1:從頭開始訓練CNN

對于本文的第一個瘧疾檢測模型,我們將構建并從頭開始訓練一個基本的卷積神經網絡(CNN)。首先,我們需要定義模型的結構。

inp = tf.keras.layers.Input(shape=INPUT_SHAPE)conv1 = tf.keras.layers.Conv2D(32, kernel_size=(3, 3), activation='relu', padding='same')(inp)pool1 = tf.keras.layers.MaxPooling2D(pool_size=(2, 2))(conv1)conv2 = tf.keras.layers.Conv2D(64, kernel_size=(3, 3), activation='relu', padding='same')(pool1)pool2 = tf.keras.layers.MaxPooling2D(pool_size=(2, 2))(conv2)conv3 = tf.keras.layers.Conv2D(128, kernel_size=(3, 3), activation='relu', padding='same')(pool2)pool3 = tf.keras.layers.MaxPooling2D(pool_size=(2, 2))(conv3)flat = tf.keras.layers.Flatten()(pool3)hidden1 = tf.keras.layers.Dense(512, activation='relu')(flat)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=inp, outputs=out)model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])model.summary()# OutputModel: "model"_________________________________________________________________Layer (type) Output Shape Param # =================================================================input_1 (InputLayer) [(None, 125, 125, 3)] 0 _________________________________________________________________conv2d (Conv2D) (None, 125, 125, 32) 896 _________________________________________________________________max_pooling2d (MaxPooling2D) (None, 62, 62, 32) 0 _________________________________________________________________conv2d_1 (Conv2D) (None, 62, 62, 64) 18496 _________________________________________________________________......_________________________________________________________________dense_1 (Dense) (None, 512) 262656 _________________________________________________________________dropout_1 (Dropout) (None, 512) 0 _________________________________________________________________dense_2 (Dense) (None, 1) 513 =================================================================Total params: 15,102,529Trainable params: 15,102,529Non-trainable params: 0_________________________________________________________________

上述代碼所構建的 CNN 模型,包含3個卷積層、1個池化層以及2個全連接層,并對全連接層設置 dropout 參數用于正則化。現在讓我們開始訓練模型吧!

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

從上面的結果可以看到,我們的模型在驗證集上的準確率為 95.6% ,這是非常好的。我們注意到模型在訓練集上的準確率為 99.9% ,這看起來有一些過擬合。為了更加清晰地查看這個問題,我們可以分別繪制在訓練和驗證階段的準確度曲線和損失曲線。

f, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))t = f.suptitle('Basic CNN Performance', fontsize=12)f.subplots_adjust(top=0.85, wspace=0.3)max_epoch = len(history.history['accuracy'])+1epoch_list = list(range(1,max_epoch))ax1.plot(epoch_list, history.history['accuracy'], label='Train Accuracy')ax1.plot(epoch_list, history.history['val_accuracy'], label='Validation Accuracy')ax1.set_xticks(np.arange(1, max_epoch, 5))ax1.set_ylabel('Accuracy Value')ax1.set_xlabel('Epoch')ax1.set_title('Accuracy')l1 = ax1.legend(loc="best")ax2.plot(epoch_list, history.history['loss'], label='Train Loss')ax2.plot(epoch_list, history.history['val_loss'], label='Validation Loss')ax2.set_xticks(np.arange(1, max_epoch, 5))ax2.set_ylabel('Loss Value')ax2.set_xlabel('Epoch')ax2.set_title('Loss')l2 = ax2.legend(loc="best")

Learning Curves for BasicCNN

從圖中可以看出,在第5個 epoch 之后,在驗證集上的精度似乎不再提高。我們先將這個模型保存,在后面我們會再次用到它。

model.save('basic_cnn.h5')

深度遷移學習

就像人類能夠運用知識完成跨任務工作一樣,遷移學習使得我們能夠利用在先前任務中學習到的知識,來處理新的任務,在機器學習和深度學習的環境下也是如此。這些文章涵蓋了遷移學習的詳細介紹和討論,有興趣的讀者可以參考學習。

Ideas for deep transferlearning

我們能否采用遷移學習的思想,將預訓練的深度學習模型(已在大型數據集上進行過訓練的模型——例如 ImageNet)的知識應用到我們的問題——進行瘧疾檢測上呢?我們將采用兩種目前最主流的遷移學習策略。

將預訓練模型作為特征提取器

對預訓練模型進行微調

我們將使用由牛津大學視覺幾何組(VGG)所開發的預訓練模型 VGG-19 進行實驗。像 VGG-19 這樣的預訓練模型,一般已經在大型數據集上進行過訓練,這些數據集涵蓋多種類別的圖像。基于此,這些預訓練模型應該已經使用CNN模型學習到了一個具有高度魯棒性的特征的層次結構,并且其應具有尺度、旋轉和平移不變性。因此,這個已經學習了超過一百萬個圖像的具有良好特征表示的模型,可以作為一個很棒的圖像特征提取器,為包括瘧疾檢測問題在內的其他計算機視覺問題服務。在引入強大的遷移學習之前,我們先簡要討論一下 VGG-19 的結構。

理解VGG-19模型

VGG-19 是一個具有 19 個層(包括卷積層和全連接層)的深度學習網絡,該模型基于 ImageNet 數據集進行訓練,該數據集是專門為圖像識別和分類所構建的。VGG-19 是由 Karen Simonyan 和 Andrew Zisserman 提出的,該模型在他們的論文《Very Deep Convolutional Networks for Large-Scale Image Recognition》中有詳細介紹,建議有興趣的讀者可以去讀一讀這篇優秀的論文。VGG-19 模型的結構如下圖所示。

VGG-19 Model Architecture

從上圖可以清楚地看到,該模型具有 16 個使用 3x3 卷積核的卷積層,其中部分卷積層后面接了一個最大池化層,用于下采樣;隨后依次連接了兩個具有 4096 個隱層神經元的全連接層,接著連接了一個具有 1000 個隱層神經元的全連接層, 最后一個全連接層的每個神經元都代表 ImageNet 數據集中的一個圖像類別。由于我們需要使用新的全連接層來分類瘧疾,因此我們不需要最后的三個全連接層。我們更關心的是前五個塊,以便我們可以利用 VGG 模型作為有效的特征提取器。

前文提到有兩種遷移學習的策略,對于第一種策略,我們將把 VGG 模型當做一個特征提取器,這可以通過凍結前五個卷積塊,使得它們的權重參數不會隨著新的訓練過程而更新來實現。對于第二種策略,我們將會解凍最后的兩個卷積塊(模塊4和模塊5),從而使得它們的參數會隨著新的訓練過程而不斷更新。

模型2:將預訓練模型作為特征提取機

為了構建這個模型,我們將利用 TensorFlow 加載 VGG-19 模型,并凍結它的卷積塊,以便我們可以將其用作圖像特征提取器。我們將在該模型的末尾插入自己的全連接層,用于執行本文的分類任務。

vgg = tf.keras.applications.vgg19.VGG19(include_top=False, weights='imagenet',input_shape=INPUT_SHAPE)vgg.trainable = False# Freeze the layersfor layer in vgg.layers: layer.trainable = Falsebase_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-4),loss='binary_crossentropy',metrics=['accuracy'])model.summary()# OutputModel: "model_1"_________________________________________________________________Layer (type) Output Shape Param # =================================================================input_2 (InputLayer) [(None, 125, 125, 3)] 0 _________________________________________________________________block1_conv1 (Conv2D) (None, 125, 125, 64) 1792 _________________________________________________________________block1_conv2 (Conv2D) (None, 125, 125, 64) 36928 _________________________________________________________________......_________________________________________________________________block5_pool (MaxPooling2D) (None, 3, 3, 512) 0 _________________________________________________________________flatten_1 (Flatten) (None, 4608) 0 _________________________________________________________________dense_3 (Dense) (None, 512) 2359808 _________________________________________________________________dropout_2 (Dropout) (None, 512) 0 _________________________________________________________________dense_4 (Dense) (None, 512) 262656 _________________________________________________________________dropout_3 (Dropout) (None, 512) 0 _________________________________________________________________dense_5 (Dense) (None, 1) 513 =================================================================Total params: 22,647,361Trainable params: 2,622,977Non-trainable params: 20,024,384

從上面代碼的輸出可以看到,我們的模型有很多層,并且我們僅僅只利用了 VGG-19 的凍結層來提取特征。下面的代碼可以驗證本模型中有多少層用于訓練,以及檢驗本模型中一共有多少層。

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

現在我們將訓練該模型,在訓練過程中所用到的配置和回調函數與模型1中的類似,完整的代碼可以參考github鏈接。下圖展示了在訓練過程中,模型的準確度曲線和損失曲線。

Learning Curves for frozen pre-trained CNN

從上圖可以看出,該模型不像模型1中基本的 CNN 模型那樣存在過擬合的現象,但是性能并不是很好。事實上,它的性能還沒有基本的 CNN 模型好。現在我們將模型保存,用于后續的評估。

model.save( 'vgg_frozen.h5')

模型3:具有圖像增廣的微調的預訓練模型

在這個模型中,我們將微調預訓練 VGG-19 模型的最后兩個區塊中層的權重。除此之外,我們還將介紹圖像增廣的概念。圖像增廣背后的原理與它的名稱聽起來完全一樣。我們首先從訓練數據集中加載現有的圖像,然后對它們進行一些圖像變換的操作,例如旋轉,剪切,平移,縮放等,從而生成現有圖像的新的、變化的版本。由于這些隨機變換的操作,我們每次都會得到不同的圖像。我們將使用 tf.keras 中的 ImageDataGenerator 工具,它能夠幫助我們實現圖像增廣。

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)

在驗證集上,我們只會對圖像進行縮放操作,而不進行其他的轉換,這是因為我們需要在每個訓練的 epoch 結束后,用驗證集來評估我們的模型。有關圖像增廣的詳細說明,可以參考這篇文章。讓我們來看看進行圖像增廣變換后的一些樣本結果。

img_id = 0sample_generator = train_datagen.flow(train_data[img_id:img_id+1], train_labels[img_id:img_id+1],batch_size=1)sample = [next(sample_generator) for i in range(0,5)]fig, ax = plt.subplots(1,5, figsize=(16, 6))print('Labels:', [item[1][0] for item in sample])l = [ax[i].imshow(sample[i][0][0]) for i in range(0,5)]

Sample Augmented Images

從上圖可以清楚的看到圖像發生了輕微的變化。現在我們將構建新的深度模型,該模型需要確保 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 = Falsebase_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

由于我們不希望在微調過程中,對預訓練的層進行較大的權重更新,我們降低了模型的學習率。由于我們使用數據生成器來加載數據,本模型的訓練過程會和之前稍稍不同,在這里,我們需要用到函數 fit_generator(…) 。

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]train_steps_per_epoch = train_generator.n //train_generator.batch_sizeval_steps_per_epoch = val_generator.n //val_generator.batch_sizehistory = model.fit_generator(train_generator, steps_per_epoch=train_steps_per_epoch,epochs=EPOCHS,validation_data=val_generator,validation_steps=val_steps_per_epoch,verbose=1)# OutputEpoch 1/25271/271 [====] - 133s 489ms/step - loss: 0.2267 - accuracy: 0.9117 - val_loss: 0.1414 - val_accuracy: 0.9531Epoch 2/25271/271 [====] - 129s 475ms/step - loss: 0.1399 - accuracy: 0.9552 - val_loss: 0.1292 - val_accuracy: 0.9589......Epoch 24/25271/271 [====] - 128s 473ms/step - loss: 0.0815 - accuracy: 0.9727 - val_loss: 0.1466 - val_accuracy: 0.9682Epoch 25/25271/271 [====] - 128s 473ms/step - loss: 0.0792 - accuracy: 0.9729 - val_loss: 0.1127 - val_accuracy: 0.9641

下圖展示了該模型的訓練曲線,可以看出該模型是這三個模型中最好的模型,其驗證準確度幾乎達到了 96.5% ,而且從訓練準確度上看,我們的模型也沒有像第一個模型那樣出現過擬合。

Learning Curves for fine-tuned pre-trained CNN

現在讓我們保存這個模型,很快我們將在測試集上用到它進行性能評估。

model.save( 'vgg_finetuned.h5')

至此,模型訓練階段告一段落,我們即將在真實的測試集上去測試這些模型的性能。

深度學習模型的性能評估階段

現在,我們將對之前訓練好的三個模型進行評估。僅僅使用驗證集來評估模型的好壞是不夠的, 因此,我們將使用測試集來進一步評估模型的性能。我們構建了一個實用的模塊 model_evaluation_utils,該模塊采用相關的分類指標,用于評估深度學習模型的性能。首先我們需要將測試數據進行縮放。

test_imgs_scaled = test_data / 255.test_imgs_scaled.shape, test_labels.shape# Output((8268, 125, 125, 3), (8268,))

第二步是加載之前所保存的深度學習模型,然后在測試集上進行預測。

# 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([1ifpred>0.5else0forpredinvgg_ft_preds.ravel()])

最后一步是利用 model_evaluation_utils 模塊,根據不同的分類評價指標,來評估每個模型的性能。

import model_evaluation_utils as meuimport pandas as pdbasic_cnn_metrics = meu.get_metrics(true_labels=test_labels, predicted_labels=basic_cnn_pred_labels)vgg_frz_metrics = meu.get_metrics(true_labels=test_labels, predicted_labels=vgg_frz_pred_labels)vgg_ft_metrics = meu.get_metrics(true_labels=test_labels, predicted_labels=vgg_ft_pred_labels)pd.DataFrame([basic_cnn_metrics, vgg_frz_metrics, vgg_ft_metrics], index=['Basic CNN', 'VGG-19 Frozen', 'VGG-19 Fine-tuned'])

從圖中可以看到,第三個模型在測試集上的性能是最好的,其準確度和 f1-score 都達到了96%,這是一個非常好的結果,而且這個結果和論文中提到的更為復雜的模型所得到的結果具有相當的 可比性!

結論

本文研究了一個有趣的醫學影像案例——瘧疾檢測。瘧疾檢測是一個復雜的過程,而且能夠進行正確操作的醫療人員也很少,這是一個很嚴重的問題。本文利用 AI 技術構建了一個開源的項目,該項目在瘧疾檢測問題上具有最高的準確率,并使AI技術為社會帶來了效益。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • python
    +關注

    關注

    56

    文章

    4807

    瀏覽量

    85040
  • 深度學習
    +關注

    關注

    73

    文章

    5515

    瀏覽量

    121553
  • ai技術
    +關注

    關注

    1

    文章

    1290

    瀏覽量

    24459

原文標題:醫生再添新助手!深度學習診斷傳染病 | 完整代碼+實操

文章出處:【微信號:rgznai100,微信公眾號:rgznai100】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    通過快速納米傳感器技術診斷防治傳染病

    要改變全世界對傳染病檢測、診斷和監測,并開發一種能夠快速得出準確、可靠結果的設備,需要做些什么?
    發表于 07-19 15:04 ?3388次閱讀
    通過快速納米傳感器技術診斷防治<b class='flag-5'>傳染病</b>

    基于深度學習的異常檢測研究方法

    研究方法進行了系統而全面的綜述。此外,我們回顧了這些方法在不同應用領域中的應用,并評估了它們的有效性。我們根據所采用的基本假設和方法,將最
    發表于 07-12 07:10

    基于深度學習的異常檢測研究方法

    ABSTRACT1.基于深度學習的異常檢測研究方法進行結構化和全面的概述2.回顧這些
    發表于 07-12 06:36

    遷移學習

    神經網絡訓練方法卷積神經網絡介紹經典網絡結構介紹章節目標:深入了解神經網絡的組成、訓練和實現,掌握深度空間特征分布關鍵概念,為深度遷移
    發表于 04-21 15:15

    模型驅動深度學習的標準流程與學習方法解析

    模型驅動的深度學習方法近年來,深度學習在人工智能領域一系列困難問題上取得了突破性成功應用。
    的頭像 發表于 01-24 11:30 ?4968次閱讀
    模型驅動<b class='flag-5'>深度</b><b class='flag-5'>學習</b>的標準流程與<b class='flag-5'>學習方法</b>解析

    深度學習在IoT大數據和流分析中的應用

    這篇論文對于使用深度學習來改進IoT領域的數據分析和學習方法進行了詳細的綜述。
    的頭像 發表于 03-01 11:05 ?7796次閱讀
    <b class='flag-5'>深度</b><b class='flag-5'>學習</b>在IoT大數據和流分析中的應用

    VR傳染病防治系統助力生命健康知識的科普

    VR傳染病防治系統助力生命健康常識科普,近期疫情嚴重,防疫知識不得不學起來,但是目前的防疫科普知識大部分都是采用手抄報、觀看視頻、名人講座或者到相應的展館展廳進行觀看形式,但是過程繁瑣復雜,加上
    發表于 06-28 17:39 ?846次閱讀

    機器學習方法遷移學習的發展和研究資料說明

    近年來,遷移學習已經引起了廣泛的關注和研究遷移學習是運用已存有的知識對不同但相關領域問題進行
    發表于 07-17 08:00 ?0次下載
    機器<b class='flag-5'>學習方法</b><b class='flag-5'>遷移</b><b class='flag-5'>學習</b>的發展和<b class='flag-5'>研究</b>資料說明

    FlightSense?技術運用高精度接近檢測助力客戶開發創新的傳染病防護設備

    中國,2020年7月21日 – 橫跨多重電子應用領域的全球領先的半導體供應商意法半導體(STMicroelectronics,簡稱ST;紐約證券交易所代碼:STM)運用其高精度接近檢測及測距傳感器助力客戶開發創新的傳染病防護設備,以應對全球蔓延的疫情所帶來的挑戰。
    發表于 08-06 16:19 ?560次閱讀

    鼠疫傳染病優化算法PDO及研究綜述

    為了求解多局部最優解的優化問題,采用具有脈沖預防接種的時滯鼠疫傳染病動力學模型,提出了種新的群智能算法——鼠疫傳染病優化算法(PDO)。在該算法中,假設某個村莊生活有若干村民,每個村民均由一些特征來
    發表于 05-11 16:23 ?2次下載

    基于多維時空數據的傳染病可視分析系統

    基于多維時空數據的傳染病可視分析系統
    發表于 06-27 14:42 ?8次下載

    如何通過快速納米傳感器技術診斷防治傳染病

    要改變全世界對傳染病檢測、診斷和監測,并開發一種能夠快速得出準確、可靠結果的設備,需要做些什么?
    發表于 08-03 17:21 ?871次閱讀

    使用深度學習方法對音樂流派進行分類

    電子發燒友網站提供《使用深度學習方法對音樂流派進行分類.zip》資料免費下載
    發表于 02-08 10:02 ?1次下載
    使用<b class='flag-5'>深度</b><b class='flag-5'>學習方法</b>對音樂流派<b class='flag-5'>進行</b>分類

    半導體制冷技術應用--傳染病POC分析儀

    傳染病POC分析儀是一種專門用于檢測傳染病病原體的小型化便攜式醫療設備。它具有結構簡單緊湊、操作簡便、多通道高效并行檢測、結果判定快速顯著
    的頭像 發表于 06-18 10:03 ?790次閱讀
    半導體制冷技術應用--<b class='flag-5'>傳染病</b>POC分析儀

    深度學習中的無監督學習方法綜述

    應用中往往難以實現。因此,無監督學習深度學習中扮演著越來越重要的角色。本文旨在綜述深度學習中的無監督
    的頭像 發表于 07-09 10:50 ?948次閱讀
    主站蜘蛛池模板: 国产精品免费视频拍拍拍 | h网址在线观看 | 久青草国产免费观看 | 国产精品夜夜春夜夜爽 | 日本黄色小说视频 | 酒色成人网 | 全部在线播放免费毛片 | 欧美a一| 欧美综合天天夜夜久久 | 亚洲一区三区 | 国产在线理论片免费播放 | 噜噜噜天天躁狠狠躁夜夜精品 | 七月丁香八月婷婷综合激情 | 天堂网欧美 | 亚洲射图 | 男女性接交无遮挡免费看视频 | 免费国产不卡午夜福在线观看 | 色尼玛亚洲综合 | 激情综合婷婷丁香六月花 | 日韩1 | 美女视频黄a | 色精品一区二区三区 | 国产成人精品曰本亚洲77美色 | 久久性生活 | 久久国产精品亚洲综合 | 欧美一级片在线免费观看 | 欧美天堂在线观看 | 五月天毛片 | 一级毛片免费不卡直观看 | 毛片你懂的 | 男女爱爱爽爽福利免费视频 | 永久免费在线看 | 国产午夜三区视频在线 | 亚洲综合久久久久久888 | 呦交小u女国产秘密入口 | 国产黄在线观看 | 色花堂国产精品首页第一页 | 激情综合网五月激情 | 理论片久久 | 国产激烈床戏无遮挡在线观看 | 国产一区二区中文字幕 |