上一篇对MNIST数据集有了一些了解,数据集包含着60000张训练图片与标签值和10000张测试图片与标签值的数据集,数据集有了,现在我们来构造神经网络,预测下对这测试的10000张图片的正确识别率,也就是看下手写数字的识别率的情况。
def getTestData():
"""
获取测试数据
"""
(x_train,t_train),(x_test,t_test)=load_mnist(normalize=True,flatten=True,one_hot_label=False)
return x_test,t_test
getTestData()[0].shape
(10000, 784)
getTestData()[1].shape
(10000,)
获取测试的数据,通过形状可以看到有10000张784(28x28像素)的图片的矩阵和10000张标签值的一维数组!
在构造神经网络过程中,不可或缺的就是权重和偏置,我们读取已预设好的权重和偏置文文件(sample_weight.pkl),在后期的学习中将如何选定参数。
import sys,os,numpy as np
sys.path.append('D:\Anaconda3\TONYTEST')
os.chdir('D:\Anaconda3\TONYTEST\dataset')
from dataset.mnist import load_mnist
import pickle
def getweights():
"""
获取权重和偏置数据
"""
with open('sample_weight.pkl','rb') as f:
wbs=pickle.load(f)
return wbs
sample_weight.pkl是一个权重和偏置的参数的pkl文件,内容是字典类型保存,分别查看下权重和偏置的形状,我们看到形状对应维度的数量一致,知道可以做点积运算
wb=getweights()
wb['W1'].shape,wb['W2'].shape,wb['W3'].shape
((784, 50), (50, 100), (100, 10))
wb['b1'].shape,wb['b2'].shape,wb['b3'].shape
((50,), (100,), (10,))
def predict(wbs,x):
"""
以NumPy数组的形式输出各个标签对应的概率
"""
W1,W2,W3=wbs['W1'],wbs['W2'],wbs['W3']
b1,b2,b3=wbs['b1'],wbs['b2'],wbs['b3']
a1=np.dot(x,W1)+b1
z1=sigmoid(a1)
a2=np.dot(z1,W2)+b2
z2=sigmoid(a2)
a3=np.dot(z2,W3)+b3
y=softmax(a3)
return y
现在来看下使用测试数据来查看识别精度,测试识别精度,都使用测试数据,不能使用训练数据
x,t=getTestData()
wb=getweights()
accuracy_cnt=0
for i in range(len(x)):
y=predict(wb,x[i])
p=np.argmax(y) #获取概率最高的元素的索引值
#概率最高的索引值如果和测试的标签值相等就加1
if p==t[i]:
accuracy_cnt+=1
print('识别精确率:{:.2%}'.format(accuracy_cnt/len(x)))
识别精确率:93.52%
也就是说10000张测试图片,正确识别了9352张
上面用到的一些公用函数,可以统一写在一个common目录里面的funtions.py
import numpy as np
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def softmax(x):
if x.ndim == 2:
x = x.T#矩阵转置
x = x - np.max(x, axis=0)
y = np.exp(x) / np.sum(np.exp(x), axis=0)
return y.T
x = x - np.max(x) # 溢出对策
return np.exp(x) / np.sum(np.exp(x))
使用方法跟上一篇文章中的使用dataset一样
from common.functions import sigmoid,softmax
上面的识别精确率,是一张一张处理,现在改进一下做批处理,也就是一次性输入比如100张图片,那10000张图片就100批次搞定,批处理可以大大缩短处理时间。
x,t=getTestData()
wb=getweights()
batch_size=100#每次批处理的数量
accuracy_cnt=0
for i in range(0,len(x),batch_size):
x_batch=x[i:i+batch_size]
y_batch=predict(wb,x_batch)
p=np.argmax(y_batch,axis=1)
accuracy_cnt+=np.sum(p==t[i:i+batch_size])
print("精确率:{:0.2%}".format(accuracy_cnt/len(x)))
精确率:93.52%
其中axis=1表示沿着第一维方向(第一维为轴),或者我是这么理解它,axis=0代表列,axis=1代表行,如下
q=np.array([[1,2,3],[22,39,1],[10,9,12],[0.9,0.1,8]])
'''
array([[ 1. , 2. , 3. ],
[ 22. , 39. , 1. ],
[ 10. , 9. , 12. ],
[ 0.9, 0.1, 8. ]])
'''
a0=np.argmax(q,axis=0)
array([1, 1, 2], dtype=int64)
a1=np.argmax(q,axis=1)
array([2, 1, 2, 2], dtype=int64)
一般来说都是axis=1,因为q.shape是(4,3),4行3列,那么我们取最大值的索引值,也是每行取一个最大值,回到前面的(10000,784)也是这样,10000张图片,每张图片是784列,那么我们肯定也是取10000张标签值,所以每行取一个!
np.max(q,axis=1)
array([ 3., 39., 12., 8.])