【问题标题】:How to force Keras VGG16 model show and include detailed layers when being used in new customized models在新的自定义模型中使用时如何强制 Keras VGG16 模型显示并包含详细层
【发布时间】:2021-10-03 15:53:40
【问题描述】:

总结:如何强制keras.applications.VGG16 层,而不是vgg 模型,在新的自定义模型中显示和包含为层。

详情:

  1. 我正在keras.applications.VGG16(表示为 conv_base)之上构建自定义模型(表示为模型)。具体来说,我用我自己的层替换了最后的密集层。

    conv_base = VGG16(weights='imagenet',  # pre-train with ImageNet
              include_top=False,  # exclude the three top layers
              input_shape=(64, 64, 3),
              pooling = 'max')
    model = models.Sequential()
    model.add(conv_base)
    model.add(layers.BatchNormalization())
    model.add(layers.Dropout(0.2))
    model.add(layers.Dense(256, activation='linear'))
    model.add(layers.BatchNormalization())
    model.add(layers.Dropout(0.2))
    model.add(layers.Dense(1, activation='linear'))
    
  2. conv_base.summary() 时我可以看到 conv_base 中的层,而新的自定义模型在 model.summary() 时只能看到 vgg16 层(Model 类型),而不是 vgg16 中的每一层(如图所示)

    conv_base.summary()
    

    model.summary()

  1. 相关问题

虽然 model.get_layer('vgg16').layers 可以访问 vgg 层,但它仍然偶尔会导致其他问题,包括:

(1) 加载砝码:有时会弄乱加载砝码的过程。

    model.load_weights('~path/weights.hdf5')  

(2) 构建新模型:调用model层构建新模型时也会出错。

    model2 = Model(inputs=model.inputs, outputs=model.get_layer('vgg16').layers[1].output, name='Vis_Model') 

想法: 我可以想象通过将keras.application.VGG 一层一层地复制到一个新模型中来部分解决这个问题。但是如何使用预训练的权重可能是个问题。任何其他想法将不胜感激。

【问题讨论】:

    标签: python tensorflow machine-learning keras vgg-net


    【解决方案1】:

    编辑:根据您的 cmets,这是一个更新的解决方案。

    您可以通过迭代层并将它们附加到顺序模型来展平嵌套模型。 Here is a great solution 用于下面的代码。

    import numpy as np
    import tensorflow as tf
    from tensorflow.keras.applications import VGG16
    from tensorflow.keras import layers, Model, utils
    
    #Instantiating the VGG model
    conv_base = VGG16(weights='imagenet',  # pre-train with ImageNet
                      include_top=False,  # exclude the three top layers
                      input_shape=(64, 64, 3),
                      pooling = 'max')
    
    #Defining secondary nested model
    inp = layers.Input((64,64,3))
    cnn = conv_base(inp)
    x = layers.BatchNormalization()(cnn)
    x = layers.Dropout(0.2)(x)
    x = layers.Dense(256, activation='linear')(x)
    x = layers.BatchNormalization()(x)
    x = layers.Dropout(0.2)(x)
    out = layers.Dense(1, activation='linear')(x)
    
    model = Model(inp, out)
    
    #Flattening nested model
    def flatten_model(model_nested):
        layers_flat = []
        for layer in model_nested.layers:
            try:
                layers_flat.extend(layer.layers)
            except AttributeError:
                layers_flat.append(layer)
        model_flat = tf.keras.models.Sequential(layers_flat)
        return model_flat
    
    model_flat = flatten_model(model)
    
    model_flat.summary()
    
    Model: "sequential_1"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    input_10 (InputLayer)        multiple                  0         
    _________________________________________________________________
    block1_conv1 (Conv2D)        (None, 64, 64, 64)        1792      
    _________________________________________________________________
    block1_conv2 (Conv2D)        (None, 64, 64, 64)        36928     
    _________________________________________________________________
    block1_pool (MaxPooling2D)   (None, 32, 32, 64)        0         
    _________________________________________________________________
    block2_conv1 (Conv2D)        (None, 32, 32, 128)       73856     
    _________________________________________________________________
    block2_conv2 (Conv2D)        (None, 32, 32, 128)       147584    
    _________________________________________________________________
    block2_pool (MaxPooling2D)   (None, 16, 16, 128)       0         
    _________________________________________________________________
    block3_conv1 (Conv2D)        (None, 16, 16, 256)       295168    
    _________________________________________________________________
    block3_conv2 (Conv2D)        (None, 16, 16, 256)       590080    
    _________________________________________________________________
    block3_conv3 (Conv2D)        (None, 16, 16, 256)       590080    
    _________________________________________________________________
    block3_pool (MaxPooling2D)   (None, 8, 8, 256)         0         
    _________________________________________________________________
    block4_conv1 (Conv2D)        (None, 8, 8, 512)         1180160   
    _________________________________________________________________
    block4_conv2 (Conv2D)        (None, 8, 8, 512)         2359808   
    _________________________________________________________________
    block4_conv3 (Conv2D)        (None, 8, 8, 512)         2359808   
    _________________________________________________________________
    block4_pool (MaxPooling2D)   (None, 4, 4, 512)         0         
    _________________________________________________________________
    block5_conv1 (Conv2D)        (None, 4, 4, 512)         2359808   
    _________________________________________________________________
    block5_conv2 (Conv2D)        (None, 4, 4, 512)         2359808   
    _________________________________________________________________
    block5_conv3 (Conv2D)        (None, 4, 4, 512)         2359808   
    _________________________________________________________________
    block5_pool (MaxPooling2D)   (None, 2, 2, 512)         0         
    _________________________________________________________________
    global_max_pooling2d_3 (Glob (None, 512)               0         
    _________________________________________________________________
    batch_normalization_4 (Batch (None, 512)               2048      
    _________________________________________________________________
    dropout_4 (Dropout)          (None, 512)               0         
    _________________________________________________________________
    dense_4 (Dense)              (None, 256)               131328    
    _________________________________________________________________
    batch_normalization_5 (Batch (None, 256)               1024      
    _________________________________________________________________
    dropout_5 (Dropout)          (None, 256)               0         
    _________________________________________________________________
    dense_5 (Dense)              (None, 1)                 257       
    =================================================================
    Total params: 14,849,345
    Trainable params: 14,847,809
    Non-trainable params: 1,536
    _________________________________________________________________
    

    我建议使用另一种总结模型的方法。

    为此,您可以使用utils.plot_modelexpand_nested=True

    tf.keras.utils.plot_model(model, show_shapes=True, show_layer_names=True, expand_nested=True)
    

    【讨论】:

    • 感谢您指出这一点。但正如问题中所述,显示详细信息并不是强制将模型层包含在新模型中的唯一原因。
    • 嗯,据我所知,你有你的预训练模型,你想将哪些层添加到元模型中?这些层会保持不可训练吗?
    • 请参阅相关问题 (2)。我想使用model 中的层(vgg 内部)来构建一个新模型来可视化特征图。
    • 请帮助我进一步理解。相关问题(2)基本上是您尝试使用相同的输入,但只是嵌套 VGG 模型的第一层作为新模型?
    • 再次感谢。我已经接受了答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-28
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 2022-10-22
    • 2020-02-02
    • 1970-01-01
    相关资源
    最近更新 更多