2017-03-05 36 views
3

使用Keras(1.2.2),我加載其最後一層是一個連續的模型:Keras - 彈出並重新添加圖層,但層不會斷開

model.add(Dense(512)) 
model.add(Activation('relu')) 
model.add(Dense(nb_classes)) 
model.add(Activation('softmax')) 

然後,我要求婚最後一層,添加另一個完全連接的層,並重新添加分類層。

model = load_model('model1.h5')                   
layer1 = model.layers.pop() # Copy activation_6 layer          
layer2 = model.layers.pop() # Copy classification layer (dense_2)       

model.add(Dense(512, name='dense_3')) 
model.add(Activation('softmax', name='activation_7')) 

model.add(layer2) 
model.add(layer1) 

print(model.summary()) 

正如你可以看到我的dense_3和activation_7沒有連接到網絡(在「連接到」的summary()中爲空值)。在解釋如何解決此問題的文檔中找不到任何內容。有任何想法嗎?

dense_1 (Dense)     (None, 512)   131584  flatten_1[0][0]     
____________________________________________________________________________________________________ 
activation_5 (Activation)  (None, 512)   0   dense_1[0][0]      
____________________________________________________________________________________________________ 
dense_3 (Dense)     (None, 512)   5632           
____________________________________________________________________________________________________ 
activation_7 (Activation)  (None, 512)   0            
____________________________________________________________________________________________________ 
dense_2 (Dense)     (None, 10)   5130  activation_5[0][0]    
____________________________________________________________________________________________________ 
activation_6 (Activation)  (None, 10)   0   dense_2[0][0]      
==================================================================================================== 

按照下面的答案,我編譯模型打印出model.summary()前,但由於某些原因,該層沒有被正確地彈出,彙總顯示:最後一層的連接是錯誤的:

dense_1 (Dense)     (None, 512)   131584  flatten_1[0][0]     
____________________________________________________________________________________________________ 
activation_5 (Activation)  (None, 512)   0   dense_1[0][0]      
____________________________________________________________________________________________________ 
dense_3 (Dense)     (None, 512)   5632  activation_6[0][0]    
____________________________________________________________________________________________________ 
activation_7 (Activation)  (None, 512)   0   dense_3[0][0]      
____________________________________________________________________________________________________ 
dense_2 (Dense)     (None, 10)   5130  activation_5[0][0]    
                    activation_7[0][0]    
____________________________________________________________________________________________________ 
activation_6 (Activation)  (None, 10)   0   dense_2[0][0]      
                    dense_2[1][0]      
==================================================================================================== 

但應

dense_1 (Dense)     (None, 512)   131584  flatten_1[0][0]     
____________________________________________________________________________________________________ 
activation_5 (Activation)  (None, 512)   0   dense_1[0][0]      
____________________________________________________________________________________________________ 
dense_3 (Dense)     (None, 512)   5632  activation_5[0][0]    
____________________________________________________________________________________________________ 
activation_7 (Activation)  (None, 512)   0   dense_3[0][0]      
____________________________________________________________________________________________________ 
dense_2 (Dense)     (None, 10)   5130      
                    activation_7[0][0]    
____________________________________________________________________________________________________ 
activation_6 (Activation)  (None, 10)   0   dense_2[0][0]      

==================================================================================================== 

回答

2

當你放下層,則需要重新編譯你的模型,以便它有任何影響。

所以使用

model.compile(loss=...,optimizer=..., ...) 

打印彙總之前,它應該正確地整合了變化。

編輯:

你所要做的其實是一個順序模式非常複雜。這是解決方案,我可以拿出(如果有任何更好的請告訴我)你的順序模型:

model = load_model('model1.h5')                   
layer1 = model.layers.pop() # Copy activation_6 layer          
layer2 = model.layers.pop() # Copy classification layer (dense_2)       

model.add(Dense(512, name='dense_3')) 
model.add(Activation('softmax', name='activation_7')) 

# get layer1 config 
layer1_config = layer1.get_config() 
layer2_config = layer2.get_config() 
# change the name of the layers otherwise it complains 
layer1_config['name'] = layer1_config['name'] + '_new' 
layer2_config['name'] = layer2_config['name'] + '_new' 

# import the magic function 
from keras.utils.layer_utils import layer_from_config 
# re-add new layers from the config of the old ones 
model.add(layer_from_config({'class_name':type(l2), 'config':layer2_config})) 
model.add(layer_from_config({'class_name':type(l1), 'config':layer1_config})) 

model.compile(...) 

print(model.summary()) 

的黑客是一個事實,即你的層具有layer1.inputlayer1.output性質,我不能更改。

解決方法是使用Functionnal API模型。這使您可以定義圖層的內容和內容。

首先,您需要定義您的POP()函數,每次你彈出一個時間來正確重新鏈接層,功能來自this github issue

def pop_layer(model): 
    if not model.outputs: 
     raise Exception('Sequential model cannot be popped: model is empty.') 

    popped_layer = model.layers.pop() 
    if not model.layers: 
     model.outputs = [] 
     model.inbound_nodes = [] 
     model.outbound_nodes = [] 
    else: 
     model.layers[-1].outbound_nodes = [] 
     model.outputs = [model.layers[-1].output] 
    model.built = False 
    return popped_layer 

它只是刪除了最後一層的每一個輸出鏈路和將模型的輸出更改爲新的最後一層。現在你可以使用它在:

model = load_model('model1.h5')                   
layer1 = model.layers.pop() # Copy activation_6 layer          
layer2 = model.layers.pop() # Copy classification layer (dense_2)  

# take model.outputs and feed a Dense layer 
h = Dense(512,name='dense_3')(model.outputs) 
h = Activation('relu', name=('activation_7')(h) 
# apply 
h = layer2(h) 
output = layer1(h) 

model = Model(input=model.input, output=output) 
model.compile(...) 
model.summary() 

有可能比這更好的解決方案,但這是我會做的。

我希望這會有所幫助。

+0

編譯顯示我已將連接添加到新添加的圖層(dense_3和activation_7),但與activation_6和dense_2的連接好像沒有被pop()更新。我試圖在彈出後編譯並在添加下一層後再次編譯,但沒有任何效果。我在這裏錯過了什麼? –

+0

編輯我的回答 –

+0

現在工作正常嗎? :) –