TensorFlow自定义层创建报错:递归深度超出限制
TensorFlow自定义层触发RecursionError的解决方法
问题详情
在TensorFlow 2.17.0版本中实现自定义全连接层时,出现如下递归深度超出错误:
File /opt/anaconda3/lib/python3.11/site-packages/tensorflow/python/util/lazy_loader.py:178 in __getattr__ if item in ("_tfll_mode", "_tfll_initialized", "_tfll_name"): 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], initializer='random_normal', # Initialize with random values trainable=True ) def call(self, inputs): return tf.matmul(inputs, self.kernel) input_dim = 4 # Number of input features output_dim = 2 # Match the target data output dimension layer = MyDenseLayer(output_dim) # Create a simple model model = tf.keras.Sequential([ layer, tf.keras.layers.Dense(2) # Ensure the final output matches the target ]) # Compile the model model.compile(optimizer='adam', loss='mse') # Create random input data x = tf.random.normal((5, input_dim)) # Batch size of 5 y = tf.random.normal((5, 2)) # Random target data for training # Train the model model.fit(x, y, epochs=10)
解决方案
该错误源于TensorFlow LazyLoader模块的递归引用问题,可通过以下几种方式修复:
1. 简化父类初始化调用
将__init__方法中的父类初始化语句改为Python 3简化写法,避免显式传递类名和self引发的递归:
def __init__(self, num_outputs): super().__init__() self.num_outputs = num_outputs
2. 避免提前实例化自定义层
不要先实例化自定义层再传入Sequential,直接在模型定义中声明层类:
model = tf.keras.Sequential([ MyDenseLayer(output_dim), tf.keras.layers.Dense(2) ])
提前实例化的层会在模型构建阶段触发不必要的属性访问递归。
3. 显式指定dtype(可选)
在__init__中添加dtype参数并传递给父类,避免类型推断时触发LazyLoader递归:
def __init__(self, num_outputs, dtype=None): super().__init__(dtype=dtype) self.num_outputs = num_outputs
修复后的完整代码
import tensorflow as tf class MyDenseLayer(tf.keras.layers.Layer): def __init__(self, num_outputs): super().__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], initializer='random_normal', trainable=True ) def call(self, inputs): return tf.matmul(inputs, self.kernel) input_dim = 4 output_dim = 2 model = tf.keras.Sequential([ MyDenseLayer(output_dim), tf.keras.layers.Dense(2) ]) model.compile(optimizer='adam', loss='mse') x = tf.random.normal((5, input_dim)) y = tf.random.normal((5, 2)) model.fit(x, y, epochs=10)
内容的提问来源于stack exchange,提问作者tew_evolving
相关产品推荐
相关产品推荐

