使用Scikit-learn感知器训练裁剪版SVHN数据集,准确率仅21%求优化
解决SVHN数据集上Perceptron分类准确率过低的问题
我来帮你排查下为什么你的Perceptron在SVHN上准确率只有21%——这里有几个关键的问题,咱们一个个来解决:
1. SVHN标签的特殊映射问题
你可能没注意到,SVHN数据集的标签里,数字0是用10来标记的,而Perceptron默认会把它当成一个独立的第10类,但我们实际要分类的是0-9这10个数字。这种标签不匹配会让模型完全搞不清分类目标,这是准确率极低的核心原因之一。
解决方法:把标签里的10替换成0:
label = train['y'].ravel() label[label == 10] = 0 # 新增这一行,修正标签映射
2. 图像特征未做归一化
Perceptron是线性模型,对特征的尺度非常敏感。你的图像像素值是0-255的范围,没有归一化的话,大数值的特征会主导权重更新,导致模型无法有效学习到关键特征。
解决方法:把像素值归一化到0-1的范围,同时优化你手动循环flatten的冗余操作:
# 替换原来的X_train初始化和循环,直接处理 X_train = data.reshape(data.shape[0], -1) / 255.0 # 扁平化+归一化一步完成
3. Perceptron模型本身的局限性
要明确:Perceptron是最简单的线性二分类模型,虽然Scikit-learn的Perceptron支持多分类(通过一对多策略),但SVHN是复杂的自然图像数据,线性模型本身很难捕捉到图像的非线性特征。所以即使解决了前面的问题,准确率也不会特别高(大概能到70%左右),如果想要更高的准确率,你可能需要尝试SVM、随机森林或者深度学习模型,但先把基础问题解决,至少能回到合理的水平。
修改后的完整代码
import scipy.io as sio import numpy as np from sklearn.linear_model import Perceptron from sklearn.metrics import accuracy_score # 加载数据 train = sio.loadmat("train_32x32.mat") test = sio.loadmat("test_32x32.mat") # 预处理训练数据 data = train["X"] data = np.transpose(data, [3, 0, 1, 2]) # 调整维度为(样本数, 高, 宽, 通道数) data = np.mean(data, axis=3) # 转灰度图 # 扁平化特征+归一化 X_train = data.reshape(data.shape[0], -1) / 255.0 # 修正标签映射 label = train['y'].ravel() label[label == 10] = 0 # 训练模型 clf = Perceptron() clf.fit(X_train, label) # 评估 train_acc = clf.score(X_train, label) print(f"训练集准确率: {train_acc:.2f}") predict = clf.predict(X_train) print(f"准确率验证: {accuracy_score(label, predict):.2f}")
额外建议
- 别忘了对测试集做完全一样的预处理(转灰度、扁平化、归一化、标签修正),再评估测试集准确率,只看训练集准确率容易忽略过拟合问题。
- 如果想要进一步提升效果,可以尝试给Perceptron加上
penalty='l2'(L2正则化),或者调整eta0(学习率)参数,比如Perceptron(eta0=0.01, penalty='l2')。
内容的提问来源于stack exchange,提问作者Alessandro Raspanti
相关产品推荐
相关产品推荐

