『TensorFlow』遷移學習

徹底版見github:TransforLearninggit

零、遷移學習

將一個領域的已經成熟的知識應用到其餘的場景中稱爲遷移學習。用神經網絡的角度來表述,就是一層層網絡中每一個節點的權重從一個訓練好的網絡遷移到一個全新的網絡裏,而不是從頭開始,爲每特定的個任務訓練一個神經網絡。github

假設你已經有了一個能夠高精確度分辨貓和狗的深度神經網絡,你以後想訓練一個可以分別不一樣品種的狗的圖片模型,你須要作的不是從頭訓練那些用來分辨直線,銳角的神經網絡的前幾層,而是利用訓練好的網絡,提取初級特徵,以後只訓練最後幾層神經元,讓其能夠分辨狗的品種。節省資源是遷移學習最大意義之一,舉圖像識別中最多見的例子,訓練一個神經網絡。來識別不一樣的品種的貓,你如果從頭開始訓練,你須要百萬級的帶標註數據,海量的顯卡資源。而如果使用遷移學習,你可使用Google發佈的Inception或VGG16這樣成熟的物品分類的網絡,只訓練最後的softmax層,你只須要幾千張圖片,使用普通的CPU就能完成,並且模型的準確性不差。api

使用遷徙學習時要注意,原本預訓練的神經網絡要和當前的任務差距不大,否則遷徙學習的效果會不好。例如若是你要訓練一個神經網絡來識別肺部X光片中是否包含腫瘤,那麼使用VGG16的網絡就不如使用一個已訓練好的判斷腦部是否包含腫瘤的神經網絡。後者與當前的任務有類似的場景,不少底層的神經員能夠作相同的事,而用來識別平常生活中照片的網絡,則難以從X光片中提取有效的特徵。數組

另外一種遷移學習的方法是對整個網絡進行微調(fine turing),假設你已訓練好了識別貓品種的神經網絡,你的網絡能對50種貓按品種進行分類。接下來你想對網絡進行升級,讓其可以識別100種貓,這時你不該該只訓練網絡的最後一層,而應該逐層對網絡中每一個節點的權重進行微調。顯然,只訓練最後幾層,是遷移學習最簡單的1.0版,而對節點權重進行微調,就是更難的2.0版,經過將其餘層的權重固定,只訓練一層這樣的逐層訓練,能夠更好的完成上述任務。bash

遷移方式和數據集規模關係

 

1)右下角場景,待訓練的數據集較小,已訓練的模型和當前任務類似。此時能夠只是從新訓練已有模型的靠近輸出的幾層,例如將ImageNet中輸出層原來能夠判別一萬種輸出的網絡改的只能判別貓的品種,從而利用已有網絡來作低層次的特徵提取。網絡

2)左下角場景,待訓練的數據集較小,已訓練的模型和當前任務場景差距較大。例如你有的已訓練網絡能識別出白天高速路上的違章車輛,你須要訓練一個能識別出夜間違章車輛的模型,因爲無論白天夜晚,交通規則是沒有變化的,因此你須要將網絡靠近輸入的那幾層從新訓練,等到新的網絡可以提取出夜間車輛的基本信息後,就能夠借用已有的,在大數據集下訓練好的神經網絡來識別違章車輛,而不用等夜間違章的車輛的照片積累的足夠多以後再從新訓練。框架

3)左上角場景,待訓練的數據集較大,已有的模型和新模型的數據差別度很高。此時應該作的是從頭開始,從新訓練。curl

4)右上角場景,待訓練的數據集較大,已有模型的訓練數據和現有的訓練數據相似。此時應該使用原網絡的結構微調。函數

1、實驗目的

使用google已經訓練好的模型,將最後的全鏈接層修改成咱們本身的全鏈接層,將原有的1000分類分類器修改成咱們本身的5分類分類器,利用原有模型的特徵提取能力實現咱們本身數據對應模型的快速訓練。實際中對於一個陌生的數據集,原有模型通過不高的迭代次數便可得到很好的準確率。學習

2、代碼實戰

實機文件夾以下:

花朵圖片數據下載:

curl -O http://download.tensorflow.org/example_images/flower_photos.tgz

已經訓練好的Inception-v3的1000分類模型下載:

wget https://storage.googleapis.com/download.tensorflow.org/models/inception_dec_2015.zip

遷移學習代碼以及使用指南見github,本次的代碼能夠將新保存的模型遷移到本身的數據集上,並對本身的數據進行預測。

新添加的測試部分,直接運行TransferLearning_reload.py便可,輸出以下,

第二行白字的五個值對應第一行的5個分類的機率。

 

3、問題&建議

1.建議從main函數開始閱讀,跳到哪裏讀到那裏;

2.我給的註釋很詳盡,原書《TensorFlow實戰Google深度學習框架》也有更爲詳盡的註釋,因此這裏很少說了

 

以前本部分對輸入圖片的過程進行了分析,當時水平有限,如今看來很幼稚,實際上分析一下圖上節點便可瞭解:

  • InceptionV3接受二進制數據便可自行解碼,即接收open().read()的二進制流便可
  • 保存的模型文件Graph包含了InceptionV3和新的classer,可是二者是隔離的,這是因爲程序中並沒將二者聯通,是先把InceptionV3的瓶頸張量feed出來,而後是用這個數組去feed新的classer,可是因爲saver、InceptionV三、classer使用的sess是同一個,因此最終二者都保存在了model模型中
相關文章
相關標籤/搜索