?譯者 | 朱先忠
審校 | 孫淑娟
遷移學習是機器學習的一種類型,它是一種應用于已經訓練或預訓練的神經網絡的方法,而且這些預訓練的神經元網絡是使用數百萬個數據點訓練出來的。
該技術目前最著名的用法是用來訓練深度神經網絡,因為這種方法在使用較少的數據訓練深度神經網絡時表現出良好的性能。實際上,這種技術在數據科學領域也是很有用的,因為大多數真實世界的數據通常沒有數百萬個數據點來訓練出穩固的深度學習模型。
目前,已經存在許多使用數百萬個數據點訓練出來的模型,并且這些模型可以用于以最大精度來訓練復雜的深度學習神經網絡。
在本教程中,您將學習到如何使用遷移學習技術來訓練一個深度神經網絡的完整過程。
使用Keras程序實現遷移學習
在構建或訓練深度神經網絡之前,您必須搞清楚有哪些選擇方案可用于遷移學習,以及必須使用哪個方案來為項目訓練復雜的深度神經網絡。
Keras應用程序是一種高級的深度學習模型,它提供了可用于預測、特征提取和微調的預訓練權重。Keras庫中內置提供了許多現成可用的模型,其中一些流行的模型包括:
- Xception
- VGG16 and VGG19
- ResNet Series
- MobileNet
【補充】Keras應用程序提供了一組深度學習模型,它們可與預先訓練的權重一起使用。有關這些模型的更具體的內容,請參考??Keras官網內容??。
在本文中,您將學習??MobileNet模型??在遷移學習中的應用。
訓練一個深度學習模型
在本節中,您將學習如何在短短的幾個步驟內為圖像識別構建一個自定義深度學習模型,而無需編寫任何一系列卷積神經網絡(CNN),您只需對預訓練的模型加以微調,即可使得您的模型在訓練數據集上進行訓練。
在本文中,我們構建的深度學習模型將能夠識別手勢語言數字的圖像。接下來,讓我們開始著手構建這個自定義深度學習模型。
獲取數據集
要開始構建一個深度學習模型的過程,您首先需要準備好數據,您可以通過訪問一個名為Kaggle的網站,從數百萬個數據集中輕松選擇合適的數據集。當然,也存在不少其他網站為構建深度學習或機器學習模型提供可用的數據集。
但本文將使用的數據集取自Kaggle網站提供的??美國手語數字數據集??。
數據預處理
在下載數據集并將其保存到本地存儲之后,現在是時候對數據集執行一些預處理了,比如準備數據、將數據拆分為train目錄、valid目錄和test目錄、定義它們的路徑以及為訓練目的創建批處理,等等。
準備數據
下載數據集時,它包含從0到9數據的目錄,其中有三個子文件夾分別對應輸入圖像、輸出圖像以及一個名稱為CSV的文件夾。
接著,從每個目錄中刪除輸出圖像和CSV文件夾,將輸入圖像文件夾下的內容移動到主目錄下,然后刪除輸入圖像文件夾。
數據集的每個主目錄現在都擁有500幅圖像,您可以選擇保留所有圖像。但出于演示目的,本文中每個目錄中只使用其中的200幅圖像。
最終,數據集的結構將如下圖所示:
數據集的文件夾結構
分割數據集
現在,讓我們從將數據集拆分為train、valid和test三個子目錄開始。
- train目錄將包含訓練數據,這些數據將作為我們輸入模型的輸入數據,用于學習模式和不規則性。
- valid目錄將包含將被輸入到模型中的驗證數據,并且將是模型所看到的第一個未看到的數據,這將有助于獲得最大的準確性。
- test目錄將包含用于測試模型的測試數據。
首先,我們來導入將在代碼中進一步使用的庫。
下面是生成所需目錄并將數據移動到特定目錄的代碼。
在上面的代碼中,我們首先更改了數據集在本地存儲中對應的目錄,然后檢查是否已經存在train/0目錄;如果沒有,我們將分別創建train、valid和test子目錄。
然后,我們創建子目錄0到9,并將所有數據移動到train目錄中,同時創建了valid和test這兩個子目錄下各自的子目錄0至9。
然后,我們在train目錄內的子目錄0到9上進行迭代,并從每個子目錄中隨機獲取90個圖像數據,并將它們移動到valid目錄內的相應子目錄。
對于測試目錄test也是如此。
【補充】在Python中執行高級文件操作的shutil模塊(手動將文件或文件夾從一個目錄復制或移動到另一個目錄可能是一件非常痛苦的事情。有關詳細技巧,請參考文章https://medium.com/@geekpython/perform-high-level-file-operations-in-python-shutil-module-dfd71b149d32)。
定義到各目錄的路徑
創建所需的目錄后,現在需要定義train、valid和test這三個子目錄的路徑。
進行預處理
預訓練的深度學習模型需要一些預處理的數據,這些數據非常適合訓練。因此,數據需要采用預訓練模型所需的格式。
在應用任何預處理之前,讓我們導入TensorFlow及其實用程序,這些實用程序將在代碼中進一步使用。
我們使用了ImageDatagenerator,它采用了一個參數preprocessing_function,在該函數參數中,我們對MobileNet模型提供的圖像進行了預處理。
接下來,調用flow_from_directory函數,其中我們提供了要訓練圖像的目錄和維度的路徑,因為MobileNet模型是為具有224x224維度的圖像訓練使用的。
再接下來,定義了批量大小——定義一次迭代中可以處理多少圖像,然后我們對圖像處理順序進行隨機打亂。在此,我們沒有針對測試數據的圖像進行隨機亂序,因為測試數據不會用于訓練。
在Jupyter筆記本或Google Colab中運行上述代碼片斷后,您將看到如下結果。
上述代碼的輸出結果
ImageDataGenerator的一般應用場景是用于增廣數據,以下是使用Keras框架中ImageDataGenerator執行數據增廣的??指南??。
創建模型
在將訓練和驗證數據擬合到模型中之前,深度學習模型MobileNet需要通過添加輸出層、刪除不必要的層以及使某些層不可訓練,從而獲得更好的準確性來進行微調。
以下代碼將從Keras下載MobileNet模型并將其存儲在mobile變量中。您需要在第一次運行以下代碼片斷時連接到因特網。
如果您運行以下代碼,那么您將看到模型的摘要信息,在其中你可以看到一系列神經網絡層的輸出信息。
現在,我們將在模型中添加以10為單位的全連接輸出層(也稱“稠密層”)——因為從0到9將有10個輸出。此外,我們從MobileNet模型中刪除了最后六個層。
然后,我們將所有輸入和輸出層添加到模型中。
現在,我們將最后23層設置成不可訓練的——其實這是一個相對隨意的數字。一般來說,這一具體數字是通過多次試驗和錯誤獲得的。該代碼的唯一目的是通過使某些層不可訓練來提高精度。
如果您看到了微調模型的摘要輸出,那么您將注意到與前面看到的原始摘要相比,不可訓練參數和層的數量存在一些差異。
接下來,我們要編譯名為Adam的優化器,選擇學習率為0.0001,以及損失函數,還有衡量模型的準確性的度量參數。
現在是準備好模型并根據訓練和驗證數據來開始訓練的時候了。在下面的代碼中,我們提供了訓練和驗證數據以及訓練的總體輪回數。詳細信息只是為了顯示準確性進度,在這里您可以指定一個數字參數值為0、1或者2。
如果您運行上面的代碼片斷,那么您將看到訓練數據丟失和準確性的輪回的每一步的輸出內容。對于驗證數據,您也能夠看到這樣的輸出結果。
顯示有精度值的訓練輪回步數
存儲模型
該模型現在已準備就緒,準確度得分為99%。現在請記住一件事:這個模型可能存在過度擬合,因此有可能對于給定數據集圖像以外的圖像表現不佳。
上面的代碼將檢查是否已經有模型的副本。如果沒有,則通過調用save函數在指定的路徑中保存模型。
測試模型
至此,模型已經經過訓練,可以用于識別圖像了。本節將介紹加載模型和編寫準備圖像、預測結果以及顯示和打印預測結果的函數。
在編寫任何代碼之前,需要導入一些將在代碼中進一步使用的必要的庫。
加載定制的模型
對圖像的預測將使用上面使用遷移學習技術創建的模型進行。因此,我們首先需要加載該模型,以供后面使用。
在此,我們通過使用load_model函數,實現從指定路徑加載模型,并將其存儲在my_model變量中,以便在后面代碼中進一步使用。
準備輸入圖像
在向模型提供任何用于預測或識別的圖像之前,我們需要提供模型所需的格式。
首先,我們要定義一個獲取圖像路徑的函數preprocess_img,然后使用image實用程序中的load_img函數加載該圖像,并將目標大小設置為224x224。然后將該圖像轉換成一個數組,并將該數組除以255.0,這樣就將圖像的像素值轉換為0和1,然后將圖像數組重新調整為形狀(224,224,3),最后返回轉換形狀后的圖像。
編寫預測函數
這里,我們定義了一個函數predict_result,它接受predict參數,此參數基本上是一個預處理的圖像。然后,我們調用模型的predict函數來預測結果。最后,從預測結果中返回最大值。
顯示與預測圖像
首先,我們將創建一個函數,它負責獲取圖像的路徑,然后顯示圖像和預測結果。
上面這個函數display_and_predict首先獲取圖像的路徑并使用PIL庫中的Image.open函數打開該圖像,然后使用matplotlib庫來顯示圖像,然后將圖像傳遞給preprep_img函數以便輸出預測結果,最后使用predict_result函數獲得結果并最終打印。
如果您運行上面的程序片斷并輸入數據集中圖像的路徑,那么您將得到所期望的輸出。
預測結果示意圖
請注意,到目前為止該模型是使用遷移學習技術成功創建的,而無需編寫任何一系列神經網絡層相關代碼。
現在,這個模型可以用于開發能夠進行圖像識別的Web應用程序了。文章的最后所附鏈接處提供了如何將該模型應用到Flask應用程序中的完整實現源碼。
結論
本文中我們介紹了使用預先訓練的模型或遷移學習技術來制作一個定制的深度學習模型的過程。
到目前為止,您已經了解了創建一個完整的深度學習模型所涉及的每一步。歸納起來看,所使用的總體步驟包括:
- 準備數據集
- 預處理數據
- 創建模型
- 保存自定義模型
- 測試自定義模型
最后,您可以從??GitHub??上獲取本文示例項目完整的源代碼。
譯者介紹
朱先忠,51CTO社區編輯,51CTO專家博客、講師,濰坊一所高校計算機教師,自由編程界老兵一枚。
原文標題:??Trained A Custom Deep Learning Model Using A Transfer Learning Technique???,作者:Sachin Pal?