2017-05-04 101 views
0

我實際上試圖通過Keras獲得VGG16的Sequential模型版本。是這樣的將VGG功能模型轉換爲Keras中的順序模型

from __future__ import division, print_function 

import os, json 
from glob import glob 
import numpy as np 
from scipy import misc, ndimage 
from scipy.ndimage.interpolation import zoom 

from keras import backend as K 
from keras.layers.normalization import BatchNormalization 
from keras.utils.data_utils import get_file 
from keras.models import Sequential 
from keras.layers.core import Flatten, Dense, Dropout, Lambda 
from keras.layers.convolutional import Convolution2D, MaxPooling2D, ZeroPadding2D 
from keras.layers.pooling import GlobalAveragePooling2D 
from keras.optimizers import SGD, RMSprop, Adam 
from keras.preprocessing import image 
import keras 
import keras.applications.vgg16 
from keras.layers import Input 

input_tensor = Input(shape=(224,224,3)) 
VGG_model=keras.applications.vgg16.VGG16(weights='imagenet',include_top= True,input_tensor=input_tensor) 

及其摘要:可以用獲得的功能版本

VGG_model.summary() 

Layer (type)      Output Shape   Param #  Connected to      
==================================================================================================== 
input_1 (InputLayer)    (None, 224, 224, 3) 0            
____________________________________________________________________________________________________ 
block1_conv1 (Convolution2D)  (None, 224, 224, 64) 1792  input_1[0][0]      
____________________________________________________________________________________________________ 
block1_conv2 (Convolution2D)  (None, 224, 224, 64) 36928  block1_conv1[0][0]    
____________________________________________________________________________________________________ 
block1_pool (MaxPooling2D)  (None, 112, 112, 64) 0   block1_conv2[0][0]    
____________________________________________________________________________________________________ 
block2_conv1 (Convolution2D)  (None, 112, 112, 128) 73856  block1_pool[0][0]     
____________________________________________________________________________________________________ 
block2_conv2 (Convolution2D)  (None, 112, 112, 128) 147584  block2_conv1[0][0]    
____________________________________________________________________________________________________ 
block2_pool (MaxPooling2D)  (None, 56, 56, 128) 0   block2_conv2[0][0]    
____________________________________________________________________________________________________ 
block3_conv1 (Convolution2D)  (None, 56, 56, 256) 295168  block2_pool[0][0]     
____________________________________________________________________________________________________ 
block3_conv2 (Convolution2D)  (None, 56, 56, 256) 590080  block3_conv1[0][0]    
____________________________________________________________________________________________________ 
block3_conv3 (Convolution2D)  (None, 56, 56, 256) 590080  block3_conv2[0][0]    
____________________________________________________________________________________________________ 
block3_pool (MaxPooling2D)  (None, 28, 28, 256) 0   block3_conv3[0][0]    
____________________________________________________________________________________________________ 
block4_conv1 (Convolution2D)  (None, 28, 28, 512) 1180160  block3_pool[0][0]     
____________________________________________________________________________________________________ 
block4_conv2 (Convolution2D)  (None, 28, 28, 512) 2359808  block4_conv1[0][0]    
____________________________________________________________________________________________________ 
block4_conv3 (Convolution2D)  (None, 28, 28, 512) 2359808  block4_conv2[0][0]    
____________________________________________________________________________________________________ 
block4_pool (MaxPooling2D)  (None, 14, 14, 512) 0   block4_conv3[0][0]    
____________________________________________________________________________________________________ 
block5_conv1 (Convolution2D)  (None, 14, 14, 512) 2359808  block4_pool[0][0]     
____________________________________________________________________________________________________ 
block5_conv2 (Convolution2D)  (None, 14, 14, 512) 2359808  block5_conv1[0][0]    
____________________________________________________________________________________________________ 
block5_conv3 (Convolution2D)  (None, 14, 14, 512) 2359808  block5_conv2[0][0]    
____________________________________________________________________________________________________ 
block5_pool (MaxPooling2D)  (None, 7, 7, 512)  0   block5_conv3[0][0]    
____________________________________________________________________________________________________ 
flatten (Flatten)    (None, 25088)   0   block5_pool[0][0]     
____________________________________________________________________________________________________ 
fc1 (Dense)      (None, 4096)   102764544 flatten[0][0]      
____________________________________________________________________________________________________ 
fc2 (Dense)      (None, 4096)   16781312 fc1[0][0]       
____________________________________________________________________________________________________ 
predictions (Dense)    (None, 1000)   4097000  fc2[0][0]       
==================================================================================================== 
Total params: 138,357,544 
Trainable params: 138,357,544 
Non-trainable params: 0 
____________________________________________________________________________________________________ 

