您是否應該針對您的特定任務重新培養VGG16? 絕對不是!重新訓練這樣一個巨大的網絡是困難的,並且需要很多直覺和知識來訓練深度網絡。讓我們來分析一下爲什麼你可以使用的權重,對ImageNet預先訓練,您的任務:
實際上,您不需要使用預先訓練好的VGG16的所有卷積層。讓我們來看看,看看他們檢測(從this article拍攝;圖像過大,所以我把剛纔的鏈接緊湊):
- 第一和第二卷積塊着眼於低電平的功能,如拐角,邊緣等
- 第三和第四卷積塊看起來在表面特徵,曲線,圓等
- 第五層着眼於高級別功能
所以,您可以決定哪種功能會受益負責您的具體任務。你需要第五檔的高級功能嗎?或者你可能想使用第三塊的中級功能?也許你想在VGG的最底層疊加另一個神經網絡?有關更多說明,請參閱我編寫的以下教程;它曾經是SO文檔。使用VGG和Keras
在這個例子中,三個簡單的和全面的子實例
遷移學習和微調都:從可用的預先訓練模型
- 加載權重,包括與Keras圖書館
- 疊加另一個網絡在VGG的任何層頂上培訓
- 插入其他層的中間層
- 提示和一般原則進行的大拇指進行微調和轉讓與VGG學習
預加載訓練的權重
預ImageNet模型,包括VGG-16和VGG-19,可在Keras。在此例中,將使用VGG-16。欲瞭解更多信息,請訪問Keras Applications documentation。
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)
考慮訪問[數據科學SE(https://datascience.stackexchange.com)或[交叉驗證(https://stats.stackexchange.com)爲關於機器學習的問題。 –