1.爲什麼神經網絡可以使用預訓練模型?
所謂使用預訓練的模型,就是使用別人已經訓練好的模型及參數,雖然利用到的數據集不同,但是前幾層幾乎做的事情是相同的,就拿CNN舉例,前幾層都是在找一些簡單的線條,對於足夠大的網絡和足夠多的數據,前幾層找到的線條是普適的,這也就是爲什麼我們可以使用預訓練模型。
2.如何使用預訓練模型?
使用預訓練模型,我們就需要固定住前幾層的參數,而後幾層的參數(尤其是全連接的部分)需要我們根據手頭的任務進行訓練得出,以CNN爲例,我們在使用這個預訓練模型時,就要固定住(frozen)其卷積基,訓練全連接的部分,也就是所謂分類器的部分。
以keras內置的模型VGG16爲例(此模型是由兩個連續的卷積層加一個池化層重複兩次和三個連續的卷積層加一個池化層重複三次構成),其引入的代碼如下
from keras.applications import VGG16
conv_base = VGG16(weights='imagenet',include_top=False,input_shape=(150,150,3))
其中weights指定其參數由imagnet這個數據集訓練獲得,inlude_top指明是否引入全連接部分,input_shape用於修改爲自己輸入圖片的大小,此參數可以不填。
from keras import models,layers
network = models.Squential()
network.add(conv_base)
network.add(layers.Flatten())
network.add(layers.Dense(512,activation='relu'))
network.add(layers.Dropout(0.5))
network.add(layers.Dense(1,activation='sigmoid'))
conv_base.trainable = False
構建好神經網絡後,訓練方式與前面類似
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
train_datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
train_dir,
target_size=(150, 150),
batch_size=20,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
validation_dir,
target_size=(150, 150),
batch_size=20,
class_mode='binary')
model.compile(loss='binary_crossentropy',
optimizer=optimizers.RMSprop(lr=2e-5),
metrics=['acc'])
history = model.fit_generator(
train_generator,
steps_per_epoch=100,
epochs=30,
validation_data=validation_generator,
validation_steps=50)
3.Fine-tuning
使用fine-tuning時,我們要力求不對模型做太大的改變,並且即使改變也儘量只改變模型的最後幾層,因爲這幾層更貼近我們自己的任務,此外,我們需要先將自己的全連接層部分的權重參數訓練好後,採用較小的學習率再進行微調,這樣纔可以避免由於預測類標與實際類標相差過大而導致模型後幾層權重參數也改變過大的情況發生。