You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Keras自定义模型显示并包含VGG16的全部详细层

如何让keras.applications.VGG16的各层作为独立层显示在自定义模型中

摘要

如何强制让keras.applications.VGG16的各层而非整个vgg模型,作为独立层显示并包含在新建的自定义模型中。

详情

  1. 我基于keras.applications.VGG16(记为conv_base)搭建自定义模型(记为model),替换了原模型的最后全连接层为自定义层,代码如下:
conv_base = VGG16(weights='imagenet',  # 基于ImageNet预训练
          include_top=False,  # 排除顶部三层全连接层
          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'))
  1. 调用conv_base.summary()时可以看到conv_base内部的所有层,但调用model.summary()时,自定义模型仅显示vgg16层(类型为Model),无法展示vgg16内部的每一层。
  2. 关联问题
    虽然可以通过model.get_layer('vgg16').layers访问vgg的层,但仍偶尔出现其他问题:
  • 加载权重:有时会打乱权重加载流程
model.load_weights('~path/weights.hdf5')  
  • 构建新模型:调用model的层构建新模型时也会报错
model2 = Model(inputs=model.inputs, outputs=model.get_layer('vgg16').layers[1].output, name='Vis_Model') 

个人思路

我考虑过将keras.application.VGG的层逐一复制到新模型中来部分解决该问题,但预训练权重的使用方式存在问题,希望获得其他可行方案。


方案1:逐层添加VGG16层(兼容性最高)

直接遍历VGG16实例的所有层逐个加入自定义模型,预训练权重会自动保留,不需要额外处理,修改后的代码如下:

from tensorflow.keras.applications import VGG16
from tensorflow.keras import models, layers

conv_base = VGG16(weights='imagenet',
                  include_top=False,
                  input_shape=(64, 64, 3),
                  pooling='max')

model = models.Sequential()
# 逐个添加VGG16的所有层,而非将整个conv_base作为单个层加入
for layer in conv_base.layers:
    model.add(layer)

# 后续自定义层保持不变
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'))

修改后调用model.summary()即可看到VGG16的全部层,权重加载、提取中间层构建新模型的问题都会同步解决。如果需要冻结VGG16的预训练参数不参与训练,添加如下代码:

# 冻结VGG16对应的所有层
for layer in model.layers[:len(conv_base.layers)]:
    layer.trainable = False

方案2:不修改嵌套结构的兼容方案

如果不想调整原有模型的嵌套写法,可针对遇到的两个问题单独修复:

  1. 权重加载报错:调用load_weights时添加by_name=True参数,适配嵌套模型的权重匹配逻辑:
model.load_weights('~path/weights.hdf5', by_name=True)
  1. 提取嵌套层中间输出构建新模型:先基于VGG子模型构建中间层输出的子模型,再关联到主模型输入即可:
vgg_submodel = model.get_layer('vgg16')
# 构建VGG子模型的中间层输出模型
intermediate_model = Model(inputs=vgg_submodel.input, outputs=vgg_submodel.layers[1].output)
# 关联主模型输入,得到最终可视化模型
model2 = Model(inputs=model.input, outputs=intermediate_model(model.input), name='Vis_Model')

内容的提问来源于stack exchange,提问作者Joey Fueng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 19:30:04