运行CNN情感分析模型时遇TypeError: len() of unsized object错误求助
len() of unsized object错误 看起来你在运行Twitter情感分析的CNN模型时踩了Python 3迭代器的坑,我来帮你梳理问题和解决方案:
错误详情
你遇到的错误栈如下:
File "twitter-sentiment-cnn.py", line 292, in
test_batches = list(batch_iter(zip(x_test, y_test), FLAGS.batch_size, 1))
File "/home/sanaa/Sentimental/Cnn/twitter-sentiment-cnn/data_helpers.py", line 179, in batch_iter
data_size = len(data1)
TypeError: len() of unsized object
问题根源
这个错误的核心原因是:Python 3中的zip()函数返回的是一个迭代器对象,而不是可计算长度的序列(比如列表)。迭代器是按需生成元素的,没有固定的长度,所以当batch_iter函数尝试调用len(data1)时,就会抛出这个类型错误。
如果你的训练代码batches = batch_iter(zip(x_train, y_train), FLAGS.batch_size, FLAGS.epochs)没报错,大概率是训练阶段的x_train和y_train被提前转换成了列表,或者代码中隐含了将zip结果转为列表的操作,但测试阶段漏掉了这一步。
解决方案
这里提供两种简单可行的解决办法:
方案1:调用batch_iter前将zip结果转为列表
直接在传入batch_iter之前,把zip(x_test, y_test)和zip(x_train, y_train)转换成列表,这样就可以正常计算长度了:
if FLAGS.train: # 批次处理:将zip结果转为列表 batches = batch_iter(list(zip(x_train, y_train)), FLAGS.batch_size, FLAGS.epochs) # 测试批次处理同样转换 test_batches = list(batch_iter(list(zip(x_test, y_test)), FLAGS.batch_size, 1))
方案2:修改batch_iter函数适配迭代器
如果你不想每次调用都手动转列表,可以直接修改data_helpers.py中的batch_iter函数,在开头先将输入数据转为列表:
def batch_iter(data, batch_size, num_epochs, shuffle=True): # 先将输入数据转为列表,确保可以获取长度 data = list(data) data_size = len(data) num_batches_per_epoch = int((data_size - 1) / batch_size) + 1 for epoch in range(num_epochs): # 每个epoch打乱数据(如果需要) if shuffle: shuffle_indices = np.random.permutation(np.arange(data_size)) shuffled_data = [data[shuffle_indices[i]] for i in range(data_size)] else: shuffled_data = data # 生成批次数据 for batch_num in range(num_batches_per_epoch): start_index = batch_num * batch_size end_index = min((batch_num + 1) * batch_size, data_size) yield shuffled_data[start_index:end_index]
这样不管传入的是迭代器还是序列,函数都会先统一转为列表,彻底避免len()报错的问题。
内容的提问来源于stack exchange,提问作者sany wright

