遷移學習實踐與理解

2021-08-20 05:45:19 字數 3276 閱讀 5862

出於硬體條件以及資料集**的限制,我從一開始就想到了遷移學習的方法,利用已經訓練成熟的模型去做調整。遷移學習有很多方式,可以大致分為三種:利用模型結構、提取瓶頸特徵(bottleneck features )、微調(fine-tuning)

利用模型結構

這個是最基礎的遷移學習,只利用別人的模型框架,所有權重重新訓練。但是這種遷移學習並不適合裝置條件差的我。。。

提取瓶頸特徵(bottleneck features )

簡單來說,將資料input到已經訓練好的模型(本文用的vgg16),但不是為了得到最後一層的output,而是從中間的某一層抽取出來作為bottleneck features。因為深度學習中間過程其實都是在提取特徵,我們可以自己選擇某一層作為bottleneck features。如下圖:

具體步驟:

1:載入去掉top層的model

2:提取bottleneck features,儲存到本地

3:搭建小型分類模型,從本地讀取bottleneck features,作為輸入進行訓練

這種遷移學習的方式已經滿足了我對準確率的要求,達到80%

微調(fine-tuning)

與提取瓶頸特徵的區別在於,fine-tuning釋放了最後乙個卷積層的權重,當然釋放那一層都可以,按需釋放即可。如下圖:

藍色:權重鎖定,不可用訓練

黃色:權重釋放,可以訓練

綠色:最終分類器,可訓練

在構建這個遷移學習的模型時遇到了大坑,官網文件是錯誤的,搜尋了很多解決方案沒有可行的,最後利用了乙個小技巧跑通了模型。具體如下:

1:官網給的例子是用了前面提取瓶頸特徵時構建的分類器作為vgg16的top層,**如下:

# 載入沒有top層的vgg16

# 構建和提取瓶頸方法一樣的網路結構

top_model = sequential()

top_model.add(flatten(input_shape=model.output_shape[1:]))

top_model.add(dense(256, activation='relu'))

top_model.add(dropout(0.5))

top_model.add(dense(1, activation='sigmoid'))

# 將提取瓶頸方法訓練儲存的權重載入進去

top_model.load_weights(top_model_weights_path)

# 將剛搭建好的模型連線到vgg16上,這裡會報錯!!!!!!

model.add(top_model)

為什麼要大費周折載入之前訓練好的top層的權重,然後再重新訓練呢?官網給的解釋是這樣可以在訓練是不用隨機初始化權重,不容易過擬合。

然後,將最後乙個卷積層的權重釋放掉:

for layer in model.layers[:25]:

layer.trainable = false

這個方案看起來很美好,但是它居然報錯。。。

最後一句報錯,為什麼?因為vgg16原始碼是model模式的,而我們搭建的是sequential模式的,所以不相容導致報錯。

2:既然不相容那就讓它們相容唄——用model模式編寫,說起來很簡單,但是目前為止各大技術論壇上都沒有找到靠譜的解決方案。因為用model寫投票層時會用到flatten層,這一層嘗試各種方式都會報錯。

3:既然都不能解決問題,那麼就從源頭換個角度思考。我們費這麼大勁載入top層的權重然後重新訓練,不如直接跳過這一步,過擬合什麼的解決方案很多,最關鍵的是能跑通的方案才算得上是乙個方案。

下面就是我的解決思路了:

1:將vgg16全部load進來

2:將最後三層pop掉,再加上三層自己需要的dense層

3:釋放掉最後乙個卷積塊的權重,訓練

def

vgg16_model

(img_rows, img_cols, num_classes=5):

model = vgg16(weights='imagenet', include_top=true)

model.layers.pop()

model.layers.pop()

model.layers.pop()

model.outputs = [model.layers[-1].output]

x=dense(1024, activation='relu')(model.layers[-1].output)

x=dense(128, activation='relu')(x)

x=dense(num_classes, activation='softmax')(x)

model=model(model.input,x)

for layer in model.layers[:15]:

layer.trainable = false

sgd = sgd(lr=1e-3, decay=1e-6, momentum=0.9, nesterov=true)

model.compile(optimizer=sgd, loss='categorical_crossentropy', metrics=['accuracy'])

model.summary()

return model

2. 新增 gitattributes檔案,這步及其關鍵,後面步驟和之前一樣

git add .gitattributes

3. 新增其他檔案並commit,push

git add yourlargefile.h5

git add test.txt

git commit -m "something"

git push -u origin master

原理:lfs跟蹤大檔案,臨時儲存,在需要的時候才會儲存複製操作,親測git clone有效。

可能碰見的坑:github 和 git bash沒有保持統一更新,所以保持同步一下就行。

遷移學習與增量學習

日常處理資料過程中,我們會遇到新資料的增加這個問題,我們既想增加新資料,又想利用原先的模型,遷移學習和增量學習就應運而生了,而且在今後的發展中,此類問題會越來越頻發。首先推薦幾篇部落格來 一下這個問題 1 xgboost之增量學習 遷移學習,增量學習增強學習 增量學習 遷移學習 概念性認知機器學習基...

django資料遷移實踐

背景 開始和同事結對開發,一人乙個sqlite3檔案資料庫來儲存配置,有兩個問題 使用django的migrate很麻煩,還得寫db router等控制同步 後來上線發現個問題,那就是檔案資料庫寫的時候會觸發uwsgi的touch reload機制而重啟專案 專案會繼續開發下去資料量會變多,檔案資料...

flask limiter 實踐與原理解析

乙個強大的軟體產品是由許多不同的元件結合完成的,其中在每乙個產品中離不開的就是api系統,api系統在整個產品中居於中樞地位,包括系統內部元件,及客戶對產品的對接都要與api打交道,這就需要最大限度的提高api的處理能力,並且防範無效請求,還有黑客的惡意攻擊。限流可以在nginx層進行設定,當然在a...