Keras fit_generator报数组真值歧义错误排查
错误定位
报错The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()的触发原因是传入fit_generator的class_weight参数类型不符合Keras要求。
你代码中计算得到的classWeight是numpy数组类型,但Keras要求class_weight必须是键为类别索引、值为对应类别权重的Python字典。框架内部处理该参数时会做键值合法性判断,直接传入numpy数组就会触发多元素数组真值判断的歧义报错。
另外你的代码还存在一处隐藏的适配问题:flow_from_directory设置了class_mode="categorical",会输出one-hot编码的二维类别标签,但你编译模型时用的损失函数是binary_crossentropy,二者形状不匹配,就算解决了前面的报错,训练时也会抛出维度错误。
修复步骤
- 把numpy数组格式的类别权重转换为字典格式,替换原代码中
classWeight=classTotals.max()/classTotals这一行为:
classWeight = {i: w for i, w in enumerate(classTotals.max() / classTotals)}
- 把模型编译时的损失函数替换为和categorical标签匹配的
categorical_crossentropy,对应修改代码为:
model.compile(loss="categorical_crossentropy",optimizer=opt,metrics=["accuracy"])
修正后可正常运行的训练段代码
# 类别权重计算部分 trainLabels=[int(p.split(os.path.sep)[-2]) for p in trainPaths] trainLabels=np_utils.to_categorical(trainLabels) classTotals=trainLabels.sum(axis=0) classWeight = {i: w for i, w in enumerate(classTotals.max()/classTotals)} # 模型编译与训练部分 model=CancerNet.build(width=48,height=48,depth=3,classes=2) opt=Adagrad(lr=INIT_LR,decay=INIT_LR/NUM_EPOCHS) model.compile(loss="categorical_crossentropy",optimizer=opt,metrics=["accuracy"]) M=model.fit_generator( trainGen, steps_per_epoch=lenTrain//BS, validation_data=valGen, validation_steps=lenVal//BS, class_weight=classWeight, epochs=NUM_EPOCHS)
内容的提问来源于stack exchange,提问作者jonathan pascal
相关产品推荐
相关产品推荐