根據這個網站https://github.com/fchollet/keras/issues/3190,它說

Sequential(layers=functional_model.layers) 

能隱蔽功能模型爲連續模型。但是,如果我這樣做:

model = Sequential(layers=VGG_model.layers) 
model.summary() 

它導致

Layer (type)      Output Shape   Param #  Connected to      
==================================================================================================== 
input_1 (InputLayer)    (None, 224, 224, 3) 0            
____________________________________________________________________________________________________ 
block1_conv1 (Convolution2D)  (None, 224, 224, 64) 1792  input_1[0][0]      
                    input_1[0][0]      
                    input_1[0][0]      
____________________________________________________________________________________________________ 
block1_conv2 (Convolution2D)  (None, 224, 224, 64) 36928  block1_conv1[0][0]    
                    block1_conv1[1][0]    
                    block1_conv1[2][0]    
____________________________________________________________________________________________________ 
block1_pool (MaxPooling2D)  (None, 112, 112, 64) 0   block1_conv2[0][0]    
                    block1_conv2[1][0]    
                    block1_conv2[2][0]    
____________________________________________________________________________________________________ 
block2_conv1 (Convolution2D)  (None, 112, 112, 128) 73856  block1_pool[0][0]     
                    block1_pool[1][0]     
                    block1_pool[2][0]     
____________________________________________________________________________________________________ 
block2_conv2 (Convolution2D)  (None, 112, 112, 128) 147584  block2_conv1[0][0]    
                    block2_conv1[1][0]    
                    block2_conv1[2][0]    
____________________________________________________________________________________________________ 
block2_pool (MaxPooling2D)  (None, 56, 56, 128) 0   block2_conv2[0][0]    
                    block2_conv2[1][0]    
                    block2_conv2[2][0]    
____________________________________________________________________________________________________ 
block3_conv1 (Convolution2D)  (None, 56, 56, 256) 295168  block2_pool[0][0]     
                    block2_pool[1][0]     
                    block2_pool[2][0]     
____________________________________________________________________________________________________ 
block3_conv2 (Convolution2D)  (None, 56, 56, 256) 590080  block3_conv1[0][0]    
                    block3_conv1[1][0]    
                    block3_conv1[2][0]    
____________________________________________________________________________________________________ 
block3_conv3 (Convolution2D)  (None, 56, 56, 256) 590080  block3_conv2[0][0]    
                    block3_conv2[1][0]    
                    block3_conv2[2][0]    
____________________________________________________________________________________________________ 
block3_pool (MaxPooling2D)  (None, 28, 28, 256) 0   block3_conv3[0][0]    
                    block3_conv3[1][0]    
                    block3_conv3[2][0]    
____________________________________________________________________________________________________ 
block4_conv1 (Convolution2D)  (None, 28, 28, 512) 1180160  block3_pool[0][0]     
                    block3_pool[1][0]     
                    block3_pool[2][0]     
____________________________________________________________________________________________________ 
block4_conv2 (Convolution2D)  (None, 28, 28, 512) 2359808  block4_conv1[0][0]    
                    block4_conv1[1][0]    
                    block4_conv1[2][0]    
