简体   繁体   English

获取Keras中子模型的层output

[英]Get the layer output of a submodel in Keras

I am currently trying to implement a custom loss function in Keras.我目前正在尝试在 Keras 中实现自定义损失 function。 However, as my model is a combination of VGG and my custom network, I can't get the output of my submodel.但是,由于我的 model 是 VGG 和我的自定义网络的组合,我无法获得我的子模型的 output。

Here is the network definition:这是网络定义:

model = VGG19(weights='imagenet', include_top=False)
#model.summary()

def change_model(model, new_input_shape=(None, 40, 40, 3)):
    ''' Change the input size of the provided network'''
    # replace input shape of first layer
    model._layers[0].batch_input_shape = new_input_shape

    # rebuild model architecture by exporting and importing via json
    new_model = keras.models.model_from_json(model.to_json())

    # copy weights from old model to new one
    for layer in new_model.layers:
        try:
            layer.set_weights(model.get_layer(name=layer.name).get_weights())
            print("Loaded layer {}".format(layer.name))
        except:
            print("Could not transfer weights for layer {}".format(layer.name))

    return new_model

new_model = change_model(model,new_input_shape=(None, 1024, 1024, 3))
new_model.summary()
for layer in new_model.layers:
    layer.trainable = False

vector_1 = new_model.get_layer("block4_conv4").output

def create_detector_network(kernel_reg = 0.):
    input = Input(shape=(128, 128, 512))
    x = Conv2D(128, kernel_size=3, strides=1, name='detect_1', padding='same', kernel_regularizer=regularizers.l2(kernel_reg))(input)
    x = BatchNormalization()(x)
    x = Conv2D(1+pow(8,2), kernel_size=1, strides=1, name='detect_2', kernel_regularizer=regularizers.l2(kernel_reg))(x)
    x = BatchNormalization()(x)
    prob = Activation('softmax')(x)
    prob = Lambda(lambda x: x[:,:, :, :-1], output_shape= (128, 128, 64))(prob)  #x[:, :, :-1]
    prob = keras.layers.UpSampling2D(size=(8, 8), data_format=None, interpolation='nearest')(prob)
    prob = Conv2D(1, kernel_size=1, strides=1, name='reduce_dim')(prob)

    return Model(input, [prob, x])



detector_model = create_detector_network()

detector_model.summary()

output = detector_model(vector_1)

full_model  = Model(inputs=new_model.input, outputs=output)

and the summary can be seen here: My Network:总结可以在这里看到:我的网络:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_4 (InputLayer)         (None, 128, 128, 512)     0         
_________________________________________________________________
detect_1 (Conv2D)            (None, 128, 128, 128)     589952    
_________________________________________________________________
batch_normalization_3 (Batch (None, 128, 128, 128)     512       
_________________________________________________________________
detect_2 (Conv2D)            (None, 128, 128, 65)      8385      
_________________________________________________________________
batch_normalization_4 (Batch (None, 128, 128, 65)      260       
_________________________________________________________________
activation_2 (Activation)    (None, 128, 128, 65)      0         
_________________________________________________________________
lambda_2 (Lambda)            (None, 128, 128, 64)      0         
_________________________________________________________________
up_sampling2d_2 (UpSampling2 (None, 1024, 1024, 64)    0         
_________________________________________________________________
reduce_dim (Conv2D)          (None, 1024, 1024, 1)     65        
=================================================================
Total params: 599,174
Trainable params: 598,788
Non-trainable params: 386
_________________________________________________________________

VGG + My Network : VGG + 我的网络

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_7 (InputLayer)         (None, 1024, 1024, 3)     0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 1024, 1024, 64)    1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 1024, 1024, 64)    36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 512, 512, 64)      0         
_________________________________________________________________
block2_conv1 (Conv2D)        (None, 512, 512, 128)     73856     
_________________________________________________________________
block2_conv2 (Conv2D)        (None, 512, 512, 128)     147584    
_________________________________________________________________
block2_pool (MaxPooling2D)   (None, 256, 256, 128)     0         
_________________________________________________________________
block3_conv1 (Conv2D)        (None, 256, 256, 256)     295168    
_________________________________________________________________
block3_conv2 (Conv2D)        (None, 256, 256, 256)     590080    
_________________________________________________________________
block3_conv3 (Conv2D)        (None, 256, 256, 256)     590080    
_________________________________________________________________
block3_conv4 (Conv2D)        (None, 256, 256, 256)     590080    
_________________________________________________________________
block3_pool (MaxPooling2D)   (None, 128, 128, 256)     0         
_________________________________________________________________
block4_conv1 (Conv2D)        (None, 128, 128, 512)     1180160   
_________________________________________________________________
block4_conv2 (Conv2D)        (None, 128, 128, 512)     2359808   
_________________________________________________________________
block4_conv3 (Conv2D)        (None, 128, 128, 512)     2359808   
_________________________________________________________________
block4_conv4 (Conv2D)        (None, 128, 128, 512)     2359808   
_________________________________________________________________
model_7 (Model)              (None, 128, 128, 65)      599109    
=================================================================
Total params: 11,184,261
Trainable params: 598,723
Non-trainable params: 10,585,538
_________________________________________________________________

This is how I train my network:这就是我训练我的网络的方式:

losses = {
    "detect_2": "mse",
    "reduce_dim": "mse",
}

full_model.compile(optimizer='adam',
              loss=losses,
              loss_weights={'prob': 1.0, 'main': 0})

full_model.summary()

history = full_model.fit_generator(
    train_generator,
    steps_per_epoch=100,
    epochs=7,
    validation_data=validation_generator,
    validation_steps=80)

Now, I want to use the output of the layer 'detect_2' and 'reduce_dim' and compute the loss/accuracy from these.现在,我想使用“detect_2”和“reduce_dim”层的 output 并从中计算损失/准确度。 But, when I run my code I get the following error:但是,当我运行我的代码时,我收到以下错误:

ValueError: Unknown entry in loss dictionary: "detect_2". Only expected the following keys: ['model_7', 'model_7']

Obviously, there must be an error somewhere, as a dictionary cannot have the same key twice.显然,某处一定有错误,因为字典不能有两次相同的键。 So could anybody tell me what I need to change such that I get the output of the layers?那么有人能告诉我我需要改变什么,以便我得到层的 output 吗?

If 'detect_2' and 'reduce_dim' are layers of your model you need to specify their outputs as an output of the network.如果 'detect_2' 和 'reduce_dim' 是 model 的层,您需要将它们的输出指定为网络的 output。 Then, you can access them in a custom loss via 'y_true' and 'y_pred' which will hold all network outputs for the ground truth and prediction respectively.然后,您可以通过 'y_true' 和 'y_pred' 在自定义损失中访问它们,这将分别保存地面实况和预测的所有网络输出。 Something like:就像是:

 return Model([input], [detect_2_output, reduce_dim_output])

Then in a custom loss use them however you like然后在自定义损失中随意使用它们

def custom_loss(y_true, y_pred):   
    return 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM