TensorFlow模型训练报错:output_signature需为tf.TypeSpec子类而非list
问题解决:TensorFlow训练时
output_signature类型错误 问题背景
使用微软AutonomousDrivingCookbook中的AirSim训练笔记本及DriveDataGenerator类训练模型时,触发TypeError,提示output_signature必须包含tf.TypeSpec的子类对象,但检测到<class 'list'>。检查生成器代码未发现明显问题,需要修复该错误以完成训练。
报错日志
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[26], line 1 ----> 1 history = model.fit(train_generator, steps_per_epoch=num_train_examples//batch_size, epochs=500, callbacks=callbacks, 2 validation_data=eval_generator, validation_steps=num_eval_examples//batch_size, verbose=1) File ~\anaconda3\envs\my-conda-env\Lib\site-packages\keras\src\utils\traceback_utils.py:122, in filter_traceback.<locals>.error_handler(*args, **kwargs) 119 filtered_tb = _process_traceback_frames(e.__traceback__) 120 # To get the full stack trace, call: 121 # `keras.config.disable_traceback_filtering()` --> 122 raise e.with_traceback(filtered_tb) from None 123 finally: 124 del filtered_tb File ~\anaconda3\envs\my-conda-env\Lib\site-packages\tensorflow\python\data\ops\from_generator_op.py:124, in _from_generator(generator, output_types, output_shapes, args, output_signature, name) 122 for spec in nest.flatten(output_signature): 123 if not isinstance(spec, type_spec.TypeSpec): --> 124 raise TypeError(f"`output_signature` must contain objects that are " 125 f"subclass of `tf.TypeSpec` but found {type(spec)} " 126 f"which is not.") 127 else: 128 if output_types is None: TypeError: `output_signature` must contain objects that are subclass of `tf.TypeSpec` but found <class 'list'> which is not.
报错触发代码
history = model.fit(train_generator, steps_per_epoch=num_train_examples//batch_size, epochs=500, callbacks=callbacks, validation_data=eval_generator, validation_steps=num_eval_examples//batch_size, verbose=1)
解决方案
该错误源于TensorFlow版本兼容性问题:旧版AutonomousDrivingCookbook代码适配早期TensorFlow版本,新版TF(2.7+)对tf.data.Dataset.from_generator的output_signature格式要求更严格,不允许直接传入列表类型的签名。以下是具体修复步骤:
1. 修改DriveDataGenerator的输出结构
找到Generator.py中的__getitem__方法,将返回的列表改为元组或numpy数组:
- 原代码示例:
return image_array, [steering_angle, throttle] - 修改为:
# 改为元组 return image_array, (steering_angle, throttle) # 或直接返回numpy数组 return image_array, np.array([steering_angle, throttle], dtype=np.float32)
2. 手动指定Dataset的output_signature
如果生成器被包装为tf.data.Dataset,需明确指定符合tf.TypeSpec的输出签名:
import tensorflow as tf # 根据你的数据尺寸调整shape参数 output_signature = ( tf.TensorSpec(shape=(140, 256, 3), dtype=tf.float32), tf.TensorSpec(shape=(2,), dtype=tf.float32) ) train_dataset = tf.data.Dataset.from_generator( lambda: train_generator, output_signature=output_signature )
之后用train_dataset替代train_generator传入model.fit即可。
3. 降级TensorFlow版本(可选)
如果不想修改代码,可以将TensorFlow降级到2.6或更早版本,适配原Cookbook的代码逻辑:
pip install tensorflow==2.6
内容的提问来源于stack exchange,提问作者D S Raigagla
相关产品推荐
相关产品推荐

