使用神经网络对手写体数字图片数据分类(MLP/PCA)

使用神经网络对手写体数字图片数据分类(MLP/PCA)

使用sklearn.neural_network.MLPClassifier类实现手写数字图片识别
MLP的常用的几个参数一般为activation(选择激活函数,如relu,sigmod等,计算效率不一样),solver(权重优化算法,adam,sgd,lbfgs等,小数据集<如本项目>一般选用lbfgs效果更佳,收敛速度也更快。),alpha(正则化项参数),hidden_layer_sizes(隐藏层参数,(200,100,50)即为三层,每层神经元个数为200、100、50),此外还有batch_size:随机优化的minibatches的大小;learning_rate:学习率,constant、invscaling、adaptive;learning_rate_init:初始学习率。只有当solver为sgd或adam时才使用;power_t:逆扩展学习率的指数,只有当solver为sgd时才使用;max_iter:最大迭代次数,具体用法可以直接查文档。

来看一下不降维直接使用MLP进行识别的情况。

from sklearn.neural_network import MLPClassifier
import joblib
import numpy as np
from sklearn.metrics import accuracy_score
#加载数据集
data=np.loadtxt(r"C:/Users/Downloads/digits_training.csv",skiprows=1, delimiter=',')
#查看前五行数据和数据集大小
print("first five lines::", data[:4,:])
print("data shape:",data.shape[0])
xTrain = data[:, 1:]
yTrain = data[:, 0]
def normalizeData(X):
    return (X - X.mean())/X.max()
#数据初始化
xTrain=normalizeData(xTrain)
#建立模型,拟合mlp模型
model = MLPClassifier(activation='relu',solver= "lbfgs" ,alpha=1e-6, hidden_layer_sizes=(200, 100, 50))
model.fit(xTrain,yTrain)
#使用joblib保存模型
print("save train model")
joblib.dump(model, "mlp_classifier_model1.m")
#测试集
data2=np.loadtxt(r"C:\Users\csh\Downloads\digits_testing.csv",skiprows=1, delimiter=',')
print("first five lines:", data2[:4,:])
print("data shape:",data2.shape[0])
xTest= data2[:, 1:]
yTest = data2[:, 0]
xTest=normalizeData(xTest)
#载入模型
model2=joblib.load("mlp_classifier_model1.m")
#预测模型
pred=model2.predict(xTest)
#打印错误数据
print("error data:",(pred != yTest).sum())
#评价模型
print("accuracy_predict;",accuracy_score(yTest,pred))

mlp

我们可以看到经过训练过后,测试集的准确率能达到93.8%,模型训练耗时39.9s,重复几次发现准确率基本稳定在93%左右。
使用sklearn.decomposition的PCA类对手写体数字图片数据进行降维后的情况。
PCA降维即主成分分析,主成分分析的原理非常简单,概括来说就是选择包含信息量大的维度,去除信息量少的“干扰”维度。原理:
1.数据从原来的坐标系转换到新的坐标系,新坐标系的选择是由数据本身决定的。第一个新坐标轴选择的是原始数据中方差最大的方向(即数据差异性最大的方向),第二个新坐标轴选择与第一个新坐标轴正交且具有最大方差的方向,以此类推,共建立与原始数据特征数目相等的新坐标轴。
2.大部分方差都包含在最前面的几个新坐标轴中,因此我们可以忽略余下的坐标轴,从而实现降维。
我们先来画一个图确认方差解释程度,利用matplotlib库画图

from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import numpy as np
data=np.loadtxt(r"C:/Users/Downloads/digits_training.csv",skiprows=1, delimiter=',')
xTrain = data[:, 1:]
yTrain = data[:, 0]
def normalizeData(X):
    return X - np.mean(X, axis=0)
xTrain=normalizeData(xTrain)
pca = PCA(n_components=xTrain.shape[1])
pca.fit(xTrain)
print(pca.explained_variance_ratio_)
'''表示取前n个主成分能解释多少百分比的方差'''
plt.plot([i for i in range(xTrain.shape[1])],\
         [np.sum(pca.explained_variance_ratio_[:i+1]) for i in range(xTrain.shape[1])])
plt.show()

图片
对于方差解释度我们既要顾忌准确程度,也要顾忌效率,我们可以看见大约在150左右的维度能达到95%以上(其实准确计算后发现149时达到95%)
接下来我们使用pca降维后用mlp进行识别

from sklearn.decomposition import PCA
from sklearn.neural_network import MLPClassifier
from timeit import default_timer as timer
import joblib
import numpy as np
from sklearn.metrics import accuracy_score
tic=timer()
data=np.loadtxt(r"C:/Users/Downloads/digits_training.csv",skiprows=1, delimiter=',')
print("data shape:",data.shape[0])
xTrain = data[:, 1:]
yTrain = data[:, 0]
def normalizeData(X):
    return X - np.mean(X, axis=0)
xTrain=normalizeData(xTrain)
pca=PCA(n_components=0.95)
pca.fit(xTrain)
xTrain_re=pca.transform(xTrain)
model = MLPClassifier(activation='relu',solver= "lbfgs" ,alpha=1e-6, hidden_layer_sizes=(200, 100, 50))
model.fit(xTrain_re,yTrain)
print("save train model")
joblib.dump(model, "mlpNN_pca.m")
#测试集
data2=np.loadtxt(r"C:\Users\Downloads\digits_testing.csv",skiprows=1, delimiter=',')
print("first five lines:", data2[:4,:])
print("data shape:",data2.shape[0])
xTest= data2[:, 1:]
yTest = data2[:, 0]
xTest=normalizeData(xTest)
xTest_re=pca.transform(xTest)
#载入模型
model2=joblib.load("mlpNN_pca.m")
#预测模型
pred=model2.predict(xTest_re)
print("error data:",(pred != yTest).sum())
#评价模型
print("accuracy_predict;",accuracy_score(yTest,pred))
toc=timer()
print(toc-tic)

pca

pca降维后分类准确率有所降低,达到90.4%,是正常情况,去掉部分维度后肯定是有所降低,但是我们可以看见训练模型的时间显著缩短,只用了16.2s,差不多是未降维时训练时间的2/5,可见pca降维对训练模型效率的提升有显著帮助。带来的准确率损失相比之下就并不突出了。

  • 8
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值