0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

手写数字识别神经网络的实现(2)

CHANBAEK 来源:小小研究生 作者:小小研究生 2023-06-23 16:57 次阅读

在练习二中,手写数字识别使用数值微分的方式实现了神经网络,现在用误差反向传播法来实现。两者的区别仅仅是使用不同方法求梯度。

1、2层神经网络的类

将2层神经网络实现为一个TwoLayerNet的类(和上次的代码仅仅是求梯度的方式不同,不同的地方加*表示):

class TwoLayerNet:
    def __init__(self, input_size, hidden_size, output_size, weight_init_std=0.01):
        # 初始化权重
        self.params = {}
        self.params['W1'] = weight_init_std *np.random.randn(input_size, hidden_size)
        self.params['b1'] = np.zeros(hidden_size)
        self.params['W2'] = weight_init_std *np.random.randn(hidden_size, output_size)
        self.params['b2'] = np.zeros(output_size)
*       #生成层        
*       self.layers = OrderedDict()
*       self.layers['Affine1'] = Affine(self.params['W1'], self.params['b1'])
*       self.layers['Relu1'] = Relu()
*       self.layers['Affine2'] = Affine(self.params['W2'], self.params['b2'])
*       self.lastLayer = SoftmaxWithLoss()
*   def predict(self, x):
        for layer in self.layers.values():
           x = layer.forward(x)
        return x
    # x:输入数据, t:监督数据
    def loss(self, x, t):
        y = self.predict(x)
*       return self.lastLayer.forward(y, t)
    def accuracy(self, x, t):
        y = self.predict(x)
        y = np.argmax(y, axis=1)
*       if t.dim != 1 : t=np.argmax(t,axis=1)
        accuracy = np.sum(y == t) / float(x.shape[0])
        return accuracy
    # x:输入数据, t:监督数据
    def numerical_gradient(self, x, t):
        loss_W = lambda W: self.loss(x, t)
        grads = {}
        grads['W1'] = numerical_gradient(loss_W, self.params['W1'])
        grads['b1'] = numerical_gradient(loss_W, self.params['b1'])
        grads['W2'] = numerical_gradient(loss_W, self.params['W2'])
        grads['b2'] = numerical_gradient(loss_W, self.params['b2'])
        return grads
*    def gradient(self, x, t):
        # forward
        self.loss(x, t)
        # backward
        dout = 1
        dout = self.lastLayer.backward(dout)      
        layers = list(self.layers.values())
        layers.reverse()
        for layer in layers:
            dout = layer.backward(dout)
        # 设定
        grads = {}
        grads['W1'], grads['b1'] = self.layers['Affine1'].dW, self.layers['Affine1'].db
        grads['W2'], grads['b2'] = self.layers['Affine2'].dW, self.layers['Affine2'].db
        return grads

只介绍和数值微分求导法不同的部分:

初始化: layer是保存神经网络的层的有序字典型变量 。OrderedDict是有序字典, 有序是说它可以记住向字典中添加元素的顺序 ,正向传播只需要按照添加元素的顺序调用各层的forward方法就可以,反向传播顺序相反地顺序调用backward方法。通过layers['Affine1'],layers['Relu1'],layers['Affine2']的形式保存各个层。还定义了最后一层lastlayer,上一篇中介绍了Affine,Relu,SoftmaxWithLoss函数的封装,在这一层中直接定义。

定义predict函数,用于识别:predict()函数的参数是输入的图像数据,按照层的顺序(layers的for语句)依次调用每一层的forward()函数,先是x经过Affine1层的forward函数,返回的out值作为Relu层的forward函数的输入参数,返回的out作为Affine2层的forward函数的输入参数,返回的out作为最后一层SoftmaxWithLoss层的forward函数的输入参数,返回的out是最后的输出,也就是识别的结果。

定义损失函数:输入参数是x输入图像和t标签,经过predict函数得到识别数据y,返回值是输入为y和t的SoftmaxWithLoss()的前向函数。

定义识别精度:经过predict()之后的输出y是识别结果,如果与标签一致说明结果准确,识别精度就是准确的次数与输入图像数量之比,即准确的概率。批处理时假设一次处理N张,y的形状是(N,10),有两个方向,a[1]是按行方向索引,argmax是找到最大值所在的位置。按行找到到最大值的索引值,就对应每一张图片识别到最大可能性的结果对应的分类。将该分类与标签进行比较,求识别正确的概率。

定义了数值微分求导的过程,这个是数值微分的方法,如果用误差反向传播法需要将这段注释掉;或者后续要比较两个方法求导的结果。

定义了误差反向传播法求导的方法:先求dout=1通过lastlayer层的backward函数的输出,返回dx。由于反向传播经过的层和正向相反,正向的有序字典变量需要reverse反向,这样通过for语句调用每一层的backward函数经过的层顺序就是affine2,relu,affine1,此时的输出就是最后的求导结果。

将神经网络用层的方式实现,将每一层模块化,是非常方便的,即使层很多,也只需要接好每一层的接口。通过各个层内部的forward和backward函数就可以识别或者计算梯度。

2、数值微分的计算耗时,但是计算简单不易出错。误差反向传播法的实现相对复杂容易出错。所以比较两者的结果可以确认误差反向传播法是否正确。这个比较的操作成为梯度确认。梯度确认的代码:

(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)
network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)
x_batch = x_train[:3]
t_batch = t_train[:3]
grad_numerical = network.numerical_gradient(x_batch, t_batch)
grad_backprop = network.gradient(x_batch, t_batch)
for key in grad_numerical.keys():
    diff = np.average( np.abs(grad_backprop[key] - grad_numerical[key]) )
    print(key + ":" + str(diff))

通过numerical_gradient函数得到的数值微分求导结果保存在grad_numerical中,通过gradient函数得到的误差反向传播结求导结果保存在grad_backprop中。通过求对应位置的数值的绝对值的平均值,判断误差反向传播求导结果是否正确。

W1:3.705434371413955e-10

b1:2.37776902256894e-09

W2:5.412727643613116e-09

b2:1.396563151026542e-07

输出的误差很小,所以是正确的。

3、使用误差反向传播法的学习

和数值微分的方法一样,因为不同之处仅仅是求梯度。

因此在练习二中的代码,把数值微分求梯度的代码注释掉,用误差反向传播法求梯度的代码就可以了。

总结:通过买水果的例子介绍了误差反向传播法的原理,介绍了神经网络中的误差反向传播法,原理一样只是不用标量用矩阵。将relu,softmaxwithloss,affine,softmax层封装成模块,内部实现了forward和backward方法。只需要搭建神经网络的每一层,通过内部的forward和backward函数,将数据正向或反向传播就可以求导。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 神经网络
    +关注

    关注

    42

    文章

    4732

    浏览量

    100395
  • 数值
    +关注

    关注

    0

    文章

    80

    浏览量

    14340
  • 函数
    +关注

    关注

    3

    文章

    4276

    浏览量

    62303
  • 数字识别
    +关注

    关注

    2

    文章

    19

    浏览量

    10129
