目录
1 项目描述 1
2 基于决策树模型手写数字识别 2
2.1 算法设计 3
2.2 性能分析 3
- 选择 gini 系数,还是信息熵 4
- 是否采取贪心的算法 (是否一直采用最大信息熵增 4
- 预剪枝 (叶子节点个数) 4
3 基于 SVM 模型手写数字识别 4
3.1 SVM 算法设计 4
3.2 SVM 模型性能分析 5
4 基于 ANN 模型手写数字识别 5
图 11. 核函数的选择 5
4.1 MNIST 数据集 5
4.2 ANN 结构 5
4.3 数据增广 5
4.4 ANN 模型性能分析 6
5 图像切割技术 6
6 前端页面设计 6
6.1 题目的聚光灯效果 6
6.2 按钮的流光效果 7
6.3 时钟的特效与 js 实现 8
6.4 动态科技曲线的设计外部引入的前端框架 8
6.5 飘落樱花的设计 8
6.6 图片的上传 8
6.7 ajax 前后端通信 9
2基于决策树模型手写数字识别
决策树是一种树形结构,其中每个内部节点表示一个属 性上的测试,每个分支代表一个测试输出,每个叶节点代表 一种类别。每个决策树都表述了一种树型结构,它由它的分 支来对该类型的对象依靠属性进行分类。每个决策树可以 依靠对源数据库的分割进行数据测试。这个过程可以递归 式的对树进行修剪。当不能再进行分割或一个单独的类可 以被应用于某一分支时,递归过程就完成了。
3基于 SVM 模型手写数字识别
3.1SVM 算法设计
SVM 分类算法以另一个角度来考虑问题。其思路是获取大量的手写数字,常称作训练样本,然后开发出一个可以从这些训练样本中进行学习的系统。换言之,SVM 使用样本来自动推断出识别手写数字的规则。随着样本数量的增加,算法可以学到更多关于手写数字的知识,这样就能够提升自身的准确性。对于分类问题。我们会将数据集分成三部分,训练集、测试集、交叉验证集。用训练集训练生成模型, 用测试集和交叉验证集进行验证模型的准确性。
我们分别使用了 Linear,Poly,Rbf,Sigmoid 四种核函数 对数据进行训练,SVM 模型有两个非常重要的参数 C 与gamma。其中 C 是惩罚系数,即对误差的宽容度。c 越高, 说明越不能容忍出现误差, 容易过拟合。C 越小,容易欠拟合。C 过大或过小,泛化能力变差。gamma 是选择 RBF 函数作为 kernel 后,该函数自带的一个参数。隐含地决定了数据映射到新的特征空间后的分布,gamma 越大,支持向量越少,gamma 值越小,支持向量越多。支持向量的个数影响训练与预测的速度。
8总结
1.我们用了三种算法对手写数字识别进行了实现,决 策树模型的精确度达到了 84.8%, SVM 模型我们最终选择了 poly 核函数,它的精确度达到了 95.7%, ANN 模型的精确度达到了 99.1%. 在这个过程中我们使用到了流出法和交叉验证和自助法分别求解精确度,上述的精确度我们采用了 十折十次交叉验证,精确度是相对稳定的一个指标
2.用精确度还是无法完全地评估一个模型,所以我们 又分别对三个模型进行了 ROC 曲线,PR 曲线,混淆矩阵的分析,从 ROC 曲线可以看出,本文转载自http://www.biyezuopin.vip/onews.asp?id=14885ANN 模型是优于 SVM 模型和决策树模型的,SVM 模型又是优于决策树模型的。PR 曲线同样是可以反应模型的能力的,特别地,PR 曲线对于样本比例是比较敏感的,从 PR 曲线来看,我们的样本比例应该是比较均衡的,事实上,我们从样本的成分分析得出了 相同的结论。混淆矩阵也能反映模型的能力,能够看到模型的错误样本。
3.本项目还有一个亮点就是做了数据增广,这个数据 增广只在 ANN 模型中做了比较,通过数据增广 (具体可以见技术手册),我们提高了 ANN 模型的性能,这从精确度, ROC 图等上都可以反映出来。特别是最后,我们测试自己手写的图片的时候,ANN 通过的数据增广训练后的表现是明显要优于其他两个模型的,它大大提高了数据的泛化能 力。
4.最后我们做了一个展示的界面,用到了 Html,CSS, JavaScript,Flask 框架等知识,学到了机器学习之外的,也是很有意思的知识。在写出漂亮网页的同时,我们感觉自我的修行和对美的感受也得到了升华,真的是受益匪浅啊!
import torch
import numpy as np
from MNIST_ANN import load_model
from DataLoader_ import MNIST_DS
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve,auc,precision_recall_curve
import os
os.environ['KMP_DUPLICATE_LIB_OK'] = 'TRUE'
class Visionlization(object):
def __init__(self,model,DataLoader,ClassSize):
self.model=model
self.DataLoader=DataLoader
self.size=ClassSize
self.Pmat=self.Mat=np.zeros(shape=(ClassSize,ClassSize))
# 计算混淆矩阵
def GetConfusionMatrix(self):
self.model.eval()
for X,y in self.DataLoader:
logit=self.model(X)
PredClass=logit.argmax(1).item()
self.Mat[y][PredClass]+=1
# 行归一化矩阵
self.PMat= self.Mat.astype('float32') / np.sum(self.Mat, axis=1)[:, np.newaxis]
# 可视化混淆矩阵
def PlotConfusionMatrix(self,SaveName='./ConMat01',title='ConfusionMatrix'):
plt.figure(figsize=(10,10),dpi=80)
x=np.arange(self.size)
X,Y=np.meshgrid(x,x)
for a,b in zip(X.flatten(),Y.flatten()):
val=self.PMat[a][b]
if val>0.001:
plt.text(a,b,'%.3f'%val,color='red',fontsize=10,va='center',ha='center')
plt.imshow(self.PMat, interpolation='nearest', cmap=plt.cm.binary)
plt.title(title,fontsize=15,color='black')
plt.colorbar()
space=np.arange(self.size)
plt.xticks(space,space,fontsize=10,rotation=90)
plt.yticks(space, space, fontsize=10, rotation=0)
plt.xlabel('Actual label',fontsize=15,color='black')
plt.ylabel('Predict label',fontsize=15,color='black')
# 调整刻度
tick_marks = np.array(range(self.size)) + 0.5
plt.gca().set_xticks(tick_marks, minor=True)
plt.gca().set_yticks(tick_marks, minor=True)
plt.gca().xaxis.set_ticks_position('none')
plt.gca().yaxis.set_ticks_position('none')
plt.grid(True, which='minor', linestyle='-')
plt.gcf().subplots_adjust(bottom=0.15)
# 保存图片
plt.savefig(SaveName,format='png')
plt.show()
# 计算one-hot编码的标签和分数
def GetParament(self):
scores=[]
labels=[]
for k in range(self.size):
self.model.eval()
score = []
label = []
for X, y in self.DataLoader:
logit = self.model(X)
score.append(logit.squeeze()[k].item())
if y.item() == k:
t = 1
else:
t = 0
label.append(t)
scores.append(score)
labels.append(label)
return labels,scores
# 可视化ROC曲线
def plotROC(self):
colors=['black','red','green','blue','yellow','gray','snow','navy','gold','cyan']
titles=['0','1','2','3','4','5','6','7','8','9']
fpr={}
tpr={}
roc_auc={}
labels,scores=self.GetParament()
for k in range(self.size):
fpr[k],tpr[k],_=roc_curve(labels[k],scores[k])
roc_auc[k]=auc(fpr[k],tpr[k])
plt.plot(fpr[k],tpr[k],color=colors[k],label=titles[k]+':AUC{0:.3f}'.format(roc_auc[k]))
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC Curve')
plt.xlim([-0.05, 1.05])
plt.ylim([-0.05, 1.05])
plt.legend(loc="lower right")
plt.show()
# 可视化测试集上准确度
def plotAccuary(self):
# 文件保存了准确率accuracy,迭代次数epoch,学习率lr,块大小bas
Paraments=np.load('test_accuracy64_100_99_1.npz')
print(Paraments['accuracy'])
epoch = [k + 1 for k in range(100)]
plt.plot(epoch, Paraments['accuracy'], color='green', linestyle='-.')
plt.xlabel('epochs')
plt.ylabel('test accuracy')
plt.xlim([1, 100])
plt.ylim([0, 1])
x_ticks=[k for k in range(1,101,10)]
y_ticks=np.linspace(0,1,10)
plt.xticks(x_ticks,x_ticks)
plt.yticks(y_ticks)
plt.show()
# 可视化PR曲线
def plotPR(self):
colors = ['black', 'red', 'green', 'blue', 'yellow', 'gray', 'snow', 'navy', 'gold', 'cyan']
titles = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
pre = {}
rec = {}
labels, scores = self.GetParament()
for k in range(self.size):
pre[k], rec[k], _ = precision_recall_curve(labels[k], scores[k])
plt.plot(pre[k], rec[k], color=colors[k], label=titles[k])
plt.xlabel('precision')
plt.ylabel('Precision')
plt.title('Recall')
plt.xlim([-0.05, 1.05])
plt.ylim([-0.05, 1.05])
plt.legend(loc="lower right")
plt.show()
# 可视化权重变化
def plotWeight(self):pass
# 可视化数据集
def plotDataSet(self):
test_size = {k: 0 for k in range(10)}
for x, y in self.DataLoader:
test_size[y.item()] += 1
sizes = test_size.values()
labels = test_size.keys()
colors = ['black', 'red', 'green', 'blue', 'yellow', 'gray', 'snow', 'navy', 'gold', 'cyan']
plt.pie(sizes, labels, colors=colors)
plt.show()
if __name__ == '__main__':
# 加载模型
model = load_model()
# 模型的参数是一个有序字典,以模型序列中带有参数的层的名字命名
Paraments=torch.load('best_Augment_with_weight_decay_Data100.pth')
model.load_state_dict(Paraments)
load_data=DataLoader(dataset=MNIST_DS(kind=False,AugmentData=False),batch_size=1)
MatVision=Visionlization(model,load_data,10)
# MatVision.GetConfusionMatrix()
# MatVision.PlotConfusionMatrix()
# MatVision.plotROC()
# MatVision.plotPR()
# MatVision.plotAccuary()
# MatVision.plotDataSet()