使用 Keras 和 VGG 進行轉學習
在這個例子中,提出了三個簡短而全面的子示例:
- 從 Keras 庫附帶的可用預訓練模型載入重量
- 在 VGG 的任何層之上堆疊另一個網路進行培訓
- 在其他圖層的中間插入圖層
- 使用 VGG 進行微調和轉移學習的提示和一般經驗法則
載入預先訓練的重量
預先訓練上 ImageNet 車型,其中包括 VGG-16 和 VGG-19 中,都可以 Keras 。在此示例中,將使用 VGG-16 。有關更多資訊,請訪問 Keras Applications 文件 。
from keras import applications
# This will load the whole VGG16 network, including the top Dense layers.
# Note: by specifying the shape of top layers, input tensor shape is forced
# to be (224, 224, 3), therefore you can use it only on 224x224 images.
vgg_model = applications.VGG16(weights='imagenet', include_top=True)
# If you are only interested in convolution filters. Note that by not
# specifying the shape of top layers, the input tensor shape is (None, None, 3),
# so you can use them for any size of images.
vgg_model = applications.VGG16(weights='imagenet', include_top=False)
# If you want to specify input tensor
from keras.layers import Input
input_tensor = Input(shape=(160, 160, 3))
vgg_model = applications.VGG16(weights='imagenet',
include_top=False,
input_tensor=input_tensor)
# To see the models' architecture and layer names, run the following
vgg_model.summary()
使用從 VGG 獲取的底層建立新網路
假設對於尺寸為 (160, 160, 3)
的影象的某些特定任務,你希望使用預先訓練的 VGG 底層,最多使用名稱 block2_pool
的圖層。
vgg_model = applications.VGG16(weights='imagenet',
include_top=False,
input_shape=(160, 160, 3))
# Creating dictionary that maps layer names to the layers
layer_dict = dict([(layer.name, layer) for layer in vgg_model.layers])
# Getting output tensor of the last VGG layer that we want to include
x = layer_dict['block2_pool'].output
# Stacking a new simple convolutional network on top of it
x = Conv2D(filters=64, kernel_size=(3, 3), activation='relu')(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Flatten()(x)
x = Dense(256, activation='relu')(x)
x = Dropout(0.5)(x)
x = Dense(10, activation='softmax')(x)
# Creating new model. Please note that this is NOT a Sequential() model.
from keras.models import Model
custom_model = Model(input=vgg_model.input, output=x)
# Make sure that the pre-trained bottom layers are not trainable
for layer in custom_model.layers[:7]:
layer.trainable = False
# Do not forget to compile it
custom_model.compile(loss='categorical_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
刪除多個圖層並在中間插入一個新圖層
假設你需要通過用單個卷積層替換 block1_conv1
和 block2_conv2
來加速 VGG16,以便儲存預先訓練的權重。我們的想法是將整個網路拆分為單獨的層,然後將其組裝回來。以下是專門針對你的任務的程式碼:
vgg_model = applications.VGG16(include_top=True, weights='imagenet')
# Disassemble layers
layers = [l for l in vgg_model.layers]
# Defining new convolutional layer.
# Important: the number of filters should be the same!
# Note: the receiptive field of two 3x3 convolutions is 5x5.
new_conv = Conv2D(filters=64,
kernel_size=(5, 5),
name='new_conv',
padding='same')(layers[0].output)
# Now stack everything back
# Note: If you are going to fine tune the model, do not forget to
# mark other layers as un-trainable
x = new_conv
for i in range(3, len(layers)):
layers[i].trainable = False
x = layers[i](x)
# Final touch
result_model = Model(input=layer[0].input, output=x)