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

TensorFlow自定义层实现时递归深度超出错误求助

TensorFlow自定义层实现时递归深度超出错误求助

问题描述

我照着TensorFlow官方文档写了自定义全连接层的代码,在Spyder里用TensorFlow 2.17.0运行时,却遇到了RecursionError: maximum recursion depth exceeded in comparison的错误,实在摸不着头脑,麻烦各位帮忙看看问题出在哪?

我的代码如下:

import tensorflow as tf
class MyDenseLayer(tf.keras.layers.Layer):
  def __init__(self, num_outputs):
    super(MyDenseLayer, self).__init__()
    self.num_outputs = num_outputs

  def build(self, input_shape):
    self.kernel = self.add_weight("kernel",
                                  shape=[int(input_shape[-1]),
                                         self.num_outputs])

  def call(self, inputs):
    return tf.matmul(inputs, self.kernel)

layer = MyDenseLayer(10)

_ = layer(tf.zeros([10, 5])) # Calling the layer `.builds` it.
print([var.name for var in layer.trainable_variables])

错误回溯信息:

Traceback (most recent call last):
File "/Users/xoxo/Documents/test.py", ...


我的解答

这种递归错误通常是某个方法被无限调用导致的,结合TensorFlow 2.17.0的版本特性和Spyder环境,给你几个排查和解决的方向:

  1. 修正super调用的写法
    在Python 3中,虽然super(MyDenseLayer, self).__init__()是合法写法,但新版本的TensorFlow可能在处理这种显式指定类名的调用时出现兼容性问题。建议改成Python 3推荐的简化写法:

    def __init__(self, num_outputs):
      super().__init__()
      self.num_outputs = num_outputs
    

    这种写法更简洁,也能避免一些潜在的继承链问题。

  2. 排查Spyder环境的变量冲突
    Spyder的交互式环境经常会保留之前运行的变量,如果你之前已经定义过layer或者MyDenseLayer同名对象/类,可能会导致新旧定义冲突,触发无限递归。解决办法:

    • 点击Spyder工具栏的“重启内核”按钮,清空环境后重新运行代码
    • 或者在代码开头添加%reset -f(IPython魔法命令)强制清除所有变量
  3. 显式完成层的构建流程
    有时候新版本TensorFlow对自定义层的构建流程要求更严格,你可以尝试在build方法中显式调用父类的build方法,确保层的初始化流程完整:

    def build(self, input_shape):
      super().build(input_shape)  # 调用父类的build方法
      self.kernel = self.add_weight("kernel",
                                    shape=[int(input_shape[-1]),
                                           self.num_outputs])
    
  4. 定位递归触发点
    如果上面的方法都没用,建议在关键方法里加打印语句,看看哪个方法被反复调用:

    def __init__(self, num_outputs):
      print("进入__init__方法")
      super().__init__()
      self.num_outputs = num_outputs
    
    def build(self, input_shape):
      print(f"进入build方法,输入形状:{input_shape}")
      super().build(input_shape)
      self.kernel = self.add_weight("kernel",
                                    shape=[int(input_shape[-1]),
                                           self.num_outputs])
    
    def call(self, inputs):
      print("进入call方法")
      return tf.matmul(inputs, self.kernel)
    

    运行后如果看到某条打印信息重复输出,那就是递归的源头,再针对性解决。

一般来说,第一种或者第二种方法就能解决你遇到的问题,先试试重启Spyder内核再运行修改后的代码吧!

备注:内容来源于stack exchange,提问作者tew_evolving

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 14:53:05