TensorFlow 1.6读取TFRecords报错:features应为Tensor字典
解决TensorFlow 1.6.0中TFRecords训练的ValueError问题
这个报错ValueError: features should be a dictionary of Tensors. Given type: <class 'tensorflow.python.framework.ops.Tensor'> 本质是**TFRecords数据的输出格式和模型输入要求不匹配**——你直接读CSV时返回的是特征字典,而转成TFRecords后,解析逻辑可能返回了单个Tensor,导致模型(尤其是tf.estimator.Estimator`这类组件)无法识别。结合你的TensorFlow 1.6.0版本,我给你具体的排查和解决步骤:
1. 检查TFRecords的解析函数(最常见问题)
你的解析函数大概率直接返回了单个特征张量,而没有封装成字典。模型期望的输入是{特征名: 张量}的结构,和CSV读取时的输出对齐。
错误示例(导致报错):
def parse_tfrecord(example_proto): # 定义特征解析格式 feature_desc = { 'age': tf.FixedLenFeature([], tf.float32), 'income': tf.FixedLenFeature([], tf.float32), 'label': tf.FixedLenFeature([], tf.int64) } parsed_features = tf.parse_single_example(example_proto, feature_desc) # 错误:直接返回合并后的特征张量,而非字典 combined_features = tf.stack([parsed_features['age'], parsed_features['income']]) return combined_features, parsed_features['label']
正确示例:
方式1:保留多特征字典
如果模型需要多个独立特征输入,直接返回特征字典和标签:
def parse_tfrecord(example_proto): feature_desc = { 'age': tf.FixedLenFeature([], tf.float32), 'income': tf.FixedLenFeature([], tf.float32), 'label': tf.FixedLenFeature([], tf.int64) } parsed_features = tf.parse_single_example(example_proto, feature_desc) # 提取特征字典(去掉label)和标签 feature_dict = {k: v for k, v in parsed_features.items() if k != 'label'} return feature_dict, parsed_features['label']
方式2:合并特征后封装成字典
如果需要合并特征为单个张量,也要把它放进字典(键名要和模型输入层对应):
def parse_tfrecord(example_proto): feature_desc = { 'age': tf.FixedLenFeature([], tf.float32), 'income': tf.FixedLenFeature([], tf.float32), 'label': tf.FixedLenFeature([], tf.int64) } parsed_features = tf.parse_single_example(example_proto, feature_desc) combined_features = tf.stack([parsed_features['age'], parsed_features['income']]) # 包装成字典,键名需和模型的特征列/输入层名称一致 return {'combined_features': combined_features}, parsed_features['label']
2. 验证Dataset的输出格式
构建TFRecords Dataset时,确保map后的输出是(特征字典, 标签)的结构:
# 加载TFRecords文件 dataset = tf.data.TFRecordDataset('your_data.tfrecords') # 应用解析函数 dataset = dataset.map(parse_tfrecord) # 批量处理 dataset = dataset.batch(32) # 如果用Estimator,train_input_fn要返回这个dataset或者(feature_dict, label)的迭代器 def train_input_fn(): return dataset.make_one_shot_iterator().get_next()
3. 对齐模型输入与特征字典
如果使用tf.estimator,你的特征列要和特征字典的键名完全匹配。比如用方式2的字典时,特征列应该定义为:
feature_columns = [tf.feature_column.numeric_column('combined_features', shape=[2])]
额外提示:检查TFRecords写入逻辑
如果写入TFRecords时没有按字典结构存储特征,也会导致解析后无法生成正确的字典。写入时要确保每个特征都被封装到tf.train.Features中:
def serialize_example(age, income, label): feature = { 'age': tf.train.Feature(float_list=tf.train.FloatList(value=[age])), 'income': tf.train.Feature(float_list=tf.train.FloatList(value=[income])), 'label': tf.train.Feature(int64_list=tf.train.Int64List(value=[label])), } example_proto = tf.train.Example(features=tf.train.Features(feature=feature)) return example_proto.SerializeToString()
这样调整后,TFRecords的输出格式就和CSV读取时一致了,应该能解决这个报错。
内容的提问来源于stack exchange,提问作者LIN
相关产品推荐
相关产品推荐