____________________________________________________________________________________________________ 
block4_conv3 (Convolution2D)  (None, 28, 28, 512) 2359808  block4_conv2[0][0]    
                    block4_conv2[1][0]    
                    block4_conv2[2][0]    
____________________________________________________________________________________________________ 
block4_pool (MaxPooling2D)  (None, 14, 14, 512) 0   block4_conv3[0][0]    
                    block4_conv3[1][0]    
                    block4_conv3[2][0]    
____________________________________________________________________________________________________ 
block5_conv1 (Convolution2D)  (None, 14, 14, 512) 2359808  block4_pool[0][0]     
                    block4_pool[1][0]     
                    block4_pool[2][0]     
____________________________________________________________________________________________________ 
block5_conv2 (Convolution2D)  (None, 14, 14, 512) 2359808  block5_conv1[0][0]    
                    block5_conv1[1][0]    
                    block5_conv1[2][0]    
____________________________________________________________________________________________________ 
block5_conv3 (Convolution2D)  (None, 14, 14, 512) 2359808  block5_conv2[0][0]    
                    block5_conv2[1][0]    
                    block5_conv2[2][0]    
____________________________________________________________________________________________________ 
block5_pool (MaxPooling2D)  (None, 7, 7, 512)  0   block5_conv3[0][0]    
                    block5_conv3[1][0]    
                    block5_conv3[2][0]    
____________________________________________________________________________________________________ 
flatten (Flatten)    (None, 25088)   0   block5_pool[0][0]     
                    block5_pool[1][0]     
                    block5_pool[2][0]     
____________________________________________________________________________________________________ 
fc1 (Dense)      (None, 4096)   102764544 flatten[0][0]      
                    flatten[1][0]      
                    flatten[2][0]      
____________________________________________________________________________________________________ 
fc2 (Dense)      (None, 4096)   16781312 fc1[0][0]       
                    fc1[1][0]       
                    fc1[2][0]       
____________________________________________________________________________________________________ 
predictions (Dense)    (None, 1000)   4097000  fc2[0][0]       
                    fc2[1][0]       
                    fc2[2][0]       
==================================================================================================== 
Total params: 138,357,544 
Trainable params: 138,357,544 
Non-trainable params: 0 
_ 

這是因爲新的層連接到先前層3倍的原始功能模型不同。人們說使用功能模型更強大。但我想要做的只是彈出最終預測層。和功能模型不能做到這一點...

+0

爲什麼你需要一個順序模型? –

回答

1

您可以通過只definining另一Model回吐此前層輸出「啪」的最後一層:

poppedModel = Model(VGG_model.input,VGG_model.layers[-2].output) 

這種模式將共享完全相同的權重爲原始模型和培訓將影響兩種模型。

您可以poppedModel後添加自己的層(甚至機型),沒有問題:

popOut = poppedModel(input_tensor) 
newLayOut = SomeKerasLayer(blablabla)(popOut) 

anotherModel = Model(input_tensor, newLayOut) 
#anotherModel will also share weights with poppedModel and VGG_model in the layers they have in common. 

是很重要的,不過,如果你打算在訓練中anotherModel新的圖層,而不會影響VGG的權重,即在編譯anotherModel之前,您製作了poppedModel.trainable = False及其中的每個圖層poppedModel.layers[i].trainable = False

1

我也一直在努力與此和前面的海報幾乎在那裏,但省略了一個特定的細節,這是我以前st me我。 事實上,即使使用由Functional API創建的模型,您也可以做到「流行」,但這是一項更多的工作。

這裏是我的模型(只是普通的香草VGG16)

model.summary() 
 
