2017-03-05 6 views
3

を切断しない、私は最後の層であるシーケンシャルモデルロードしています:Keras - ポップと再度追加層が、層がKeras(1.2.2)を使用して

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が(「に接続されている」と要約で空の値())ネットワークに接続できませんでした見ることができるように。この問題を解決する方法を説明しているドキュメントには何も見つかりません。何か案は?

下記の解答後
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性質を持っているという事実にあります変化する。

これは、Functional APIモデルを使用することです。これにより、何が入って来るのか、どの層から来るのかを定義することができます。

あなたが適切層に使用すると、1つをポップするたびに再リンクする、あなたのポップ()関数を定義する必要がありますまず、関数は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

今は正しく動作していますか? :) –

関連する問題