深度学习入门--手写数字识别-推理处理
2019-03-25 本文已影响0人
爱吃西瓜的番茄酱
求解机器学习问题的步骤如下:
- 学习
- 推理
类似的,使用神经网络解决问题时,也需要使用训练数据进行权重参数的学习;进行推理时,使用刚才学习到的参数,对输入数据进行分类。
这里假设学习已经全部结束,我们使用学习到的参数,先实现神经网络的“推理处理”。这个推理处理也称为神经网络的前向传播。
这里使用的数据集是MNIST手写数字图像集,MNIST数据集是机器学习领域有名的数据集之一。MNIST数据集是由0到9的数字图像构成的,训练图像有6万张,测试图像有1万张。
MNIST的图像数据是28像素*28像素的灰度图像,各个像素的取值在0-255之间,每个图像数据都相应地标有“9”,“2”, “4”等标签。
导入MNIST数据集
import sys, os
sys.path.append(os.pardir) # 为了导入父目录中的文件而进行的设定
from dataset.mnist import load_mnist
# 第一次调用会花些时间
(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False)
# 输出各个数据的形状
print(x_train.shape)
print(t_train.shape)
print(x_test.shape)
print(t_test.shape)
输出为:
(60000, 784)
(60000,)
(10000, 784)
(10000,)
load_mnist函数
以“(训练图像,训练标签), (测试图像,测试标签)”的形式返回读入的MNIST数据。
load_mnist函数
有三个参数:
-
normalize
设置为False,则输入图像的像素会保持原来的0-255;设置为True,则将输入图像正规化为0.0-1.0的值 -
flatten
设置为False,则输入图像为12828的三维数组; 设置为True,则将输入图像保存为由784个元素构成的一维数组 -
one_hot_label
设置为False时,只是像7,2这样简单的保存正确解标签;设置为True时,标签则保存为one_hot形式:仅正确解标签为1,其余皆为0
显示MNIST图像
import sys, os
sys.path.append(os.pardir)
import numpy as np
from dataset.mnist import load_mnist
from PIL import Image
def img_show(img):
pil_img=Image.fromarray(np.uint8(img))
pil_img.show()
(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False)
img=x_train[0]
label=t_train[0]
print(label)
print(img.shape)
img=img.reshape(28,28) # 把图像变回原来的尺寸
print(img.shape)
img_show(img)
由于flatten=True
时读入的图像是以一维numpy数组的形式保存的。因此,显示图像时,需要把它变为原来的28像素*28像素的形状,可以通过reshape()
方法的参数指定期望的形状。
输出为:
5
(784,)
(28, 28)
显示图像为:
神经网络的推理处理
假设已经学习到的参数保存在sample_weight.pkl
中。
import sys, os
sys.path.append(os.pardir)
import numpy as np
import pickle # 利用pickle快速加载已经下载过的MNIST数据集
from dataset.mnist import load_mnist
from common.functions import sigmoid, softmax # 激活函数
def get_data():
(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=True, one_hot_label=False)
return x_test, t_test
def init_network():
with open("sample_weight.pkl", "rb") as f: # 读取学习到的权重、偏置参数
network=pickle.load(f)
return network
def predict(network, x):
w1, w2, w3=network['W1'], network['W2'], network['W3']
b1, b2, b3=network['b1'], network['b2'], network['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=get_data()
network=init_network()
accuracy_cnt=0
for i in range(len(x)):
y=predict(network, x[i])
p=np.argmax(y) # 获取概率最高的元素的索引
if p==t[i]: # 当预测数据和测试标签一致时,即识别正确
accuracy_cnt += 1
print("识别精度为:" + str(float(accuracy_cnt)/len(x)))
输出为:
识别精度为:0.9352
这表示有93.52%的数据被正确分类了。
每天学习一点点,每天进步一点点。
参考书籍:《深度学习入门:基于Python的理论和实现》