使用Keras+Scikit-learn处理多维输入多输出CAPTCHA数据集遇错求助
解决Scikeras+GridSearchCV多输出CAPTCHA识别的类型不匹配错误
问题概述
使用CNN识别5字符文本CAPTCHA,通过Scikeras将Keras模型接入scikit-learn的GridSearchCV调参时,触发以下错误:
ValueError: Classification metrics can't handle a mix of multilabel-indicator and multiclass-multioutput targets
初始训练数据形状:
train_X shape: (856, 50, 200, 1) train_y shape: (5, 856, 36)
转换后的y_sklearn被scikit-learn判定为multilabel-indicator类型,但模型实际为5个独立的多分类任务,导致指标计算时类型冲突。
核心原因
scikit-learn默认的accuracy评分器无法兼容当前数据格式:输入的y_sklearn是拼接后的独热编码数组,被识别为多标签格式;而模型输出是5个独立的多分类结果,属于多分类多输出类型,两者不匹配。
修复步骤
1. 替换GridSearchCV的默认评分器
直接使用自定义的scorer方法,替代内置的'accuracy':
# 修改main.py中的GridSearchCV初始化 grid_search = GridSearchCV( estimator=clf, verbose=3, param_grid=param_grid, scoring=MO.MultiOutputClassifier.scorer )
2. 修正MultiOutputTransformer的inverse_transform方法
当前方法返回类别索引数组,与自定义scorer期望的独热编码格式不匹配,调整为返回独热编码:
# 修改MO.py中的inverse_transform方法 def inverse_transform(self, y: List[np.ndarray], return_proba: bool = False) -> np.ndarray: y_pred_proba = y if return_proba: # 修正column_stack参数错误 return np.column_stack(y_pred_proba) # 生成与y_true结构一致的独热编码 y_pred_onehot = [] for probs in y_pred_proba: pred_idx = np.argmax(probs, axis=1) onehot = np.zeros_like(probs) onehot[np.arange(len(pred_idx)), pred_idx] = 1 y_pred_onehot.append(onehot) return np.column_stack(y_pred_onehot)
3. 规范y_sklearn的生成逻辑(可选)
直接从labels生成拼接后的独热编码数组,避免形状转换错误:
# 替换main.py中原有的y生成代码 characters = "0123456789" + string.ascii_lowercase y_sklearn = np.zeros((len(labels), 5 * len(characters))) for j in range(len(labels)): for i in range(5): char_pos = characters.index(labels[j][i]) y_sklearn[j, i*len(characters) + char_pos] = 1 # 拆分训练/验证/测试集 train_y = y_sklearn[:int(0.8 * len(X))] validation_y = y_sklearn[int(0.8 * len(X)):int(0.9 * len(X))] test_y = y_sklearn[int(0.9 * len(X)):]
效果验证
修改后,GridSearchCV会调用自定义评分器,将y_true和y_pred拆分为5个独立的多分类任务,分别计算准确率后取均值,彻底解决类型不匹配的问题。
内容的提问来源于stack exchange,提问作者Kadam
相关产品推荐
相关产品推荐