____________________________________________________________________________________________________ 
Layer (type)      Output Shape   Param #  Connected to      
==================================================================================================== 
input_6 (InputLayer)    (None, 224, 224, 3) 0            
____________________________________________________________________________________________________ 
block1_conv1 (Convolution2D)  (None, 224, 224, 64) 1792  input_6[0][0]      
____________________________________________________________________________________________________ 
block1_conv2 (Convolution2D)  (None, 224, 224, 64) 36928  block1_conv1[0][0]    
____________________________________________________________________________________________________ 
block1_pool (MaxPooling2D)  (None, 112, 112, 64) 0   block1_conv2[0][0]    
____________________________________________________________________________________________________ 
block2_conv1 (Convolution2D)  (None, 112, 112, 128) 73856  block1_pool[0][0]     
____________________________________________________________________________________________________ 
block2_conv2 (Convolution2D)  (None, 112, 112, 128) 147584  block2_conv1[0][0]    
____________________________________________________________________________________________________ 
block2_pool (MaxPooling2D)  (None, 56, 56, 128) 0   block2_conv2[0][0]    
____________________________________________________________________________________________________ 
block3_conv1 (Convolution2D)  (None, 56, 56, 256) 295168  block2_pool[0][0]     
____________________________________________________________________________________________________ 
block3_conv2 (Convolution2D)  (None, 56, 56, 256) 590080  block3_conv1[0][0]    
____________________________________________________________________________________________________ 
block3_conv3 (Convolution2D)  (None, 56, 56, 256) 590080  block3_conv2[0][0]    
____________________________________________________________________________________________________ 
block3_pool (MaxPooling2D)  (None, 28, 28, 256) 0   block3_conv3[0][0]    
____________________________________________________________________________________________________ 
block4_conv1 (Convolution2D)  (None, 28, 28, 512) 1180160  block3_pool[0][0]     
____________________________________________________________________________________________________ 
block4_conv2 (Convolution2D)  (None, 28, 28, 512) 2359808  block4_conv1[0][0]    
____________________________________________________________________________________________________ 
block4_conv3 (Convolution2D)  (None, 28, 28, 512) 2359808  block4_conv2[0][0]    
____________________________________________________________________________________________________ 
block4_pool (MaxPooling2D)  (None, 14, 14, 512) 0   block4_conv3[0][0]    
____________________________________________________________________________________________________ 
block5_conv1 (Convolution2D)  (None, 14, 14, 512) 2359808  block4_pool[0][0]     
____________________________________________________________________________________________________ 
block5_conv2 (Convolution2D)  (None, 14, 14, 512) 2359808  block5_conv1[0][0]    
____________________________________________________________________________________________________ 
block5_conv3 (Convolution2D)  (None, 14, 14, 512) 2359808  block5_conv2[0][0]    
____________________________________________________________________________________________________ 
block5_pool (MaxPooling2D)  (None, 7, 7, 512)  0   block5_conv3[0][0]    
____________________________________________________________________________________________________ 
flatten (Flatten)    (None, 25088)   0   block5_pool[0][0]     
____________________________________________________________________________________________________ 
fc1 (Dense)      (None, 4096)   102764544 flatten[0][0]      
____________________________________________________________________________________________________ 
fc2 (Dense)      (None, 4096)   16781312 fc1[0][0]       
____________________________________________________________________________________________________ 
predictions (Dense)    (None, 1000)   4097000  fc2[0][0]       
==================================================================================================== 
Total params: 138,357,544 
Trainable params: 138,357,544 
Non-trainable params: 0 
____________________________________________________________________________________________________ 

然後我 「突然出現」 的最後一層,但沒有使用流行,只是與功能API

#Get the last but one layer/tensor from the old model 
last_layer = model.layers[-2].output 

#Define the new layer/tensor for the new model 
new_model = Dense(2, activation='softmax', name='Binary_predictions')(last_layer) 

#Create the new model, with the old models input and the new_model tensor as the output 
new_model = Model(model.input, new_model, name='Finetuned_VGG16') 

#Set all layers,except the last one to not trainable 
for layer in new_model.layers[:-1]: layer.trainable=False 

#Compile the new model 
new_model.compile(optimizer=Adam(lr=learning_rate), 
       loss='categorical_crossentropy', metrics=['accuracy']) 

