基于Gabor滤波器、PCA与SVM的手写数字识别低准确率问题咨询
基于Gabor滤波器+PCA+SVM的手写数字分类准确率过低问题
我正尝试使用Python构建一个简单程序,通过Gabor滤波器实现手写数字分类。
我采用MNIST数据集进行训练,实现步骤如下:
- 计算不同方向和尺度下Gabor滤波器的相位信息。
- 执行PCA对相位特征进行降维处理。
- 采用径向基函数作为核的SVM进行分类。
我使用的代码如下:
# 导入所需库 import numpy as np from sklearn.decomposition import PCA from sklearn import svm from skimage.filters import gabor import matplotlib.pyplot as plt from sklearn.model_selection import cross_val_score from sklearn.model_selection import train_test_split import idx2numpy from sklearn.model_selection import KFold from sklearn.multiclass import OneVsOneClassifier # 加载MNIST数据集 trainX = idx2numpy.convert_from_file("data/train-images-idx3-ubyte") labelsX = idx2numpy.convert_from_file("data/train-labels-idx1-ubyte") features = np.empty((1, 2)) labels = np.empty((1,)) mxm = 100 for i in range(mxm): image = trainX[i] for freq in np.arange(0.2,1.2,0.2): for orientation in range(0,360,45): # 对第i张图像在给定尺度和方向下计算Gabor滤波结果 filt_real, filt_imag = gabor(image,frequency=freq,theta=orientation) # 用实部和虚部计算相位 phase = np.angle(filt_real + 1.0j*filt_imag) # 初始化2成分PCA pca = PCA(n_components=2) # 对相位矩阵拟合PCA pca.fit(phase) # 特征降维 curr = pca.transform(phase) # 追加特征 features = np.append(features,curr,axis=0) # 追加标签 labels = np.append(labels,[labelsX[i]]*len(curr)) kf = KFold(n_splits=mxm) counter = 1 for train, test in kf.split(features): print('折数',counter) counter = counter + 1 X_train, X_test, y_train, y_test = features[train], features[test], labels[train], labels[test] clf = OneVsOneClassifier(svm.SVC(kernel='rbf')) clf.fit(X_train,y_train) print('准确率:',clf.score(X_test,y_test))
但运行后得到的准确率非常低,仅约0.1。我不希望使用神经网络方案,特此问询:结合PCA的SVM是否是Gabor滤波器特征提取的合适策略?
问题解答
结合PCA的SVM本身是Gabor特征提取后非常成熟的分类策略,你的准确率过低不是策略本身的问题,是代码实现逻辑有多处错误:
- PCA使用逻辑错误:你当前是对单张图的单个Gabor相位输出(28*28矩阵)做PCA降维,相当于把单张图的单个滤波结果拆成了多组特征,而正确的做法是先为每张图生成全局特征向量,再对整个数据集的全局特征矩阵做PCA降维。
- 特征选择不合理:Gabor相位特征对图像位移非常敏感,手写数字的微小位置偏移都会导致相位大幅变化,区分度远低于Gabor幅度特征,建议优先使用幅度特征做后续处理。
- 特征构造逻辑错误:你将同一张图的多个Gabor输出的降维结果拆成了多个独立样本,复用同一个标签,相当于混淆了样本和特征的边界,正确的做法是每张图对应唯一的特征向量:把所有Gabor输出的统计特征(如均值、方差、能量等)拼接成一个1维向量作为该图的特征。
- 训练样本量不足:你仅使用了100张训练图,远不足以支撑SVM拟合10分类的边界,建议至少使用1000张以上训练图,条件允许的话用全量MNIST训练集。
- 交叉验证逻辑错误:你设置KFold的折数等于训练样本数100,相当于留一验证,但你的特征构造逻辑错误导致验证结果完全不具备参考性。
按上述逻辑修改后,该方案可以达到95%以上的MNIST分类准确率。
内容的提问来源于stack exchange,提问作者user16478428
相关产品推荐
相关产品推荐

