搭建物理信息神经网络时遇EagerTensor无_keras_history错误与gather弃用警告
PINN 调试问题排查与修复
问题成因
AttributeError: 'EagerTensor' object has no attribute '_keras_history'触发原因:
Keras函数式API构建模型时,要求所有作为输入、输出的张量必须是经过Keras层操作生成、携带计算图追踪标记的KerasTensor。自定义DifferentiationLayer在call方法内通过GradientTape计算得到的u_t、u_x、u_xx属于脱离Keras层追踪的EagerTensor,后续基于这些张量在层外计算得到的residual直接作为模型输出时,Keras无法追溯其所属的计算层链路,因此抛出属性错误。- TensorFlow弃用警告触发原因:
该警告是TensorFlow内部执行batch_jacobian算子时,底层实现调用gather操作传入了已废弃的validate_indices参数,属于框架内部的版本兼容提示,不影响实际计算逻辑。
修复方案
修复_keras_history属性报错
核心调整思路是将残差计算逻辑移入自定义微分层内部完成,保证所有输出张量都在Keras层的追踪上下文中生成,避免无追踪的EagerTensor直接作为模型输出。
- 修改
DifferentiationLayer实现,将残差计算逻辑整合到层内class DifferentiationLayer(tf.keras.layers.Layer): def __init__(self, network, nu, **kwargs): self.u_network = network self.nu = nu super().__init__(**kwargs) def call(self, res_pts): with tf.GradientTape() as tape2: tape2.watch(res_pts) with tf.GradientTape() as tape1: tape1.watch(res_pts) u = self.u_network(res_pts) u_tx = tape1.batch_jacobian(u, res_pts) u_t = u_tx[..., 0] u_x = u_tx[..., 1] u_xx = tape2.batch_jacobian(u_x, res_pts)[..., 1] # 层内直接计算残差,保证输出被Keras追踪 residual = u_t + u*u_x - self.nu*u_xx return residual - 调整
PINN类的初始化与模型构建逻辑,适配修改后的微分层class PINN: def __init__(self, nu, lb, ub, layers=[2, 20, 20, 20, 20, 1], activation="tanh"): self.u_NN = uNN.build(lb, ub, layers=layers, activation=activation) self.nu = nu self.diff = DifferentiationLayer(self.u_NN, nu) self.model = self.build_model() def build_model(self): res_pts = tf.keras.layers.Input(shape=(2,)) IC_pts = tf.keras.layers.Input(shape=(2,)) BC_pts = tf.keras.layers.Input(shape=(2,)) residual = self.diff(res_pts) u_IC = self.u_NN(IC_pts) u_BC = self.u_NN(BC_pts) return tf.keras.models.Model( inputs=[res_pts, IC_pts, BC_pts], outputs=[residual, u_IC, u_BC] )
处理弃用警告
该警告为TensorFlow框架内部的冗余版本提示,不影响代码运行。如果需要屏蔽该类非致命警告,可在导入TensorFlow后添加日志过滤配置:
import tensorflow as tf # 过滤非致命的框架提示日志 tf.get_logger().setLevel('ERROR')
内容的提问来源于stack exchange,提问作者Omega
相关产品推荐
相关产品推荐