收藏 人收藏

    评论

    相关推荐

    基于BP神经网络的手势识别系统

      摘 要:本文给出了采用ADXL335加速度传感器来采集五个手指和手背的加速度三轴信息,并通过ZigBee无线网络传输来提取手势特征量,同时利用BP神经网络算法进行误差分析来实现手势识别
    发表于 11-13 16:04

    【PYNQ-Z2申请】基于PYNQ-Z2神经网络图形识别

    神经网络的学习,讲解其工作原理。4.基于PYNQ-Z2,用python实现一个神经网络。5.训练和测试神经网络,完成
    发表于 01-09 14:48

    【PYNQ-Z2试用体验】神经网络基础知识

    前言前面我们通过notebook,完成了在PYNQ-Z2开发板上编写并运行python程序。我们的最终目的是基于神经网络,完成手写数字识别
    发表于 03-03 22:10

    【PYNQ-Z2试用体验】基于PYNQ-Z2神经网络图形识别[结项]

    前言前面我们简单讲解了神经网络的基本概念和工作原理,接下来,将通过具体的python代码来完成基于神经网络的图形识别。这里使用手写数字图像
    发表于 03-18 21:51

    【案例分享】ART神经网络与SOM神经网络

    是一种常用的无监督学习策略,在使用改策略时,网络的输出神经元相互竞争,每一时刻只有一个竞争获胜的神经元激活。ART神经网络由比较层、识别层、
    发表于 07-21 04:30

    人工神经网络实现方法有哪些?

    人工神经网络(Artificial Neural Network,ANN)是一种类似生物神经网络的信息处理结构,它的提出是为了解决一些非线性,非平稳,复杂的实际问题。那有哪些办法能实现人工神经
    发表于 08-01 08:06

    matlab实现神经网络 精选资料分享

    神经神经网络,对于神经网络实现是如何一直没有具体实现一下:现看到一个简单的神经网络模型用于训
    发表于 08-18 07:25

    如何使用STM32F4+MPU9150实现神经网络识别手势?

    如何使用STM32F4+MPU9150实现神经网络识别手势?
    发表于 11-19 07:06

    人工神经网络手写数字识别系统的详细资料概述

    逼近未知非线性对象的特点,使其为手写数字识别提供了一种新的方法。本论文采用一编制了一套基于神经网络手写
    发表于 05-27 08:00 18次下载
    人工<b class='flag-5'>神经网络</b><b class='flag-5'>手写</b><b class='flag-5'>数字</b><b class='flag-5'>识别</b>系统的详细资料概述

    谷歌向神经网络手写数字识别发起挑战,竟用量子计算识别

    神经网络做 MNIST 手写数字识别是机器学习小白用来练手的入门项目,业内最佳准确率已经达到了 99.84%。但最近,谷歌向这个「古老」的数据集发起了一项新的挑战:用量子计算来进行
    的头像 发表于 08-17 17:17 1576次阅读
    谷歌向<b class='flag-5'>神经网络</b><b class='flag-5'>手写</b><b class='flag-5'>数字</b><b class='flag-5'>识别</b>发起挑战,竟用量子计算<b class='flag-5'>识别</b>

    神经网络入门:使用Python+Flux+Julia来实现手写数字识别

    使用 MNIST 数据集对 0 到 9 之间的数字进行手写数字识别神经网络的一个典型入门教程。 该技术在现实场景中是很有用的,比如可以把该
    的头像 发表于 11-03 22:02 672次阅读

    使用PyhonFluxJulia实现手写数字识别神经网络入门教程

    使用 MNIST 数据集对 0 到 9 之间的数字进行手写数字识别神经网络的一个典型入门教程。该技术在现实场景中是很有用的,比如可以把该技
    发表于 12-08 00:23 7次下载

    手写数字识别神经网络实现(1)

    对MNIST数据集使用2神经网络(1层隐藏层)实现
    的头像 发表于 06-23 16:57 520次阅读
    <b class='flag-5'>手写</b><b class='flag-5'>数字</b><b class='flag-5'>识别</b><b class='flag-5'>神经网络</b>的<b class='flag-5'>实现</b>(1)

    卷积神经网络如何识别图像

    多层卷积层、池化层和全连接层。CNN模型通过训练识别并学习高度复杂的图像模式,对于识别物体和进行图像分类等任务有着非常优越的表现。本文将会详细介绍卷积神经网络如何识别图像,主要包括以下
    的头像 发表于 08-21 16:49 1866次阅读

    神经网络在图像识别中的应用

    随着人工智能技术的飞速发展,神经网络在图像识别领域的应用日益广泛。神经网络以其强大的特征提取和分类能力,为图像识别带来了革命性的进步。本文将详细介绍
    的头像 发表于 07-01 14:19 579次阅读