保存和读取自定义Tensorflow模型

保存和读取自定义Tensorflow模型,tensorflow,keras,model,save,layer,Tensorflow,Keras,Model,Save,Layer,我正在使用tensorflow 2.3生成一个自定义编码器/解码器网络。我可以生成、培训和评估网络;但是,当我尝试将其保存到文件并随后加载它时,会根据我是否在急切执行模式下运行而出现不同的错误: 如果没有急切模式,代码运行良好并显示结果。但是,会显示一条警告: tensorflow/core/common_runtime/graph_constructor.cc:808]节点“max_pool_layer_with_index/PartitionedCall”有2个输出,但 _“输出形状”属性为

我正在使用tensorflow 2.3生成一个自定义编码器/解码器网络。我可以生成、培训和评估网络;但是,当我尝试将其保存到文件并随后加载它时,会根据我是否在急切执行模式下运行而出现不同的错误:

  • 如果没有急切模式,代码运行良好并显示结果。但是,会显示一条警告:
  • tensorflow/core/common_runtime/graph_constructor.cc:808]节点“max_pool_layer_with_index/PartitionedCall”有2个输出,但 _“输出形状”属性为4个输出指定形状。输出形状可能不准确

    我不明白4的输出从哪里来。我的图层定义有问题吗

  • 在急切执行模式下,当我尝试使用经过训练的模型进行预测时,tensorflow返回一个错误:
  • 找不到要从SavedModel加载的调用的匹配函数。获取:位置参数(共1个): tf.Tensor(…,shape=(1,256,256,1),dtype=float32)关键字 参数:{'training':False}期望这些参数与一个匹配 以下2个选项中的一个:选项1:位置参数(2 总数): *TensorSpec(shape=(None,256,256,1),dtype=tf.float32,name='input_1') *False关键字参数:{}选项2:位置参数(共2个): *TensorSpec(shape=(None,256,256,1),dtype=tf.float32,name='input_1') *True关键字参数:{}

    我试图生成一个最小的示例来重现该问题:

    将tensorflow导入为tf
    从tensorflow.python.framework导入tensor_形状
    从tensorflow进口keras
    从tensorflow.python.keras导入后端
    从tensorflow.python.keras.engine.base_层导入层
    从tensorflow.python.keras.engine.input\u spec导入InputSpec
    从tensorflow.python.keras.utils导入conv_utils
    将matplotlib.pyplot作为plt导入
    类MaxPoolLayerWithindicates(层):
    def uuu init uuuu(self,in_shape,pool_size=(2,2),步长=无,padding='valid',
    数据(格式=无,名称=无,**kwargs):
    super(MaxPoolLayerWithIndices,self)。\uuuuu init\uuuuu(name=name,trainable=False,**kwargs)
    如果数据格式为“无”:
    数据\格式=后端。图像\数据\格式()
    如果“跨步数”为“无”:
    步幅=池大小
    self.pool\u size=conv\u utils.normalize\u元组(pool\u size,2,“pool\u size”)
    self.strips=conv_utils.normalize_元组(strips,2,“strips”)
    self.padding=conv_utils.normalize_padding(padding)
    self.data\u format=conv\u utils.normalize\u data\u format(数据格式)
    self.input\u spec=InputSpec(ndim=4)
    #self.in_shape=in_shape
    @功能
    def呼叫(自我,输入):
    如果self.data\u format=='channels\u last':
    池_形状=(1,)+self.pool_大小+(1,)
    步幅=(1,)+自我。步幅+(1,)
    其他:
    池_形状=(1,1)+self.pool_大小
    步幅=(1,1)+自我步幅
    res=tf.nn.max\u pool\u带argmax(
    输入,ksize=池形,步长=步长,
    padding=self.padding.upper(),output\u dtype=tf.int64,
    data\u format=conv\u utils.convert\u data\u format(self.data\u format,4))
    返回res
    def计算输出形状(自身、输入形状):
    input_shape=tensor_shape.TensorShape(input_shape).as_list()
    如果self.data\u format==“channels\u first”:
    行=输入_形[2]
    cols=输入_形状[3]
    其他:
    行=输入_形[1]
    cols=输入_形状[2]
    rows=conv_utils.conv_output_length(行,self.pool_size[0],
    self.padding,self.strips[0])
    cols=conv_utils.conv_output_length(cols,self.pool_size[1],
    自我填充,自我跨步[1])
    如果self.data\u format==“channels\u first”:
    形状=张量(
    [输入形状[0],输入形状[1],行,列])
    其他:
    形状=张量(
    [输入_形[0],行,列,输入_形[3])
    返回[形状,形状]
    def get_配置(自身):
    配置={
    “池大小”:self.pool\u size,
    “padding”:self.padding,
    “跨步”:自我跨步,
    “数据格式”:self.data\u格式
    }
    base_config=super(MaxPoolLayerWithIndices,self).get_config()
    return dict(list(base_config.items())+list(config.items())
    类SimpleModel(tf.keras.Model):
    def uuu init uuuuuu(自身、形状、过滤器大小=3):
    super(SimpleModel,self)。\uuuu init\uuuuu()
    #设置参数
    self.filter\u size=过滤器大小
    #创建层
    self.input\u layer=tf.keras.layers.InputLayer(input\u shape=in\u shape,batch\u size=1)
    self.conv_layer=tf.keras.layers.Conv2D(1[filter_size,filter_size],步长=(1,1),padding='same',use_bias=False)
    self.pooling_layer=MaxPoolLayerWithIndices(在_形状中,池大小=(2,2),步幅=(2,2),填充=‘有效’)
    @功能
    def呼叫(自我,输入):
    x=自输入层(输入)
    x、 ind=自池层(自转换层(x))
    返回x
    tf.config.run_函数(True)
    #设置输入路径
    模型\u文件名='E:\\simple\u test\u model'
    #初始化GPU
    GPU=tf.config.experimental.list\u物理\u设备('GPU'))
    tf.config.experimental.set_memory_growth(GPU[0],True)
    #创建随机数据集
    ds=tf.data.Dataset.from_tensor_切片((tf.random.uniform([1256256,1]),tf.random.uniform([1128128,1]))。批次(1)。重复()
    img,lbl=下一个(国际热核实验堆(ds))
    #生成模型
    模型=SimpleModel([256256])
    #编译模型
    model.compile(优化器='adam',
    loss=tf.keras.loss.CategoricalCrossentropy(from_logits=False),35; SparseCategoricCrossEntropy
    指标=[‘准确度’])
    #列车模型
    模型历史=model.fit(ds,历元=1,每历元步长=10)
    #保存模型
    model.save(model\u文件)