You need to enable JavaScript to run this app. 如何将Keras模型导出为.pbtxt文件 解决TF2.2+Keras2.3环境转换报错
优惠活动
大模型
产品
解决方案
定价
更多

如何将Keras模型导出为.pbtxt文件 解决TF2.2+Keras2.3环境转换报错

TF2.2+Keras2.3环境下pbtxt模型保存适配方案

报错根因

该Input 0 of node ... AssignSubVariableOp incompatible with expected resource错误为指定版本组合的原生兼容问题:

  • 按要求使用独立安装的keras.applications.DenseNet121时,模型内部BatchNorm、卷积层的变量,是基于独立Keras的资源管理逻辑创建的Resource类型节点
  • 参考教程使用的convert_variables_to_constants_v2接口在TF2.2版本中,无法正确识别独立Keras创建的Resource类型变量,会错误地把普通float值传入要求Resource类型输入的节点端口,触发图导入时的类型校验失败。

适配操作流程(严格保留要求的DenseNet导入方式)

1. 前置环境兼容配置

在模型构建前,完成Keras后端与当前TF图的绑定,避免资源管理脱节:

import tensorflow as tf
# 关闭eager模式,匹配Keras2.3对静态图的兼容要求
tf.compat.v1.disable_eager_execution()

# 严格按要求保留该DenseNet导入,禁止替换为tf.keras对应接口
from keras.applications import DenseNet121
from keras.models import Sequential
from keras.layers import Dense
from keras import backend as K
# 绑定Keras后端会话到当前TF静态图
K.set_session(tf.compat.v1.Session())

2. 模型构建修正

在原有模型结构基础上,补充全局池化层匹配低版本下的维度推导逻辑,不改变模型预测行为:

opt = tf.keras.optimizers.Adam(learning_rate=1e-4) # 替换为你实际使用的优化器配置
densenet_wrapper = DenseNet121(weights='imagenet',
                        include_top=False,
                        input_shape=(224, 224, 3))

def build_model():
    model = Sequential()
    model.add(densenet_wrapper)
    # 补充全局平均池化,消除低版本下4维特征图到Dense层的维度推导错误
    model.add(tf.keras.layers.GlobalAveragePooling2D())
    model.add(Dense(5, activation=tf.keras.activations.relu))
    model.add(Dense(1, activation="linear"))
    model.compile(loss='mse',
                  optimizer=opt,
                  metrics=['mse', 'acc'])
    print(model.summary())
    return model

model = build_model()

3. 低版本兼容的模型冻结与pbtxt保存逻辑

替换原教程中易触发类型不匹配的tf.function转换逻辑,使用TF2.2兼容的图冻结接口:

import os
# 提前创建模型保存目录
save_dir = './pbtxt_save_dir'
os.makedirs(save_dir, exist_ok=True)
output_pb_name = 'frozen_graph.pbtxt'

# 获取当前会话的图定义,以及模型的输出节点名称
sess = K.get_session()
output_node_name = model.output.op.name

# 使用TF2.2原生的常量转换接口,冻结所有变量
from tensorflow.python.framework import graph_util
frozen_graph_def = graph_util.convert_variables_to_constants(
    sess=sess,
    input_graph_def=sess.graph.as_graph_def(),
    output_node_names=[output_node_name]
)

# 写入文本格式的pbtxt文件
tf.io.write_graph(
    graph_or_graph_def=frozen_graph_def,
    logdir=save_dir,
    name=output_pb_name,
    as_text=True
)

校验注意事项

  • 保存完成后,可打开pbtxt文件确认输入节点维度为[None, 224, 224, 3],输出节点为线性激活层的对应Op,无缺失的Resource类型节点
  • 禁止中途将独立Keras的DenseNet121替换为tf.keras对应接口,否则会触发图重复初始化,再次出现Resource类型不匹配的报错
  • 若运行时出现图节点重复报错,可在脚本最开头增加Keras会话重置操作:K.clear_session()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 07:15:03