1. 程式人生 > >keras-遷移學習(fine-tuning)

keras-遷移學習(fine-tuning)

不同修改預訓練模型方式的情況:

  1. 特徵提取
    我們可以將預訓練模型當做特徵提取裝置來使用。具體的做法是,將輸出層去掉,然後將剩下的整個網路當做一個固定的特徵提取機,從而應用到新的資料集中。
  2. 採用預訓練模型的結構
    我們還可以採用預訓練模型的結構,但先將所有的權重隨機化,然後依據自己的資料集進行訓練。
  3. 訓練特定層,凍結其它層
    另一種使用預訓練模型的方法是對它進行部分的訓練。具體的做法是,將模型起始的一些層的權重保持不變,重新訓練後面的層,得到新的權重。在這個過程中,我們可以多次進行嘗試,從而能夠依據結果找到frozen layers和retrain layers之間的最佳搭配。
    如何使用與訓練模型,是由資料集大小和新舊資料集(預訓練的資料集和我們要解決的資料集)之間資料的相似度來決定的。
    下圖表展示了在各種情況下應該如何使用預訓練模型:
    在這裡插入圖片描述

    原文:https://blog.csdn.net/u011268787/article/details/80170482

fine-tuning方式一:使用預訓練網路的bottleneck特徵

先看VGG-16的網路結構如下:
在這裡插入圖片描述
本節主要是通過已經訓練好的模型,把bottleneck特徵抽取出來,然後滾到下一個“小”模型裡面,也就是全連線層。
實施步驟為:

1、把訓練好的模型的權重拿來,model;
2、執行,提取bottleneck feature(網路在全連線之前的最後一層啟用的feature
map,卷積-全連線層之間),單獨拿出來,並儲存
3、bottleneck層資料,之後 + dense全連線層,進行fine-tuning

1、匯入預訓練權重與網路框架

WEIGHTS_PATH = '/home/ubuntu/keras/animal5/vgg16_weights_tf_dim_ordering_tf_kernels.h5' 
WEIGHTS_PATH_NO_TOP = '/home/ubuntu/keras/animal5/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5' 
from keras.applications.vgg16_matt import VGG16 
model = VGG16(include_top=False, weights='imagenet')

其中WEIGHTS_PATH_NO_TOP 就是去掉了全連線層,可以用他直接提取bottleneck的特徵

2、提取圖片的bottleneck特徵

需要步驟:

1. 載入圖片;
2. 灌入pre-model的權重;
3. 得到bottleneck feature

程式碼:

#如何提取bottleneck feature 
from keras.models import Sequential 
from keras.layers import Conv2D, MaxPooling2D 
from keras.layers import Activation, Dropout, Flatten, Dense
# (1)載入圖片 
# 影象生成器初始化 
from keras.preprocessing.image import ImageDataGenerator 
import numpy as np 
datagen = ImageDataGenerator(rescale=1./255)
# 訓練集影象生成器 
generator = datagen.flow_from_directory( '/home/ubuntu/keras/animal5/train', 
				target_size=(150, 150), batch_size=32, class_mode=None, shuffle=False) 
# 驗證集影象生成器 
generator = datagen.flow_from_directory( '/home/ubuntu/keras/animal5/validation', 
				target_size=(150, 150), batch_size=32, class_mode=None, shuffle=False)
				
#(2)灌入pre-model的權重
model.load_weights('/.../vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5')

#(3)得到bottleneck feature 
bottleneck_features_train = model.predict_generator(generator, 500) 
#核心,steps是生成器要返回資料的輪數,每個epoch含有500張圖片,與model.fit(samples_per_epoch)相對 
np.save(open('bottleneck_features_train.npy', 'w'), bottleneck_features_train)

bottleneck_features_validation = model.predict_generator(generator, 100) 
#與model.fit(nb_val_samples)相對,一個epoch有800張圖片,驗證集 
np.save(open('bottleneck_features_validation.npy', 'w'), bottleneck_features_validation)

3、 fine-tuning - "小"網路

主要步驟:

(1)匯入bottleneck_features資料;
(2)設定標籤,並規範成Keras預設格式;
(3)寫“小網路”的網路結構
(4)設定引數並訓練

在這裡插入圖片描述

fine-tuning方式二:要調整權重

先來看看整個結構。
在這裡插入圖片描述
fine-tune分三個步驟:

  1. 搭建vgg-16並載入權重,將之前定義的全連線網路加在模型的頂部,並載入權重
  2. 凍結vgg16網路的一部分引數
  3. 模型訓練

注意:

1、fine-tune,所有的層都應該以訓練好的權重為初始值,例如,你不能將隨機初始的全連線放在預訓練的卷積層之上,這是因為由隨機權重產生的大梯度將會破壞卷積層預訓練的權重。
2、選擇只fine-tune最後的卷積塊,而不是整個網路,這是為了防止過擬合。整個網路具有巨大的熵容量,因此具有很高的過擬合傾向。由底層卷積模組學習到的特徵更加一般,更加不具有抽象性,因此我們要保持前兩個卷積塊(學習一般特徵)不動,只fine-tune後面的卷積塊(學習特別的特徵)
3、fine-tune應該在很低的學習率下進行,通常使用SGD優化而不是其他自適應學習率的優化演算法,如RMSProp。這是為了保證更新的幅度保持在較低的程度,以免毀壞預訓練的特徵。

1、步驟一:搭建vgg-16並載入權重

在這裡插入圖片描述

2、凍結vgg16網路的一部分引數

然後將最後一個卷積塊前的卷積層引數凍結:
在這裡插入圖片描述

3、模型訓練

然後以很低的學習率進行訓練:
在這裡插入圖片描述