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

TensorFlow2/Keras训练调用get/set_weights报图函数无法取值错误的解决方法

错误产生的根本原因

get_weights()、set_weights()是专门为eager模式设计的接口:

  • 调用get_weights()时,底层会执行.numpy()把权重张量转成Python可直接操作的numpy数组
  • 调用set_weights()时,会把传入的numpy数组转成张量,覆写对应层的权重值

而Keras运行fit()时,会自动把重写的train_step编译成带图执行的tf.function函数,静态图环境禁止直接读取张量的实际数值做numpy转换,因此就抛出了Cannot get value inside Tensorflow graph function的错误。

可正常运行的实现方式

核心逻辑是跳出“取numpy数组-算完再塞回去”的流程,全程留在TensorFlow张量计算体系里完成权重操作,完全适配静态图的执行规则:

  • 不调用get_weights()、set_weights(),直接通过模型的weights属性拿到对应编码器的权重张量列表——这个列表的顺序、形状和get_weights()返回的numpy数组列表完全一致,不会出现权重错位
  • EMA的加权计算直接在张量层面完成,计算完通过权重自带的assign()方法直接完成赋值,这个接口是原生支持静态图执行的,不会触发numpy取值的报错。

修正后的代码

只需要替换原来的update_ema方法,其余训练逻辑可以保留:

def update_ema(self, decay=0.999):
    # 直接拿权重张量,不触发numpy转换
    online_weights = self.online_encoder.weights
    target_weights = self.target_encoder.weights
    # 逐权重计算EMA值并直接赋值
    for online_w, target_w in zip(online_weights, target_weights):
        new_target_w = decay * target_w + (1 - decay) * online_w
        target_w.assign(new_target_w)
调试时的注意点
  • 替换完逻辑后,可以先跑eager模式的单步训练验证:确认两个编码器的权重列表顺序完全匹配,不会出现因为层结构不同导致的权重错位赋值。
  • 静态图包裹的所有方法里,都不要调用.numpy()、get_weights()、set_weights()这类会触发跨环境取值的操作,一旦在图函数里调用,必然会触发同类报错。
  • 初始化模型时要把target_encoder的所有权重标记为non_trainable=True,避免优化器把它的权重纳入梯度更新范围,和后续的EMA赋值逻辑产生冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 17:27:04