Keras训练7类图像分类器时出现val_ins未定义错误求助
问题排查与修复方案
首先,触发UnboundLocalError: local variable 'val_ins' referenced before assignment的直接原因是你调用classifier.fit()时,validation_data参数只传入了测试图像数据test_data,却没有传入对应的测试标签。Keras要求validation_data必须是**(验证数据, 验证标签)**的元组,缺失标签会导致内部处理验证流程时出现变量未定义的错误。
接下来我们一步步修复你的代码:
1. 补全测试标签的收集逻辑
你目前只收集了测试图像,完全没处理测试标签,需要在读取测试图像的循环中添加标签收集的代码:
test_labels = [] # 新增:初始化测试标签列表 for label,labelData in labelList: dir = "mlData/test/" + label for img in os.listdir(dir): path = os.path.join(dir, img) img = Image.open(path) img = img.convert('RGB') img = img.resize((imageSide, imageSide), Image.ANTIALIAS) img = np.array(img) test_data.append(img) test_labels.append(labelData) # 新增:将当前图像对应的标签加入列表 test_labels = np.array(test_labels) # 新增:转成numpy数组,和训练标签格式统一
2. 修正validation_data参数格式
在fit()方法中,把validation_data改成包含测试数据和标签的元组:
classifier.fit( train_data, train_labels, steps_per_epoch=110, # 这里需要修改,原因见下文 epochs=10, validation_data=(test_data, test_labels), # 修正:传入数据+标签的元组 validation_steps=110 # 同样需要修改,原因见下文 )
3. 修复多分类任务的核心配置问题
你的任务是7个类别的图像分类,属于标准多分类任务,但当前代码有两个关键设置错误:
- 最后一层激活函数用了
sigmoid:多分类任务应该用softmax,它能保证所有类别的概率之和为1,符合分类任务的概率逻辑; - loss函数用了
binary_crossentropy:针对one-hot格式标签的多分类任务,应该使用categorical_crossentropy。
修改模型的输出层和编译配置:
# 把最后一层的sigmoid改成softmax classifier.add(Dense(units = 7, activation = 'softmax')) # 把loss改成categorical_crossentropy classifier.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])
4. 修正steps_per_epoch和validation_steps的取值
你的训练数据只有3502个样本,默认batch_size是32,steps_per_epoch的合理值应该是训练样本数 // batch_size(即3502//32≈110),而不是你设置的8000——这个数值远大于实际样本量,会导致Keras反复遍历训练数据,既低效又无意义。同理,validation_steps应该设置为测试样本数//batch_size(3506//32≈110)。
额外优化建议
- 对图像数据做归一化处理:将像素值除以255,把数据范围缩放到[0,1],这能帮助模型更快收敛:
train_data = train_data / 255.0 test_data = test_data / 255.0
- 替换弃用的API:
Image.ANTIALIAS在PIL新版本中已被弃用,建议改用Image.Resampling.LANCZOS,避免版本兼容警告。
把这些修改整合后,你的代码应该就能正常运行并开始训练了。
内容的提问来源于stack exchange,提问作者Omroth
相关产品推荐
相关产品推荐

