《深度学习--基于python的理论与实现》学习笔记6:第三章神经网络(2)

本章节主要介绍手写数字图像集MNIST,并且通过神经网络对其进行前向传播。

3.6 手写数字识别

通过神经网络能够对手写数字进行识别处理。

3.6.1 MNIST数据集介绍

为了训练一个手写数字识别模型,必须要用到数据集,这里用的是MNIST数据集,这个数据库主要包含了60000张的训练图像和10000张的测试图像。数据集由四个压缩包构成

图1: MNIST数据集的组成压缩包

3.6.2 MNIST数据集的调用

通过编写一个mnist.py文件,其中定义的函数load_mnist(),能够很方便地读入MNIST数据,其数据形式以:“(训练数据,训练标签),(测试图像,测试标签)”的形式返还读入的MNIST数据。运行mnist.py文件,能够自动下载MNIST数据集,并且完成数据的读入。

下面编写读入MNIST数据集的代码,其中要用到一个mnist.py的文件,这个文件和程序运行文件我会分享到我的博客上:。

#代码在文件:mnist.a.py中
import sys,os
#os模块是Python标准库中提供的与操作系统交互的模块,提供了访问操作系统底层的接口,里面有很多操作系统的函数
#其中os.path模块主要用于文件属性的获取
#sys模块负责程序与Python解释器的交互。

sys.path.append(os.pardir)   #为了导入父目录的文件而进行的设定,因为该文件和mnist文件不在一个文件夹中
from dataset.mnist import load_mnist  #调用dataset文件夹中的文件mnist中的load_mnist函数(下载mnist文件)


(x_train,t_train),(x_test,t_test)=load_mnist(flatten=True,normalize=False,one_hot_label=False)  
#load_mnist以(训练图片,训练标签),(测试图片,测试标签)的形式读入数据集
#normalize:是否将输入图片正规化为0.0-1.0的值,这里没有正规化,图片像素仍然为0-255
#flatten:是否展开输入图像(变为一维数组),这里是用一维数组显示的
#one_hot_label:仅正确标签为1,其他均为0的数组,形如[0,0,0,1,0,0],如果为False,则仅保存2,7等正确解的标签

#输出,确定训练集与测试集的数组形状
print('训练集图片形状',x_train.shape)   #训练集图片形状
print('训练集标签形状',t_train.shape)   #训练集标签形状
print('测试集图片形状',x_test.shape)    #测试集图片形状
print('测试集标签形状',t_test.shape)    #测试集标签形状

#mnist书写数据集中训练集有6万张图片,测试集中有一万张图片

输出:

训练集图片形状 (60000, 784)
训练集标签形状 (60000,)
测试集图片形状 (10000, 784)
测试集标签形状 (10000,)

3.6.3 对读入的数据集信息进行显示

#代码在文件:mnist_show.py中
import sys,os
sys.path.append(os.pardir)  #为了导入父目录的文件而进行的设定
from dataset.mnist import load_mnist   
import numpy as np
from PIL import Image    #图像的显示使用PIL(Python Image Library)模块


def img_show(img):     #定义数组转变函数
    pil_img=Image.fromarray(np.uint8(img))
    pil_img.show()     #转换后的图片显示
#根据下一步操作可知,图片已经转变为一维数组了,这里需要把图片重新变为28像素X28像素的形状;这里通过Image.fromarray()函数进行转变
    
    
(x_train,t_train),(x_test,t_test)=load_mnist(flatten=True, normalize=False) #读入load——mnist调取的图片


img=x_train[3]     #读取第三张图片的数组
lable=t_train[3]   #读取第三张标签的数组
print(lable)       #输出第三张标签的数组

print(img.shape)          #一开始的图片数组形状
img=img.reshape(28,28)    #把数组变为指定的形状
print(img.shape)          #变换后的图片数组形状

img_show(img)     #调用图片转化函数,进行图片的显示

输出:
文本:

1
(784,)
(28, 28)

图片:

图2:输出图片

3.6.4神经网络的前向学习

对手写数字图像集,通过神经网络进行前向学习,即给定了训练好的参数(参数信息在文件sample_weight.pkl中),通过输出对每个输入的图像进行预测,判断属于哪一个数字(在下一个章节会对参数的跟新进行说明),并且得出该神经网络的准确性。

神经网络的结构说明:图片大小为28*28=784,即输入为784个神经元,输出层为10个神经元(对应数字0-9),其中有两层隐藏层(度余个隐藏层有50个神经元,第二个神经元由100个神经元)。

#代码在文件:neuarl_network.py中
import sys, os
sys.path.append(os.pardir)  # 为了导入父目录的文件而进行的设定
import numpy as np
import pickle    #调用pickle库
from dataset.mnist import load_mnist  

#1.sigmoid函数
def  sigmoid(x):
    return 1/(1+np.exp(-x))

#2.softmax激活函数    (感叹一下,数组计算就是快)
def softmax(a):
    exp_a=np.exp(a)
    sum_exp_a=np.sum(exp_a)
    y= exp_a/ sum_exp_a
    return y


'''
测试数据的获取:这里函数中的normalize是正规化的意思,正规化能够提高训练结果的准确率
'''
def get_test_data(): 
    (x_train,t_train),(x_test,t_test)=\
    load_mnist(flatten=True,normalize=True,one_hot_label=False)   #读取数据集的信息 (进行正则化,精度高)
    #load_mnist(flatten=True,normalize=False,one_hot_label=False)   #读取数据集的信息  (不进行正则化,精度稍低)
    return x_test,t_test
 
#神经元初始参数的设定(后面用反向传播学习到的参数)
def init_network():
    with open("sample_weight.pkl",'rb')  as f:
        network=pickle.load(f)    #获取文件sample_weight.pkl中的权重信息
    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_test_data()     #从函数get_test_data() 中获取测试数据
network=init_network()  #权重的选定

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(network,x_batch)
    p=np.argmax(y_batch,axis=1)  #获取概率最高的元素的索引
    accuracy_cnt +=np.sum(p==t[i:i+batch_size])
        
print("Accuracy:"+str(float(accuracy_cnt)/len(x)))

结果:

数据进行预处理:Accuracy:0.9352

更改其中的代码:注销第一句代码,运行第二句代码,其他不变:

图2:代码更改

结果:

数据进行预处理:Accuracy:0.92087

由上述可知:如果对数据进行预处理,即正则化,是能够提高模型识别的准确度的。

本小节的代码内容我已经打包好了,需要的可以留言。
手写数字识别代码

参考书籍:
1.《深度学习–基于python的理论与实现》

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值