使用TensorFlow 1.8遇类型错误:无法将generator转为Tensor求解决
解决TensorFlow 1.8中
TypeError: Failed to convert object of type <class 'generator'> to Tensor问题 嘿,这个错误我太熟了——你肯定是把Python生成器直接塞给TensorFlow 1.8的API了!TF1.x的计算图模式可不认生成器这玩意儿,得用它原生的数据管道来处理才行。结合你的indices.csv和wordvecs.csv格式,我给你一步步解决:
先唠清楚你的数据结构
先确认下我理解的没错:
indices.csv:每行是逗号分隔的整数序列,每个序列内部用空格拆数字(比如1 4 2,5 3 5,2 0就是3个样本,对应[1,4,2]、[5,3,5]、[2,0])wordvecs.csv:每行是空格分隔的词向量,每个向量用逗号拆浮点数(每个向量对应indices里的一个整数索引)
替换生成器,用TF原生数据管道
TF1.8里最稳妥的方式是用tf.data.TextLineDataset读文本文件,再用映射函数处理每行,完全绕开Python生成器。下面是完整示例:
1. 写好数据解析的辅助函数
先搞两个函数分别处理两个文件的每行内容:
import tensorflow as tf def parse_indices_line(line): # 把一行逗号分隔的序列拆成单个序列 split_seqs = tf.string_split([line], ',').values # 每个序列转成整数张量,再堆叠成批次 indices = tf.stack([ tf.string_to_number(tf.string_split([seq], ' ').values, out_type=tf.int32) for seq in split_seqs ]) return indices def parse_wordvecs_line(line): # 把一行空格分隔的向量拆成单个向量 split_vecs = tf.string_split([line], ' ').values # 每个向量转成浮点张量,再堆叠成批次 wordvecs = tf.stack([ tf.string_to_number(tf.string_split([vec], ',').values, out_type=tf.float32) for vec in split_vecs ]) return wordvecs
2. 搭建完整的数据管道
# 读取indices文件,逐行解析 indices_dataset = tf.data.TextLineDataset("indices.csv") indices_dataset = indices_dataset.map(parse_indices_line) # 读取wordvecs文件,逐行解析 wordvecs_dataset = tf.data.TextLineDataset("wordvecs.csv") wordvecs_dataset = wordvecs_dataset.map(parse_wordvecs_line) # 如果两个文件是每行一一对应的(比如indices的第一行对应wordvecs的第一行),就把它们配对 combined_dataset = tf.data.Dataset.zip((indices_dataset, wordvecs_dataset)) # 打乱数据、分批(参数根据你的数据集大小调整) combined_dataset = combined_dataset.shuffle(buffer_size=1000).batch(32) # 创建迭代器,用来取批次数据 iterator = combined_dataset.make_initializable_iterator() next_batch = iterator.get_next()
3. 在会话里跑起来
with tf.Session() as sess: sess.run(iterator.initializer) while True: try: batch_indices, batch_wordvecs = sess.run(next_batch) # 这里就可以把批次数据喂给你的模型啦 print("批次indices形状:", batch_indices.shape) print("批次wordvecs形状:", batch_wordvecs.shape) except tf.errors.OutOfRangeError: # 所有数据遍历完就退出 break
为啥你原来会报错?
大概率是你写了个Python生成器来读数据,然后直接传给TF的操作了,比如这样:
# 错误示范!别这么干 def data_generator(): with open("indices.csv", 'r') as f: for line in f: yield process_line(line) # 直接把生成器塞给TF,就会触发那个类型转换错误 dataset = tf.data.Dataset.from_generator(data_generator, ...)
虽然TF1.14之后from_generator好用多了,但TF1.8的这个API限制超多,很容易踩类型转换的坑。所以咱用上面的TextLineDataset+map方案更靠谱,全程用TF的操作处理数据,和Python生成器划清界限。
额外提个醒
- 如果你的
wordvecs.csv是每行一个词向量(不是一行多个),那改下parse_wordvecs_line,去掉外层的tf.stack,直接处理单个向量就行。 - 检查下你的数据文件有没有空行,空行会导致
string_split返回空值,引发错误。可以在映射函数里加个过滤逻辑,跳过空行。
内容的提问来源于stack exchange,提问作者Uvuvwevwe
相关产品推荐
相关产品推荐

