深度学习⼊门案例:⼿写数字识别
MNIST⼿写数字数据库的训练集为60,000个⽰例,⽽测试集为10,000个⽰例。
⼀共4个⽂件,训练集、训练集标签、测试集、测试集标签
MNIST的图像数据是28像素 × 28像素的灰度图像(1通道),各个像素
的取值在0到255之间。每个图像数据都相应地标有“7” “2” “1”等标签。
⽬录
1、读⼊MNIST数据。
从下载MNIST数据集到将这些数据转换成NumPy数组
# coding: utf-8
try:
quest
except ImportError:
raise ImportError('You should use Python 3.x')
import os.path
import gzip
import pickle
import os
import numpy as np
# 下载数据
url_base ='yann.lecun/exdb/mnist/'
key_file ={
'train_img':'',
'train_label':'',
'test_img':'',
'test_label':''
}
# 设置数据保存路径
dataset_dir = os.path.dirname(os.path.abspath(__file__))#
save_file = dataset_dir +"/mnist.pkl"
train_num =60000
test_num =10000
img_dim =(1,28,28)
img_size =784
def_download(file_name):
file_path = dataset_dir +"/"+ file_name
if ists(file_path):
return
print("Downloading "+ file_name +" ... ")
print("Done")
def download_mnist():
def download_mnist():
for v in key_file.values():
_download(v)
def_load_label(file_name):
file_path = dataset_dir +"/"+ file_name
print("Converting "+ file_name +" to NumPy Array ...")
with gzip.open(file_path,'rb')as f:
labels = np.ad(), np.uint8, offset=8)
print("Done")
return labels
def_load_img(file_name):
file_path = dataset_dir +"/"+ file_name
print("Converting "+ file_name +" to NumPy Array ...")
with gzip.open(file_path,'rb')as f:
data = np.ad(), np.uint8, offset=16)
data = shape(-1, img_size)
print("Done")
return data
def_convert_numpy():
dataset ={}
dataset['train_img']=  _load_img(key_file['train_img'])
dataset['train_label']= _load_label(key_file['train_label'])
dataset['test_img']= _load_img(key_file['test_img'])
dataset['test_label']= _load_label(key_file['test_label'])
return dataset
def init_mnist():
download_mnist()
dataset = _convert_numpy()
print("Creating pickle file ...")
with open(save_file,'wb')as f:
pickle.dump(dataset, f,-1)
print("Done!")
def_change_one_hot_label(X):
T = np.zeros((X.size,10))
for idx, row in enumerate(T):
row[X[idx]]=1
return T
def load_mnist(normalize=True, flatten=True, one_hot_label=False): """读⼊MNIST数据集
Parameters
----------
normalize : 将图像的像素值正规化为0.0~1.0
one_hot_label :
one_hot_label为True的情况下,标签作为one-hot数组返回
one-hot数组是指[0,0,1,0,0,0,0,0,0,0]这样的数组
flatten : 是否将图像展开为⼀维数组
Returns
-------
(训练图像, 训练标签), (测试图像, 测试标签)
"""
if not ists(save_file):
init_mnist()
with open(save_file,'rb')as f:
dataset = pickle.load(f)
if normalize:
for key in('train_img','test_img'):
dataset[key]= dataset[key].astype(np.float32)
dataset[key]/=255.0
if one_hot_label:
dataset['train_label']= _change_one_hot_label(dataset['train_label'])
dataset['test_label']= _change_one_hot_label(dataset['test_label'])
if not flatten:
for key in('train_img','test_img'):
dataset[key]= dataset[key].reshape(-1,1,28,28)
return(dataset['train_img'], dataset['train_label']),(dataset['test_img'], dataset['test_label'])
if __name__ =='__main__':
init_mnist()
Python有pickle这个便利的功能。这个功能可以将程序运⾏中的对象保存为⽂件。
如果加载保存过的pickle⽂件,可以⽴刻复原之前程序运⾏中的对象。
2、进⾏训练显⽰图像
# coding: utf-8
import sys, os
sys.path.append(os.pardir)# 为了导⼊⽗⽬录的⽂件⽽进⾏的设定,从dataset中导⼊数据
import numpy as np
ist import load_mnist
from PIL import Image
def img_show(img):
pil_img = Image.fromarray(np.uint8(img))# 把保存为Numpy数组的图像数据转换为PIL⽤的数据对象
pil_img.show()
# load_mnist的三个参数的意思
# 第 1 个参数normalize :设置是否将输⼊图像正规化为0.0~1.0的值。如果将该参数设置为 False ,则输⼊图像的像素会保持原来的0~255。# 第2个参数 flatten 设置是否展开输⼊图像(变成⼀维数组):
# 如果将该参数设置为 False ,则输⼊图像为1 × 28 × 28的三维数组;若设置为 True ,则输⼊图像会保存为由784个元素构成的⼀维数组。数据库学习入门书籍
# 第3个参数 one_hot_label 设置是否将标签保存为one-hot表⽰(one-hot representation)。
# one-hot表⽰是仅正确解标签为1,其余皆为0的数组,就像 [0,0,1,0,0,0,0,0,0,0] 这样。
# 当 one_hot_label 为 False 时,只是像 7,2 这样简单保存正确解标签;
# 当 one_hot_label 为 True 时,标签则保存为one-hot表⽰。
(x_train, t_train),(x_test, t_test)= load_mnist(flatten=True, normalize=False)
img = x_train[0]
label = t_train[0]
print(label)# 5
print(img.shape)# (784,)
img = shape(28,28)# 把图像的形状变为原来的尺⼨
print(img.shape)# (28, 28)
img_show(img)
3、神经⽹络的推理处理
神经⽹络的输⼊层有784个神经元,输出层有10个神经元。
输⼊层的784这个数字来源于图像⼤⼩的28 × 28 = 784,输出层的10这个数字来源于10类别分类(数字0到9,共10类别)。
此外,这个神经⽹络有2个隐藏层,第1个隐藏层有50个神经元,第2个隐藏层有100个神经元。这个50和100可以设置为任何值。
# coding: utf-8
import sys, os
sys.path.append(os.pardir)# 为了导⼊⽗⽬录的⽂件⽽进⾏的设定
import numpy as np
import pickle
ist import load_mnist
from common.functions import sigmoid, softmax
# 获取数据:
def get_data():
(x_train, t_train),(x_test, t_test)= load_mnist(normalize=True, flatten=True, one_hot_label=False)
return x_test, t_test
# 初始化⽹络
# init_network()读⼊保存在pickle⽂件sample_weight.pkl中的学习到的权重参数。这个⽂件中以字典变量的形式保存了权重和偏置参数
def init_network():
with open("sample_weight.pkl",'rb')as f:
network = pickle.load(f)
return network
# 预测⽹络的权重和b
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()# ⾸先获得MNIST数据集,⽣成⽹络
network = init_network()
accuracy_cnt =0
# ⽤ for 语句逐⼀取出保存在 x 中的图像数据,⽤ predict() 函数进⾏分类。
# predict() 函数以NumPy数组的形式输出各个标签对应的概率。
# ⽐如输出 [0.1, 0.3, 0.2, ... , 0.04] 的数组,该数组表⽰“0”的概率为0.1,“1”的概率为0.3,
for i in range(len(x)):
y = predict(network, x[i])
p= np.argmax(y)# 获取概率最⾼的元素的索引,作为预测结果
if p == t[i]:
accuracy_cnt +=1
print("Accuracy:"+str(float(accuracy_cnt)/len(x)))# ⽐较神经⽹络所预测的答案和正确解标签,将回答正确的概率作为识别精度
# 会显⽰“Accuracy:0.9352”。这表⽰有93.52 %的数据被正确分类了
我们把 load_mnist 函数的参数 normalize 设置成了True 。将 normalize 设置成 True 后,函数内部会进⾏转换,将图像的各个像素值除以255,使得数据的值在0.0~1.0的范围内。
像这样把数据限定到某个范围内的处理称为正规化(normalization)。此外,对神经⽹络的输⼊数据进⾏某种既定的转换称为预处理(pre-processing)。这⾥,作为对输⼊图像的⼀种预处理,我们进⾏了正规化。
4、批处理
我们来关注输⼊数据和权重参数的“形状”。再看⼀下刚才的代码实现。
通过上图的输⼊,进⾏下图的对⽐
现在我们来考虑打包输⼊多张图像的情形。⽐如,我们想⽤ predict()
函数⼀次性打包处理100张图像。可以把x的形状改为100 × 784,将
100张图像打包作为输⼊数据。⽤图表⽰的话,如图所⽰。
输⼊数据的形状为100 × 784,输出数据的形状为100 × 10。这表⽰输⼊的100张图像的结果被⼀次性输出了。⽐如, x[0] 和y[0] 中保存了第0张图像及其推理结果, x[1] 和 y[1] 中保存了第1张图像及其推理结果,等等。
这种打包式的输⼊数据称为批(batch)
代码:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。