第二章.神经网络
2.5 手写数字识别的实现
1.MNIST数据集:
1).MNIST简介:
- 这里使用的数据集是MNIST手写数字数据集,是由0~9的数组图像构成,训练图像有6万张,测试图像1万张,可用这些数据进行学习和推理。
- MNIST图像数据是28pixel*28pixel的灰度图像,像素取值在0~255之间。
2).导入方式
- 在导入
from dataset.mnist import load_mnist
时会提示“ModuleNotFoundError: No module named 'dataset”的错误,是因为dataset
不是python或者Anaconda库中自带的,而是 《深度学习入门》 这本书的官方资料中下载的:下载链接
①.进入这个网站后,我们会看到如下界面:
②.点击右边的随书下载
③.解压后的文件夹中可以看到一个“dataset”文件夹
④.将这个文件夹放到当前运行工程所在的./Lib/site-packages文件内
2.基础概念:
1).Pickle库文件
- Python中的pickle可以将程序运行中的对象保存成文件,加载之前保存的pickle文件,可以立刻复原之前程序运行中的对象
2).正则化
- 把数据限定在某个范围内的处理称为正则化。(例如:将图像像素归一化到0~1范围内)
3).预处理
- 对神经网络的输入数据进行某种既定的转换成为预处理
4).白化
- 将数据整体的分布形状均匀化的方法成为白化。
5).批处理
- 批:输入数据的集合成为批,通过一批为单位进行推理处理,能否实现高速的运算
- 批处理的优势:
①.可以缩短每张图像的处理时间。(原因:大多数处理数值计算的库都进行了能够高效处理大型数组计算的最优化)
②.在神经网络中,当数据传送成为瓶颈时,批处理可以减轻数据总线的负荷(严格的说:相对于数据读入,可以将更多的时间用在计算上)
2.代码
import pickle # 文件读写操作
import sys, os
sys.path.append(os.pardir) # 为了导入父目录中的文件而进行设定
from dataset.mnist import load_mnist # 本书中的数据集,不是官方数据集
import numpy as np
from PIL import Image
# 显示图像:将Numpy数组的类型转化为PIL可以使用的数据类型
def img_show(img):
pil_img = Image.fromarray(np.uint(img))
pil_img.show()
# 获取训练集
def get_train_data():
(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False)
return x_train, t_train
# 获取测试集
def get_test_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
# 激活函数:sigmoid
def sigmoid(x):
return 1 / (1 + np.exp(-x))
# 输出层函数:softmax
def softmax(x):
arraymax = np.max(x)
return np.exp(x - arraymax) / np.sum(np.exp(x - arraymax))
# 正向传播:3层神经元,激活函数:sigmoid函数,输出层函数softmax函数
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
# 识别精度:批处理的方式
def Accuracy(network, x, t, bitch_size):
accuracy_num = 0
for i in range(0, len(x), bitch_size):
x_bitch = x[i:i + bitch_size]
y_bitch = predict(network, x_bitch)
p = np.argmax(y_bitch, axis=1)
accuracy_num += np.sum(p == t[i:i + bitch_size])
return accuracy_num / len(x)
# 加载训练集:
x_train, t_train = get_train_data()
# 显示训练集数据
img = x_train[0]
label = t_train[0]
print('label:', label)
img = img.reshape(28, 28)
img_show(img)
# 加载测试集数据:
x_test, t_test = get_test_data()
# 加载权重和偏置值
network = init_network()
# 批处理的图像数
bitch_size = 100
# 识别精度
accuracy = Accuracy(network, x_test, t_test, bitch_size)
print('accuracy:', accuracy)