写在开头
本文主要是记录个人所学所得,若有错误,请各位朋友指出~
本次实验用到的计算机语言:Python 3.7
手写体数据集来源:http://amlbook.com/support.html
本文的训练及测试数据均采用原生特征~
改变
紧接着上一篇文章——基于人工神经网络(ANN)对手写体数据集的辨识度分析(一)
我决定进一步用神经网络对数据进行测试,但这次我使用的数据将是原生数据,也就是这些手写体图片的256个灰度值
程序三
此程序同样先对 ‘1’ 与 ‘ 5’ 进行个别判定,但我对神经网络的隐藏层数增加至2层
输入:<zip.train> / <zip.test>
输出:最优训练模型 + 各模型准确率
1、读取训练数据文件,建立存储列表
#读取原生数据文件
f=open(r"zip.train","r")
#读取所有行数据
lines=f.readlines()
#建立存储列表
feature=[]
label=[]
m=[]
s=[]
2、提取数字 ‘1’ 与 ‘5’ 的原生数据,存入对应列表
#逐行读取数据
for line in lines:
#每行数据以空格作分割
line_split=line.split(' ')
#提取出‘1’与‘5’的数据
if line_split[0][0]=='1' or line_split[0][0]=='5':
#将标签数据置入标签列表
label.append(float(line_split[0]))
#将特征值置入特征列表,由于有256个值,我直接无脑操作置入
feature.append((float(line_split[1]),float(line_split[2]),float(line_split[3]),float(line_split[4]),float(line_split[5]),float(line_split[6]),float(line_split[7]),float(line_split[8]),float(line_split[9]),float(line_split[10]),float(line_split[11]),float(line_split[12]),float(line_split[13]),float(line_split[14]),float(line_split[15]),float(line_split[16]),
float(line_split[17]),float(line_split[18]),float(line_split[19]),float(line_split[20]),float(line_split[21]),float(line_split[22]),float(line_split[23]),float(line_split[24]),float(line_split[25]),float(line_split[26]),float(line_split[27]),float(line_split[28]),float(line_split[29]),float(line_split[30]),float(line_split[31]),float(line_split[32]),
float(line_split[33]),float(line_split[34]),float(line_split[35]),float(line_split[36]),float(line_split[37]),float(line_split[38]),float(line_split[39]),float(line_split[40]),float(line_split[41]),float(line_split[42]),float(line_split[43]),float(line_split[44]),float(line_split[45]),float(line_split[46]),float(line_split[47]),float(line_split[48]),
float(line_split[49]),float(line_split[50]),float(line_split[51]),float(line_split[52]),float(line_split[53]),float(line_split[54]),float(line_split[55]),float(line_split[56]),float(line_split[57]),float(line_split[58]),float(line_split[59]),float(line_split[60]),float(line_split[61]),float(line_split[62]),float(line_split[63]),float(line_split[64]),
float(line_split[65]),float(line_split[66]),float(line_split[67]),float(line_split[68]),float(line_split[69]),float(line_split[70]),float(line_split[71]),float(line_split[72]),float(line_split[73]),float(line_split[74]),float(line_split[75]),float(line_split[76]),float(line_split[77]),float(line_split[78]),float(line_split[79]),float(line_split[80]),
float(line_split[81]),float(line_split[82]),float(line_split[83]),float(line_split[84]),float(line_split[85]),float(line_split[86]),float(line_split[87]),float(line_split[88]),float(line_split[89]),float(line_split[90]),float(line_split[91]),float(line_split[92]),float(line_split[93]),float(line_split[94]),float(line_split[95]),float(line_split[96]),
float(line_split[97]),float(line_split[98]),float(line_split[99]),float(line_split[100]),float(line_split[101]),float(line_split[102]),float(line_split[103]),float(line_split[104]),float(line_split[105]),float(line_split[106]),float(line_split[107]),float(line_split[108]),float(line_split[109]),float(line_split[110]),float(line_split[111]),float(line_split[112]),
float(line_split[113]),float(line_split[114]),float(line_split[115]),float(line_split[116]),float(line_split[117]),float(line_split[118]),float(line_split[119]),float(line_split[120]),float(line_split[121]),float(line_split[122]),float(line_split[123]),float(line_split[124]),float(line_split[125]),float(line_split[126]),float(line_split[127]),float(line_split[128]),
float(line_split[129]),float(line_split[130]),float(line_split[131]),float(line_split[132]),float(line_split[133]),float(line_split[134]),float(line_split[135]),float(line_split[136]),float(line_split[137]),float(line_split[138]),float(line_split[139]),float(line_split[140]),float(line_split[141]),float(line_split[142]),float(line_split[143]),float(line_split[144]),
float(line_split[145]),float(line_split[146]),float(line_split[147]),float(line_split[148]),float(line_split[149]),float(line_split[150]),float(line_split[151]),float(line_split[152]),float(line_split[153]),float(line_split[154]),float(line_split[155]),float(line_split[156]),float(line_split[157]),float(line_split[158]),float(line_split[159]),float(line_split[160]),
float(line_split[161]),float(line_split[162]),float(line_split[163]),float(line_split[164]),float(line_split[165]),float(line_split[166]),float(line_split[167]),float(line_split[168]),float(line_split[169]),float(line_split[170]),float(line_split[171]),float(line_split[172]),float(line_split[173]),float(line_split[174]),float(line_split[175]),float(line_split[176]),
float(line_split[177]),float(line_split[178]),float(line_split[179]),float(line_split[180]),float(line_split[181]),float(line_split[182]),float(line_split[183]),float(line_split[184]),float(line_split[185]),float(line_split[186]),float(line_split[187]),float(line_split[188]),float(line_split[189]),float(line_split[190]),float(line_split[191]),float(line_split[192]),
float(line_split[193]),float(line_split[194]),float(line_split[195]),float(line_split[196]),float(line_split[197]),float(line_split[198]),float(line_split[199]),float(line_split[200]),float(line_split[201]),float(line_split[202]),float(line_split[203]),float(line_split[204]),float(line_split[205]),float(line_split[206]),float(line_split[207]),float(line_split[208]),
float(line_split[209]),float(line_split[210]),float(line_split[211]),float(line_split[212]),float(line_split[213]),float(line_split[214]),float(line_split[215]),float(line_split[216]),float(line_split[217]),float(line_split[218]),float(line_split[219]),float(line_split[220]),float(line_split[221]),float(line_split[222]),float(line_split[223]),float(line_split[224]),
float(line_split[225]),float(line_split[226]),float(line_split[227]),float(line_split[228]),float(line_split[229]),float(line_split[230]),float(line_split[231]),float(line_split[232]),float(line_split[233]),float(line_split[234]),float(line_split[235]),float(line_split[236]),float(line_split[237]),float(line_split[238]),float(line_split[239]),float(line_split[240]),
float(line_split[241]),float(line_split[242]),float(line_split[243]),float(line_split[244]),float(line_split[245]),float(line_split[246]),float(line_split[247]),float(line_split[248]),float(line_split[249]),float(line_split[250]),float(line_split[251]),float(line_split[252]),float(line_split[253]),float(line_split[254]),float(line_split[255]),float(line_split[256]),))
3、建立神经网络训练模型,采用三重交叉验证,导出最优训练模型
#隐藏层数为2 各层的神经元数量分别为6与2
units=(6,2)
#三重交叉验证
kf=KFold(n_splits=3)
for train,test in kf.split(feature):
#模型训练
model=MLPClassifier(solver='sgd',alpha=1e-5,hidden_layer_sizes=units,random_state=1)
model.fit(np.array(feature)[train],np.array(label)[train])
#准确率计算
score=model.score(np.array(feature)[test],np.array(label)[test])
#存储准确率
s.append(score)
#存储训练模型
m.append(model)
#显示准确率
print(s)
#导出最优训练模型
joblib.dump(m[1],'Q3_train.pkl')
4、利用最优训练模型对测试集数据进行检测
#读取测试数据集
f=open(r"zip.test","r")
#读取所有行
lines=f.readlines()
feature=[]
label=[]
#遍历所有行读取数据
for line in lines:
#每行数据以空格作分割
line_split=line.split(' ')
#提取测试集中的‘1’和‘5’的数据
if line_split[0][0]=='1' or line_split[0][0]=='5':
#置入标签值
label.append(float(line_split[0]))
#置入特征值
featurefeature.append((float(line_split[1]),float(line_split[2]),float(line_split[3]),float(line_split[4]),float(line_split[5]),float(line_split[6]),float(line_split[7]),float(line_split[8]),float(line_split[9]),float(line_split[10]),float(line_split[11]),float(line_split[12]),float(line_split[13]),float(line_split[14]),float(line_split[15]),float(line_split[16]),
float(line_split[17]),float(line_split[18]),float(line_split[19]),float(line_split[20]),float(line_split[21]),float(line_split[22]),float(line_split[23]),float(line_split[24]),float(line_split[25]),float(line_split[26]),float(line_split[27]),float(line_split[28]),float(line_split[29]),float(line_split[30]),float(line_split[31]),float(line_split[32]),
float(line_split[33]),float(line_split[34]),float(line_split[35]),float(line_split[36]),float(line_split[37]),float(line_split[38]),float(line_split[39]),float(line_split[40]),float(line_split[41]),float(line_split[42]),float(line_split[43]),float(line_split[44]),float(line_split[45]),float(line_split[46]),float(line_split[47]),float(line_split[48]),
float(line_split[49]),float(line_split[50]),float(line_split[51]),float(line_split[52]),float(line_split[53]),float(line_split[54]),float(line_split[55]),float(line_split[56]),float(line_split[57]),float(line_split[58]),float(line_split[59]),float(line_split[60]),float(line_split[61]),float(line_split[62]),float(line_split[63]),float(line_split[64]),
float(line_split[65]),float(line_split[66]),float(line_split[67]),float(line_split[68]),float(line_split[69]),float(line_split[70]),float(line_split[71]),float(line_split[72]),float(line_split[73]),float(line_split[74]),float(line_split[75]),float(line_split[76]),float(line_split[77]),float(line_split[78]),float(line_split[79]),float(line_split[80]),
float(line_split[81]),float(line_split[82]),float(line_split[83]),float(line_split[84]),float(line_split[85]),float(line_split[86]),float(line_split[87]),float(line_split[88]),float(line_split[89]),float(line_split[90]),float(line_split[91]),float(line_split[92]),float(line_split[93]),float(line_split[94]),float(line_split[95]),float(line_split[96]),
float(line_split[97]),float(line_split[98]),float(line_split[99]),float(line_split[100]),float(line_split[101]),float(line_split[102]),float(line_split[103]),float(line_split[104]),float(line_split[105]),float(line_split[106]),float(line_split[107]),float(line_split[108]),float(line_split[109]),float(line_split[110]),float(line_split[111]),float(line_split[112]),
float(line_split[113]),float(line_split[114]),float(line_split[115]),float(line_split[116]),float(line_split[117]),float(line_split[118]),float(line_split[119]),float(line_split[120]),float(line_split[121]),float(line_split[122]),float(line_split[123]),float(line_split[124]),float(line_split[125]),float(line_split[126]),float(line_split[127]),float(line_split[128]),
float(line_split[129]),float(line_split[130]),float(line_split[131]),float(line_split[132]),float(line_split[133]),float(line_split[134]),float(line_split[135]),float(line_split[136]),float(line_split[137]),float(line_split[138]),float(line_split[139]),float(line_split[140]),float(line_split[141]),float(line_split[142]),float(line_split[143]),float(line_split[144]),
float(line_split[145]),float(line_split[146]),float(line_split[147]),float(line_split[148]),float(line_split[149]),float(line_split[150]),float(line_split[151]),float(line_split[152]),float(line_split[153]),float(line_split[154]),float(line_split[155]),float(line_split[156]),float(line_split[157]),float(line_split[158]),float(line_split[159]),float(line_split[160]),
float(line_split[161]),float(line_split[162]),float(line_split[163]),float(line_split[164]),float(line_split[165]),float(line_split[166]),float(line_split[167]),float(line_split[168]),float(line_split[169]),float(line_split[170]),float(line_split[171]),float(line_split[172]),float(line_split[173]),float(line_split[174]),float(line_split[175]),float(line_split[176]),
float(line_split[177]),float(line_split[178]),float(line_split[179]),float(line_split[180]),float(line_split[181]),float(line_split[182]),float(line_split[183]),float(line_split[184]),float(line_split[185]),float(line_split[186]),float(line_split[187]),float(line_split[188]),float(line_split[189]),float(line_split[190]),float(line_split[191]),float(line_split[192]),
float(line_split[193]),float(line_split[194]),float(line_split[195]),float(line_split[196]),float(line_split[197]),float(line_split[198]),float(line_split[199]),float(line_split[200]),float(line_split[201]),float(line_split[202]),float(line_split[203]),float(line_split[204]),float(line_split[205]),float(line_split[206]),float(line_split[207]),float(line_split[208]),
float(line_split[209]),float(line_split[210]),float(line_split[211]),float(line_split[212]),float(line_split[213]),float(line_split[214]),float(line_split[215]),float(line_split[216]),float(line_split[217]),float(line_split[218]),float(line_split[219]),float(line_split[220]),float(line_split[221]),float(line_split[222]),float(line_split[223]),float(line_split[224]),
float(line_split[225]),float(line_split[226]),float(line_split[227]),float(line_split[228]),float(line_split[229]),float(line_split[230]),float(line_split[231]),float(line_split[232]),float(line_split[233]),float(line_split[234]),float(line_split[235]),float(line_split[236]),float(line_split[237]),float(line_split[238]),float(line_split[239]),float(line_split[240]),
float(line_split[241]),float(line_split[242]),float(line_split[243]),float(line_split[244]),float(line_split[245]),float(line_split[246]),float(line_split[247]),float(line_split[248]),float(line_split[249]),float(line_split[250]),float(line_split[251]),float(line_split[252]),float(line_split[253]),float(line_split[254]),float(line_split[255]),float(line_split[256]),))
#导入模型
model=joblib.load('Q3_train.pkl')
#计算准确率
score=model.score(feature,label)
#显示准确率
print(score)
训练数据的结果输出如下:
根据先前程序二的准确率数据,再结合程序三的准确率数据
我导出了第二个模型作为最优训练模型,并对测试数据进行检测
测试数据的结果输出如下:
程序三结论:
此模型对测试数据集的检测准确率高达98.58%,in-sample error仅为1.923076923e-3 ,test set error仅为1.41509434e-2
所以此训练模优异型表现十分,对‘1’和‘5’分辨效果非常的好
程序四
基于先前的数据,我打算利用两个error来绘制一幅错误率迭代曲线
输入:<zip.train> / <zip.test>
输出:错误率迭代图
这个程序的文件读取、模型建立都是与先前程序一致的
添加的步骤是对错误率提取的过程以及画图过程
#隐藏层参数
units=(6,2)
#索取150次迭代的数据变化
for i in range(1,150):
model=MLPClassifier(solver='sgd',max_iter=i,alpha=1e-5,hidden_layer_sizes=units,random_state=1)
model.fit(feature,label)
#score是属于训练集的
score=model.score(feature,label)
#改成log域
s_log=math.log(1-score,10)
#置入数据
s.append(s_log)
#score2是属于测试集的
score2=model.score(feature2,label2)
s_log2=math.log(1-score2,10)
s2.append(s_log2) #put score values into s2
#绘图
p0=plt.plot(s,color='b',label='Ein') #Ein为in-sample
p1=plt.plot(s2,color='r',label='Eval') #Eval为test
plt.xlabel('itetation,t')
plt.ylabel('log10(error)')
plt.legend()
plt.show()
输出结果如下:
程序四结论:
可以看到从大约第30次迭代开始,错误率就在急速下降,并且两个数据集在100次迭代过后逐渐达到饱和
程序五
经过此前这么多想法的验证,这个ANN模型的表现还是非常优秀的
接下来就是用同样的方法,检测‘0’到‘9’所有的数据,看看其整体分辨的效果如何
f=open(r"zip.train","r")
lines=f.readlines()
feature=[]
label=[]
m=[]
s=[]
for line in lines:
line_split=line.split(' ')
label.append(float(line_split[0]))
feature.append((float(line_split[1]),float(line_split[2]),float(line_split[3]),float(line_split[4]),float(line_split[5]),float(line_split[6]),float(line_split[7]),float(line_split[8]),float(line_split[9]),float(line_split[10]),float(line_split[11]),float(line_split[12]),float(line_split[13]),float(line_split[14]),float(line_split[15]),float(line_split[16]),
float(line_split[17]),float(line_split[18]),float(line_split[19]),float(line_split[20]),float(line_split[21]),float(line_split[22]),float(line_split[23]),float(line_split[24]),float(line_split[25]),float(line_split[26]),float(line_split[27]),float(line_split[28]),float(line_split[29]),float(line_split[30]),float(line_split[31]),float(line_split[32]),
float(line_split[33]),float(line_split[34]),float(line_split[35]),float(line_split[36]),float(line_split[37]),float(line_split[38]),float(line_split[39]),float(line_split[40]),float(line_split[41]),float(line_split[42]),float(line_split[43]),float(line_split[44]),float(line_split[45]),float(line_split[46]),float(line_split[47]),float(line_split[48]),
float(line_split[49]),float(line_split[50]),float(line_split[51]),float(line_split[52]),float(line_split[53]),float(line_split[54]),float(line_split[55]),float(line_split[56]),float(line_split[57]),float(line_split[58]),float(line_split[59]),float(line_split[60]),float(line_split[61]),float(line_split[62]),float(line_split[63]),float(line_split[64]),
float(line_split[65]),float(line_split[66]),float(line_split[67]),float(line_split[68]),float(line_split[69]),float(line_split[70]),float(line_split[71]),float(line_split[72]),float(line_split[73]),float(line_split[74]),float(line_split[75]),float(line_split[76]),float(line_split[77]),float(line_split[78]),float(line_split[79]),float(line_split[80]),
float(line_split[81]),float(line_split[82]),float(line_split[83]),float(line_split[84]),float(line_split[85]),float(line_split[86]),float(line_split[87]),float(line_split[88]),float(line_split[89]),float(line_split[90]),float(line_split[91]),float(line_split[92]),float(line_split[93]),float(line_split[94]),float(line_split[95]),float(line_split[96]),
float(line_split[97]),float(line_split[98]),float(line_split[99]),float(line_split[100]),float(line_split[101]),float(line_split[102]),float(line_split[103]),float(line_split[104]),float(line_split[105]),float(line_split[106]),float(line_split[107]),float(line_split[108]),float(line_split[109]),float(line_split[110]),float(line_split[111]),float(line_split[112]),
float(line_split[113]),float(line_split[114]),float(line_split[115]),float(line_split[116]),float(line_split[117]),float(line_split[118]),float(line_split[119]),float(line_split[120]),float(line_split[121]),float(line_split[122]),float(line_split[123]),float(line_split[124]),float(line_split[125]),float(line_split[126]),float(line_split[127]),float(line_split[128]),
float(line_split[129]),float(line_split[130]),float(line_split[131]),float(line_split[132]),float(line_split[133]),float(line_split[134]),float(line_split[135]),float(line_split[136]),float(line_split[137]),float(line_split[138]),float(line_split[139]),float(line_split[140]),float(line_split[141]),float(line_split[142]),float(line_split[143]),float(line_split[144]),
float(line_split[145]),float(line_split[146]),float(line_split[147]),float(line_split[148]),float(line_split[149]),float(line_split[150]),float(line_split[151]),float(line_split[152]),float(line_split[153]),float(line_split[154]),float(line_split[155]),float(line_split[156]),float(line_split[157]),float(line_split[158]),float(line_split[159]),float(line_split[160]),
float(line_split[161]),float(line_split[162]),float(line_split[163]),float(line_split[164]),float(line_split[165]),float(line_split[166]),float(line_split[167]),float(line_split[168]),float(line_split[169]),float(line_split[170]),float(line_split[171]),float(line_split[172]),float(line_split[173]),float(line_split[174]),float(line_split[175]),float(line_split[176]),
float(line_split[177]),float(line_split[178]),float(line_split[179]),float(line_split[180]),float(line_split[181]),float(line_split[182]),float(line_split[183]),float(line_split[184]),float(line_split[185]),float(line_split[186]),float(line_split[187]),float(line_split[188]),float(line_split[189]),float(line_split[190]),float(line_split[191]),float(line_split[192]),
float(line_split[193]),float(line_split[194]),float(line_split[195]),float(line_split[196]),float(line_split[197]),float(line_split[198]),float(line_split[199]),float(line_split[200]),float(line_split[201]),float(line_split[202]),float(line_split[203]),float(line_split[204]),float(line_split[205]),float(line_split[206]),float(line_split[207]),float(line_split[208]),
float(line_split[209]),float(line_split[210]),float(line_split[211]),float(line_split[212]),float(line_split[213]),float(line_split[214]),float(line_split[215]),float(line_split[216]),float(line_split[217]),float(line_split[218]),float(line_split[219]),float(line_split[220]),float(line_split[221]),float(line_split[222]),float(line_split[223]),float(line_split[224]),
float(line_split[225]),float(line_split[226]),float(line_split[227]),float(line_split[228]),float(line_split[229]),float(line_split[230]),float(line_split[231]),float(line_split[232]),float(line_split[233]),float(line_split[234]),float(line_split[235]),float(line_split[236]),float(line_split[237]),float(line_split[238]),float(line_split[239]),float(line_split[240]),
float(line_split[241]),float(line_split[242]),float(line_split[243]),float(line_split[244]),float(line_split[245]),float(line_split[246]),float(line_split[247]),float(line_split[248]),float(line_split[249]),float(line_split[250]),float(line_split[251]),float(line_split[252]),float(line_split[253]),float(line_split[254]),float(line_split[255]),float(line_split[256]),))
#这个隐藏层的参数可以根据效果去调整
units=(50,20,10)
#多折验证
kf=KFold(n_splits=3)
for train,test in kf.split(feature):
model=MLPClassifier(solver='sgd',alpha=1e-5,hidden_layer_sizes=units,random_state=1)
model.fit(np.array(feature)[train],np.array(label)[train])
score=model.score(np.array(feature)[test],np.array(label)[test])
s.append(score)
m.append(model)
#我计算了一下准确率的方差
variance=np.var(s)
print(variance)
#导出最优模型
joblib.dump(m[0],'Q4_train.pkl')
输出的结果如下:
在一开始的训练中,准确率其实没有这么高,在我采用隐藏层为两层的时候,准确率大概只有60%~70%
后来经过更深层数的模型计算,在训练的三个模型当中,第一个模型准确率一直处于最高分数,准确率高达95%,方差仅为1.47e-5
此时的神经网络结构为 [256, 50, 20, 10, 1]
因此,我用这个最优训练模型去对测试集进行检测,最终结果如下:
这个模型整体的准确率接近92%,可以辨识绝大部分的手写体数据
如果对神经网络的隐藏层数再调整,或许会有更高的准确率,但三个隐藏层基本已适用于大多数的分类问题
写在最后
别忘了给Python安装sklearn库哦~