#now train with the new outputs (cats and dogs!) 

這將創建一個新模型(new_model),最後一層被替換,舊層固定(不可訓練)。

new_model.summary() 

____________________________________________________________________________________________________ 
Layer (type)      Output Shape   Param #  Connected to      
==================================================================================================== 
input_6 (InputLayer)    (None, 224, 224, 3) 0            
____________________________________________________________________________________________________ 
block1_conv1 (Convolution2D)  (None, 224, 224, 64) 1792  input_6[0][0]      
____________________________________________________________________________________________________ 
block1_conv2 (Convolution2D)  (None, 224, 224, 64) 36928  block1_conv1[0][0]    
____________________________________________________________________________________________________ 
block1_pool (MaxPooling2D)  (None, 112, 112, 64) 0   block1_conv2[0][0]    
____________________________________________________________________________________________________ 
block2_conv1 (Convolution2D)  (None, 112, 112, 128) 73856  block1_pool[0][0]     
____________________________________________________________________________________________________ 
block2_conv2 (Convolution2D)  (None, 112, 112, 128) 147584  block2_conv1[0][0]    
____________________________________________________________________________________________________ 
block2_pool (MaxPooling2D)  (None, 56, 56, 128) 0   block2_conv2[0][0]    
____________________________________________________________________________________________________ 
block3_conv1 (Convolution2D)  (None, 56, 56, 256) 295168  block2_pool[0][0]     
____________________________________________________________________________________________________ 
block3_conv2 (Convolution2D)  (None, 56, 56, 256) 590080  block3_conv1[0][0]    
____________________________________________________________________________________________________ 
block3_conv3 (Convolution2D)  (None, 56, 56, 256) 590080  block3_conv2[0][0]    
____________________________________________________________________________________________________ 
block3_pool (MaxPooling2D)  (None, 28, 28, 256) 0   block3_conv3[0][0]    
____________________________________________________________________________________________________ 
block4_conv1 (Convolution2D)  (None, 28, 28, 512) 1180160  block3_pool[0][0]     
____________________________________________________________________________________________________ 
block4_conv2 (Convolution2D)  (None, 28, 28, 512) 2359808  block4_conv1[0][0]    
____________________________________________________________________________________________________ 
block4_conv3 (Convolution2D)  (None, 28, 28, 512) 2359808  block4_conv2[0][0]    
____________________________________________________________________________________________________ 
block4_pool (MaxPooling2D)  (None, 14, 14, 512) 0   block4_conv3[0][0]    
____________________________________________________________________________________________________ 
block5_conv1 (Convolution2D)  (None, 14, 14, 512) 2359808  block4_pool[0][0]     
____________________________________________________________________________________________________ 
block5_conv2 (Convolution2D)  (None, 14, 14, 512) 2359808  block5_conv1[0][0]    
____________________________________________________________________________________________________ 
block5_conv3 (Convolution2D)  (None, 14, 14, 512) 2359808  block5_conv2[0][0]    
____________________________________________________________________________________________________ 
block5_pool (MaxPooling2D)  (None, 7, 7, 512)  0   block5_conv3[0][0]    
____________________________________________________________________________________________________ 
flatten (Flatten)    (None, 25088)   0   block5_pool[0][0]     
____________________________________________________________________________________________________ 
fc1 (Dense)      (None, 4096)   102764544 flatten[0][0]      
____________________________________________________________________________________________________ 
fc2 (Dense)      (None, 4096)   16781312 fc1[0][0]       
____________________________________________________________________________________________________ 
Binary_predictions (Dense)  (None, 2)    8194  fc2[0][0]       
==================================================================================================== 
Total params: 134,268,738 
Trainable params: 8,194 
Non-trainable params: 134,260,544 

棘手的部分是獲得.output作爲最後一層,因爲這使得它成爲一個張量。然後使用該張量作爲新的密集層的輸入,並使其成爲新模型中的最終輸出...

希望這有助於...

Thon

相關問題