在新的定制模型中使用时如何强制显示 Keras VGG16 模型并包含详细图层
How to force Keras VGG16 model show and include detailed layers when being used in new customized models
总结: 如何强制 keras.applications.VGG16
层而不是 vgg
模型显示并作为层包含在新的自定义模型中。
详情:
我在 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'))
虽然我在conv_base.summary()
时可以看到conv_base中的层,但新的自定义模型只能看到vgg16层(类型模型),而不是vgg16内的每一层当model.summary()
(如图)
conv_base.summary()
model.summary()
- 相关问题
尽管 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_model
与 expand_nested=True
一起用于此目的。
tf.keras.utils.plot_model(model, show_shapes=True, show_layer_names=True, expand_nested=True)
总结: 如何强制 keras.applications.VGG16
层而不是 vgg
模型显示并作为层包含在新的自定义模型中。
详情:
我在
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'))
虽然我在
conv_base.summary()
时可以看到conv_base中的层,但新的自定义模型只能看到vgg16层(类型模型),而不是vgg16内的每一层当model.summary()
(如图)conv_base.summary()
model.summary()
- 相关问题
尽管 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_model
与 expand_nested=True
一起用于此目的。
tf.keras.utils.plot_model(model, show_shapes=True, show_layer_names=True, expand_nested=True)