在新的定制模型中使用时如何强制显示 Keras VGG16 模型并包含详细图层

How to force Keras VGG16 model show and include detailed layers when being used in new customized models

总结: 如何强制 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中的层,但新的自定义模型只能看到vgg16层(类型模型),而不是vgg16内的每一层当model.summary()(如图)

    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 层一层一层地复制到新模型中来部分解决这个问题。但是如何使用pre-trained权重可能是个问题。任何其他想法将不胜感激。

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

您可以通过遍历层并将它们附加到顺序模型来展平嵌套模型。 我已将其用于以下代码。

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)