TensorFlow2.4.1使用VGGFace训练时报错'int'无shape属性求解
问题修复方案
报错1:'int' object has no attribute 'shape'
原因
自定义生成器返回的labels是由Python原生int组成的列表,Keras在数据校验阶段需要读取标签的shape属性,原生int不存在该属性,因此触发报错。
修复方法
在生成器的yield语句前,将labels转换为numpy数组:
def gen(list_tuples, person_to_images_map, batch_size=16): ppl = list(person_to_images_map.keys()) while True: batch_tuples = sample(list_tuples, batch_size // 2) labels = [1] * len(batch_tuples) while len(batch_tuples) < batch_size: p1 = choice(ppl) p2 = choice(ppl) if p1 != p2 and (p1, p2) not in list_tuples and (p2, p1) not in list_tuples: batch_tuples.append((p1, p2)) labels.append(0) for x in batch_tuples: if not len(person_to_images_map[x[0]]): print(x[0]) X1 = [choice(person_to_images_map[x[0]]) for x in batch_tuples] X1 = np.array([read_img(x) for x in X1]) X2 = [choice(person_to_images_map[x[1]]) for x in batch_tuples] X2 = np.array([read_img(x) for x in X2]) # 新增以下行,转换标签为numpy数组 labels = np.array(labels) yield [X1, X2], labels
报错2:'generator' object is not subscriptable
原因
- 你新增的
x=np.array(x)属于多余操作,完全不需要修改遍历batch_tuples的循环,该修改不会解决第一个问题,反而可能引入额外异常。 - 该报错的核心是你对生成器对象直接使用了下标访问(比如
valx[0]):生成器是迭代器,本身不支持下标取值。如果修改生成器代码后没有重新执行valx赋值的代码块,valx还是生成器对象,就会触发该报错。
修复方法
- 把你修改的循环代码改回原始版本:
for x in batch_tuples: if not len(person_to_images_map[x[0]]): print(x[0])
- 用更稳妥的方式获取验证集batch,避免迭代器取值错误:
# 替换原来的valx赋值和for循环代码 val_gen = gen(val, val_person_to_images_map, batch_size=100) valx = next(val_gen)
可选优化
TensorFlow 2.x已经废弃fit_generator方法,直接用fit即可支持生成器输入,训练代码可以修改为:
history = model.fit( gen(train, train_person_to_images_map, batch_size=16), use_multiprocessing=True, validation_data=(valx[0],valx[1]), epochs=50, verbose=1, workers = 4, callbacks=callbacks_list, steps_per_epoch=200 )
内容的提问来源于stack exchange,提问作者Shubhasmita Roy
相关产品推荐
相关产品推荐

