神经网络编程实战-Java语言实现(原书第2版).html.pdf

上传人:紫竹语嫣 文档编号:5518771 上传时间:2020-05-28 格式:PDF 页数:159 大小:11.03MB
返回 下载 相关 举报
神经网络编程实战-Java语言实现(原书第2版).html.pdf_第1页
第1页 / 共159页
神经网络编程实战-Java语言实现(原书第2版).html.pdf_第2页
第2页 / 共159页
神经网络编程实战-Java语言实现(原书第2版).html.pdf_第3页
第3页 / 共159页
神经网络编程实战-Java语言实现(原书第2版).html.pdf_第4页
第4页 / 共159页
神经网络编程实战-Java语言实现(原书第2版).html.pdf_第5页
第5页 / 共159页
点击查看更多>>
资源描述

《神经网络编程实战-Java语言实现(原书第2版).html.pdf》由会员分享,可在线阅读,更多相关《神经网络编程实战-Java语言实现(原书第2版).html.pdf(159页珍藏版)》请在三一文库上搜索。

1、译者序 众所周知,人工智能是当下非常热门的技术。其概念在20世纪80年代就已经炒得火热,但是由于软硬件两方面的技术局限使其两度陷入低谷。而如今,各大IT巨头(诸如谷歌、Facebook、Apple、百 度、腾讯、阿里等)纷纷在人工智能领域密集布局,通过巨额研发投入、人才储备、投资并购及开源合作等方式极力打造各自的人工智能生态圈。人工智能已经成为这个时代激动人心、值得期待的技术, 或将成为未来10年乃至更长时间内IT产业发展的焦点。究其原因,除了互联网大数据积累、计算能力提升及计算成本降低等推动因素外,其本质原因是孜孜不倦积累30多年的神经网络技术的集中爆发。 神经网络(Neural Netwo

2、rk)是人工智能领域最重要的基础模型之一,也是目前非常热门的研究方向深度学习的核心。作为一门重要的机器学习技术,其已经广泛应用于自动驾驶、机器翻译、语 音识别、图像识别等许多前沿领域。而当前人工智能领域的诸多应用平台(如智能客服等)都基于Java服务框架开发,因此,通过Java实现机器学习算法对于业务平台实现真正的智能化非常重要。 遗憾的是,现有的书籍要么只阐述机器学习方面的算法理论,要么只阐述Java理论,缺少基于工程性语言的机器学习算法实现,由此带来的问题是智能化应用产品的落地和实现过程的复杂化。 作为一本集神经网络理论、神经网络Java实现及优秀案例于一体的书,本书以一种简单易懂、循序渐

3、进的方式介绍神经网络。本书由10章构成。首先系统、全面地阐述了神经网络的相关概念、知识点 及特征。然后重点介绍了神经网络学习过程的细节,如何用Java实现神经网络特性及设计神经网络架构,如何优化调整神经网络参数等。最后介绍了一些经典案例。结合Java实现神经网络架构是本书的一 个主要特色。这是一本基于Java语言阐述神经网络架构特性、设计实现过程又包含经典实践案例的优秀书籍。 本书的读者对象如下:1)神经网络初学者,本书全面阐述了神经网络的相关概念、知识点以及神经网络架构的创建过程;2)有Java背景且对智能化方向感兴趣的软件开发者,本书介绍了如何基于 Java实现神经网络核心算法;3)智能化

4、软件开发人员,本书提供了基于神经网络Java实现的诸多案例,为解决实践中的问题提供了很好的借鉴。本书不需要读者有深厚的数学基础,但是懂一些机器学习基 础知识更有助于理解本书。 参与本书翻译工作的人员主要有:百度研发工程师王彩霞和蔚来汽车研发工程师夏妍。非常感谢百度地图刘懿的牵线引荐,让我能有机会和机械工业出版社合作。衷心感谢刘懿、百度美国大数据实验 室的杨涛、百度推荐技术平台部的尚斌及网易产品经理马庆提出的修改建议。也非常感谢清华大学公派加州大学伯克利分校博士顾维玺、机械工业出版社张梦玲编辑的无私帮助。 限于水平,对中文语言的表达及内容的理解难免存在不当之处,在此敬请读者批评指正。本人十分荣幸

5、能有机会成为本书的译者,认真阅读本书也一定会使你受益匪浅。 王彩霞 2018年5月于厦门 作者和审校者简介 作者简介 Fabio M.Soares目前是位于巴西北部的帕拉联邦大学(UFPA)的博士研究生。他几乎对所有领域的技术都充满热情,2004年起开始设计神经网络解决方案,此后将该技术应用于电信、工业过程控制 和建模、水力发电、财务应用、零售客户分析等多个领域。他的研究课题涉及针对数据驱动模型的监督学习。2017年以来,他主要在铝冶炼和铁镍合金方面进行化学过程建模及控制的研究,同时也作为计 算机编程和人工智能课程的讲师,从事教学工作。作为一名活跃的研究者,他已经在诸多会议和期刊上发表了数篇论

6、文,参与4本书的编写。 Alan M.F.Souza是IESAM(Instituto de Estudos Superiores da Amazonia)的一名IT工程师,他拥有帕拉联邦大学软件项目管理专业的研究生学历和工业过程专业(应用计算)的硕士学位。2009 年以来,他一直从事神经网络相关工作,并且自2006年起,他和巴西IT公司共同致力于Java、PHP、SQL及其他编程语言的相关研发工作。他非常热爱编程和计算智能。目前他是UNAMA的教授,同时也 是UFPA的博士研究生。 审校者简介 Charles Griffiths是一名对技术、医学、经济学和营养学感兴趣的软件工程师和大学教授。他

7、在GitHub和Unity Asset Store上都发布过源码。 无论走到哪里,都很感谢那些指引我前进的朋友,感谢他们一直以来对我的支持和信任。 前言 程序员需要持续不断地学习,而且经常会面对新技术和新方法的挑战。生活中人们虽然习惯了重复的事情,但也会经历新的事情。学习过程是科学界最有趣的话题之一,很多尝试都试图描述或者再现 人类的学习过程。 本书的主要挑战是学习并掌握业界最新的内容。虽然神经网络这个名字可能看起来很奇怪,甚至可能误认为它是关于神经学的,但是我们通过把重点放在你决定购买这本书的原因上来简化这些细微差 别。我们打算建立一个框架,告诉你神经网络其实很简单,很容易理解,你不需要有足

8、够的先验知识,就完全可以理解本书提到的概念。 因此,我们希望你充分掌握本书的内容,在面对棘手问题时,能始终以初学者的态度运用神经网络的功能来解决。本书对提到的每个概念都用简单的语言进行解释,但理解它也需要一定的技术背景。 本书的目的是让你了解智能应用可以通过简单语言编写。 各章概览 第1章主要介绍神经网络的概念,解释基本神经元结构(单层感知机、学习机),以及激活函数、权重和学习算法。此外,该章还演示了用Java创建基本神经网络的整个过程。 第2章主要介绍神经网络学习过程的细节,解释几个有用的概念,如训练、测试和验证,演示如何实现训练和验证算法、如何进行误差评估。 第3章主要讨论感知机和监督学习

9、的特性,展示这类神经网络的训练算法,以及如何用Java实现这些特性。 第4章主要介绍无监督学习和自组织映射,即Kohonen神经网络在分类和聚类问题中的应用。 第5章主要阐述如何用神经网络解决天气预报的问题,你会看到来自不同地区、不同时间的历史天气数据记录,并学习如何在神经网络训练之前对数据进行预处理。 第6章主要介绍分类问题,这属于监督学习的范畴。运用患者的数据构建基于神经网络的专家系统,专家系统能够根据患者的症状给出诊断结果。 第7章讨论如何应用无监督学习算法和神经网络实现聚类,进而实现客户画像聚类。 第8章主要介绍另一种涉及神经网络的常见任务:光学字符识别(OCR)。OCR非常有用,它显

10、示了神经网络强大的学习能力。 第9章主要介绍神经网络优化的相关技术,如输入选择,切分训练数据集、验证数据集和测试数据集的较优方法,以及数据过滤和隐含神经元个数的选择。 第10章主要介绍神经网络领域的新技术动态,启发你理解并设计出适用于更复杂问题的新策略。 附录内容为在线内容,可以通过以下链接下载:https:/ 容主要涉及搭建Netbeans开发环境的详细步骤,搭建Eclipse开发环境的详细步骤。 阅读准备 需要Netbeans(beans.org)或者Eclipse(www.eclipse.org)软件,两者都是免费的,可以从官方网站下载。 本书读者对象 本书适合以下Java开发者:想知道

11、如何运用神经网络的功能开发更智能的应用。同时本书适用于那些处理大量复杂数据并希望在日常应用中有更高效率的人士。本书的读者最好具有一些统计计算的基 础知识。 下载示例代码 可以从网站http:/或华章网站下载本书中的示例代码。 第1章 神经网络入门 本章将介绍神经网络及其设计目的。作为后续章节的基础,本章主要介绍神经网络的基本概念。本章将讨论以下主题: 人工神经元 权重和偏置 激活函数 神经元层 使用Java实现神经网络 1.1 探索神经网络 听到神经网络这个词,从直觉上我们会想到大脑,的确,我们可以将大脑看成一个大型的天然神经网络。然而,人工神经网络又是什么呢?人工是一个与天然相对的词,我们首

12、先想到的就是人工大脑 或者机器人,这就是所谓的人工。在这种情况下,受人脑的启发,我们创建出一个和人脑相似的结构,称之为人工智能。 ANN初学者可能认为本书是讲如何构建智能系统的,例如人工大脑,智能系统能用Java代码模拟人类思维,是这样吗?答案是肯定的,但是,我们不会像电影黑客帝国中那样讨论如何创造人工思 考机器;而会介绍人工神经网络解决方案的设计过程,它能够利用整个Java框架,从原始数据抽象知识。 1.2 人工神经网络 在不了解神经网络的起源和相关术语的情况下,无法讨论神经网络。本书中神经网络(NN)和人工神经网络(ANN)是同义词,尽管NN因涵盖自然神经网络而更加通用。那么,什么是ANN

13、呢?下 面探究这个词的历史。 20世纪40年代,神经生理学家Warren McCulloch和数学家Walter Pitts将神经学基础和数学运算结合起来,设计了人工神经元的第一个数学实现。当时,人脑被大量研究以弄懂那些潜在及神秘的行 为,不过主要在神经学领域。众所周知,生物神经元结构有一个细胞核和多个树突(接收来自其他神经元传入的信号),以及一个轴突(将信号传递给其他神经元),如图1-1所示。 图1-1 生物神经元结构 McCulloch和Pitts的创新是在神经元模型中加入了数学成分,他们假设神经元是一个简单的处理器,用于合并所有输入信号并产生新的信号以激活其他神经元,如图1-2所示。 此

14、外,考虑到大脑由数十亿个神经元组成,每个都与成千上万个其他神经元相联系,产生了数万亿的连接,因此我们讨论的是一个巨大的网络结构。基于这个事实,McCulloch和Pitts为单个神经元设 计一个简单的模型,最初用来模拟人类视觉。当时可用的计算器或计算机资源虽然有限,但能很好地处理数学运算。即使今天,像视觉和声音识别这类任务,没有特殊的框架仍然很难编程实现。然而,相 比于复杂的数学运算,人脑可以更高效地识别声音和图像,这激起了科学家和研究人员的兴趣。 图1-2 神经元模型 然而,众所周知,人脑执行的所有复杂活动都基于所学知识,为了克服传统算法在人类易于解决的问题上所面临的困难,我们设计了ANN解

15、决方案,期望它具备基于外部刺激(数据),通过自学习来 解决问题的能力(见表1-1)。 表1-1 人类和计算机可解决的任务 1.2.1 神经网络是如何组织的 结合人脑的特点和结构,可以说ANN是一种自然启发的方法。每个神经元与许多其他神经元相接,这些神经元又会和其他大量神经元相连,形成一个高度互连的结构。本书后续章节将会介绍,神经元 之间的连通性解释了学习能力,因为每个连接都可以根据刺激和期望目标进行配置。 1.2.2 基本元素人工神经元 我们来看看最基本的人工神经元素人工神经元。已证明生物神经元是信号处理器,神经元中的树突会根据接收到信号的强度和振幅,发送信号到轴突。可以这样认为,神经元在输入

16、上有一个信号 收集器,在输出上有一个激活单元,它可以触发一个新的信号,然后传递给其他神经元,如图1-3所示。 图1-3 人工神经元 提示 生物神经元中,存在一个潜在的阈值,一旦达到该值,会触发轴突并传递信号到其他神经元。这一行为可以通过激活函数来模拟,已经证明,激活函数在表示神经元的非线性行为方面非常有 用。 1.2.3 赋予神经元生命激活函数 激活函数是指一个神经元根据输入信号,执行计算并产生输出。从数学方面讲,激活函数用于为神经网络模型的处理加入非线性因素,从而提供人工神经网络的非线性行为,这对模拟生物神经元的非 线性特征非常有用。激活函数通常是一个非线性函数,输出限制在某个区间范围内,但

17、某些特定情况下,也可以是线性函数。 虽然任何函数都可以用作激活函数,但是本章主要介绍常用的几种,见表1-2。 表1-2 常见激活函数 在这些函数和图形中,系数a可以通过激活函数进行设置。 1.2.4 可变参数权重 尽管神经网络的结构能固定,但通过神经元之间的连接权重能够增强或减弱接收到的神经信号,所以可以通过修改权重影响神经元的输出。因此,神经元的激活不仅依赖输入信号,还依赖权重。如果 输入来自其他神经元或者外部世界(刺激),权重可以看成神经网络在神经元之间建立的连接。由于权重是神经网络的内部组件且影响输出,因此也可将权重视为神经网络的认知,即改变权重将会改变神 经网络对外界刺激的应答。 1.

18、2.5 额外参数偏置 作为一个独立组件,偏置主要为激活函数增加一个额外信号,这对人工神经元非常有用。它的作用类似一个输入,只是这个输入等于一个固定值(通常是1)乘以相关性权重。这一特性有助于神经网络 认知表现为一个更纯粹的非线性系统,假设当所有输入都为零时,神经元的输出不仅可以不为零,反而可以由偏置和相关权重触发一个不同的值。 1.2.6 由部分到整体层 为抽象化处理层次,如我们大脑处理问题的方式,神经元按层组织。输入层接收外部世界的直接刺激,输出层触发一些行为,对外部世界产生直接影响。输入层和输出层之间,有许多隐含层,某种意 义上,这些隐含层对外部世界不可见。在人工神经网络中,同一层的所有神

19、经元具有相同的输入和激活函数,如图1-4所示。 图1-4 神经网络层 神经网络由几个互相连接的层组成,形成所谓的多层网络。神经层因此可以分为输入层、隐含层和输出层。 事实上,追加一个神经层可以增强神经网络表达复杂知识的能力。 提示 无论层数多少,每个神经网络都至少有一个输入/输出层。一个多层网络中,输入和输出层之间的层叫作隐含层。 1.2.7 神经网络体系结构 神经网络可以有不同的布局,主要取决于神经元或层之间是如何连接的。每一个神经网络体系结构都是为特定目标而设计。神经网络可以应用于许多问题,根据问题的性质,神经网络旨在更高效地解 决问题。 神经网络体系结构分类如下: 神经元连接 单层网络

20、多层网络 信号流 前馈网络 反馈网络 1.2.8 单层网络 单层网络体系结构中,所有神经元都处于同一层,形成单个层,如图1-5所示。 图1-5 单层网络 神经网络接收输入信号并送入神经元,进而产生输出。神经元可以彼此高度连接,无须递归。如单层感知机、学习机(Adaline)、自组织映射、Elman、Hopfield神经网络等都属于单层网络体系结 构。 1.2.9 多层网络 多层网络中,神经元分成多个层,每层对应神经元的一个平行布局,每层神经元都共享相同的输入数据,如图1-6所示。 图1-6 多层网络 径向基函数(radial basis function)和多层感知机都是这种体系结构的典型例子

21、。这种网络对于设计能近似表达真实数据的函数非常有用。此外,因为经过多层处理,所以这些网络适用于非线性数据 的学习,能够从原始的非线性数据提取或识别知识,以便于更好地分类或决策。 1.2.10 前馈网络 神经网络中的信号流动可以是单向的,也可以是递归的。对于第一种结构,称之为前馈网络,如图1-6所示,输入信号被送入输入层,经过处理后向前传递到下一层。多层感知机和径向基函数也是前馈 网络的好例子。 1.2.11 反馈网络 当神经网络中有某种内部递归时,这意味着信号会反向传递到已经接收或已经处理过信号的神经元或层,这种网络类型称为反馈网络,如图1-7所示。 在网络中加入递归,主要为了产生动态行为,特

22、别是当网络处理涉及时间序列或者模式识别的问题时,就需要内部记忆来加强学习过程。然而,这种网络训练起来特别困难,因为除了准备训练数据之 外,训练过程终归是一个递归行为(例如,一个神经元的输出反过来可能又会成为它的输入)。大多数反馈网络都是单层的,比如Elman网络和Hopfield网络。也有少数是递归的多层网络,比如echo和递 归多层感知机网络。 图1-7 反馈网络 1.3 从无知到认知学习过程 神经网络通过调整神经元之间的连接进行学习,也就是权重。如1.2.4节所述,权重代表神经网络的认知。同样的输入、不同的权重会导致网络产生不同的结果。因此,根据某种学习规则调整权重,可 以改善神经网络的输

23、出结果。学习过程的通用模式如图1-8所示。 因为神经网络有期望输出,所以图1-8描述的过程叫作监督学习,但是神经网络也可以没有任何期望输出(无监督),而是通过输入数据学习而得。第2章将深入探究神经网络的学习过程。 图1-8 通用学习模式 1.4 开始编程神经网络实践 本书将介绍用Java编程语言实现神经网络的整个过程。Java是一种面向对象的编程语言,由Sun公司的一小部分工程师在20世纪90年代创建,后Sun公司于2010年被Oracle收购。现在,Java应用在许 多设备中,已经成为我们日常生活的一部分。 面向对象语言(比如Java),主要处理的是类和对象。类是现实世界中事物的抽象,对象是

24、这个抽象事物的一个实例,有点类似汽车(类指所有及任何汽车)和我的汽车(对象指定的汽车我的) 的关系。Java类通常由属性和方法(或函数)组成,包含面向对象编程(OOP)思想。这里简要回顾一些概念,而不会深入探究,因为本书的目标仅仅是从实用角度来设计和创建神经网络。与这个过程相 关的主要有4个概念。 抽象:将现实世界的问题或规则映射到计算机领域,只考虑其相关特性,不考虑阻碍开发的细节。 封装:类似于产品封装,其中,有些相关特性是公开的(公有方法),有些特性隐藏在作用域内(私有的或者受保护的),因此避免了信息误用或者信息过多。 继承:在现实世界中,对象的多个分类以分层的方式共享属性和方法,例如,车

25、辆可以是轿车和卡车的超类。因此,在OOP中,一个类可以继承另一个类的所有特性,从而避免了代码重写。 多态:与继承几乎相同,不同之处在于,相同函数名的方法在不同的类上表现出不同的行为。 利用本章介绍的OOP思想和神经网络思想,我们将设计实现神经网络的第一个类集。如前所述,神经网络由层、神经元、权重、激活函数和偏置组成。层主要包括三类:输入层、隐含层和输出层。每 层都有一个或者多个神经元,每一个神经元都和神经输入/输出连接,或者和另一个神经元连接,这些连接就是权重。 需要重点强调一下,一个神经网络可能有许多隐含层,也可能一个都没有,因为每层的神经元数目可能不同。然而,输入层和输出层的神经元个数分别

26、等于神经输入/输出的个数。 所以,让我们开始实现吧!首先,定义以下类。 Neuron:定义人工神经元。 NeuralLayer:抽象类,定义一个神经元层。 InputLayer:定义神经输入层。 HiddenLayer:定义输入层和输出层之间的层。 OutputLayer:定义神经输出层。 InputNeuron:定义神经网络输入中出现的神经元。 NeuralNet:将前面定义的所有类组合成一个ANN结构。 除了这些类之外,也要为激活函数定义一个IActivationFunction接口。这是必要的,因为激活函数与方法类似,需要作为神经元的一个属性进行分配。所以要为激活函数定义类,这些类需实现

27、 IActivationFunction接口: Linear Sigmoid Step HyperTan 第1章的编码基本完成。除此之外,还需要定义两个类。一个用于异常处理(NeuralException),另一个用于产生随机数(RandomNumberGenerator)。最后,将这些类分别放到两个包。 edu.packt.neuralnet:与神经网络相关的类(NeuralNet、Neuron、NeuralLayer等) edu.packt.neuralnet.math:与数学相关的类(IActivationFunction、Linear等) 为了节约篇幅,本书不会对每个类进行完整描述,只

28、重点讨论最重要类的关键特性。欢迎读者浏览代码的Javadoc文档以便获得实现的更多细节。 1.5 神经元类 神经元类是本章代码的基础类。根据理论,人工神经元有如下属性: 输入 权重 偏置 激活函数 输出 定义一个在后续例子中很有用的属性也很重要,比如激活函数之前的输出。接下来,实现以下属性: public class Neuron protected ArrayList weight; private ArrayList input; private Double output; private Double outputBeforeActivation; private int number

29、OfInputs = 0; protected Double bias = 1.0; private IActivationFunction activationFunction; http:/ 当实例化神经元时,需要指定输入数据的个数以及激活函数。构造函数如下: public Neuron(int numberofinputs,IActivationFunction iaf) numberOfInputs=numberofinputs; weight=new ArrayList(numberofinputs); activationFunction=iaf; 注意,为偏置定义另一个权重。一个

30、重要的步骤是初始化神经元,也就是为权重赋初始值。这主要在init()方法中完成,通过随机数生成器静态类RandomNumberGenerator生成随机数,赋值权 重。注意,设置权重值时需要防止权重数组越界: public void init() for(int i=0;i0) if(input!=null i neuron; protected IActivationFunction activationFnc; protected NeuralLayer previousLayer; protected NeuralLayer nextLayer; protected ArrayList

31、input; protected ArrayList output; protected int numberOfInputs; http:/ 这个类是抽象的,真正可实例化的层类是InputLayer、HiddenLayer和Outp-utLayer。创建一个层时,必须使用其中一个类的构造函数,这几个类具有相似的构造函数: public InputLayer(int numberofinputs); public HiddenLayer(int numberofneurons,IActivationFunction iaf,int numberofinputs); public OutputL

32、ayer(int numberofneurons,IActivationFunction iaf, int numberofinputs); 层的初始化和计算都和神经元一样,它们也实现了init()方法和calc()方法。声明为protected类型,确保了只有子类可以调用或覆盖这些方法。 protected void init() for(int i=0;i hiddenLayer; private OutputLayer outputLayer; private int numberOfHiddenLayers; private int numberOfInputs; private in

33、t numberOfOutputs; private ArrayList input; private ArrayList output; http:/ 这个类的构造函数比前面类的参数更多: public NeuralNet(int numberofinputs,int numberofoutputs, int numberofhiddenneurons, IActivationFunctionhiddenAcFnc, IActivationFunction outputAcFnc) 如果隐含层的数量是可变的,我们还应该考虑到可能有多个隐含层或0个隐含层,且对每个隐含层来说,隐藏神经元的数量也

34、是可变的。处理这种可变性的最好方法就是把每个隐含层中的神经元数量表 示为一个整数向量(参数numberofhiddenlayers)。此外,需要为每个隐含层定义激活函数,包括输出层,完成这个目标所需的参数分别为hiddenActivationFnc和outputAcFnc。 为了节约篇幅,本章不会展示这个构造函数的完整实现,只展示层的定义和层与层之间的连接。首先,输入层的定义如下: input=new ArrayList0) outputLayer=new OutputLayer(numberofoutputs,outputAcFnc, hiddenLayer.get(numberOfHidd

35、enLayers-1). getNumberOfNeuronsInLayer() ); hiddenLayer.get(numberOfHiddenLayers-1).setNextLayer(outputLayer); else outputLayer=new OutputLayer(numberofinputs, outputAcFnc, numberofoutputs); inputLayer.setNextLayer(outputLayer); calc()方法执行从输入到输出的信号传递: public void calc() inputLayer.setInputs(input);

36、inputLayer.calc(); for(int i=0;i error; public ArrayList generalError; public ArrayList overallError; public double overallGeneralError; public double degreeGeneralError=2.0; public double degreeOverallError=0.0; public enum ErrorMeasurement SimpleError,SquareError,NDegreeError,MSE public ErrorMeasu

37、rement generalErrorMeasurement=ErrorMeasurement.Square- Error; public ErrorMeasurement overallErrorMeasurement=ErrorMeasurement.MSE; private int currentRecord=0; private ArrayList newWeights; / http:/ 2.3.4节讨论的一般误差和总体误差都在DeltaRule类中实现了,因为规则学习算法在训练期间会考虑这些误差。一般误差和总体误差都是数组,因为每个数据集记录都会有一个一般误差,每个输出都 会有一个

38、总体误差。属性overallGeneralError接受损失函数结果,即所有输出和记录的总体误差。属性error是个误差矩阵,存储每个输出记录组合的误差。 这个类里计算一般误差和总体误差的方法有多种。属性generalErrorMeasurement和overallErrorMeasurement可以用一个输入值进行简单误差、平方误差、N-degree误差(三次、四次等)或者 MSE的计算。一般误差的默认值是简单误差,总体误差的默认值是MSE。 这段代码里有两个重要的属性值得注意:currentRecord是指在训练过程中输入神经网络的记录的索引,newWeights的三维矩阵是所有新权值的集

39、合,用于在神经网络中更新权重。currentRecord属 性在在线训练中很有用,newWeights矩阵可以帮助神经网络保存所有原始权重,直到所有新权重计算完成,这将能防止在前向处理阶段更新权重,否则会极大降低训练质量。 2.4.4 规则学习的核心train和calcNewWeight方法 为节约篇幅,这里不详细介绍forward()方法的实现。如前所述,forward意味着神经数据集记录应该输入神经网络,然后计算误差: Override public void train() throws NeuralException / http:/ switch(learningMode) case

40、 BATCH: / this is the batch training mode epoch=0; forward(); / all data are presented to the neural network while(epochMinOverallError) / continue condition epoch+; / new epoch for(int j=0;jMinOverallError) for(int j=0;j=trainingDataSet.numberOfRecords) k=0; / if it was the last record, again the f

41、irst currentRecord=0; epoch+; / epoch completes after presenting all records forward(k); / presenting the next record break; train()方法中,为了持续训练需要循环满足一个条件。这意味着当条件不满足时训练将会停止。这个条件主要检查epoch数(迭代次数)和总体误差。当epoch达到最大值或者总体误差达到最小值 时,训练完成。然而,在某些情况下,总体误差无法满足最低要求,神经网络也需要停止训练。 新权重使用calcNewWeight()方法计算: Override pu

42、blic Double calcNewWeight(int layer,int input,int neuron)throws Neural- Exception / http:/ Double deltaWeight=LearningRate; Neuron currNeuron=neuralNet.getOutputLayer().getNeuron(neuron); switch(learningMode) case BATCH: / Batch mode ArrayList derivativeResult=currNeuron.derivativeBatch(training- Da

43、taSet.getArrayInputData(); ArrayList _ithInput; if(input(); for(int i=0;i newWeights; private ArrayList currentOutputMean; private ArrayList lastOutputMean; 除了缺少误差度量和新增了新的均值度量之外,所有参数都和DeltaRule类相同。除了calcNewWeight()方法,方法也很相似: Override public Double calcNewWeight(int layer,int input,int neuron)throws

44、Neural- Exception / http:/ Double deltaWeight=LearningRate; Neuron currNeuron=neuralNet.getOutputLayer().getNeuron(neuron); switch(learningMode) case BATCH: / http:/ / the batch case is analogous to the implementation in Delta Rule / but with the neurons output instead of the error / were suppressin

45、g here to save space break; case ONLINE: deltaWeight*=currNeuron.getOutput(); if(input=deltaRule.getOverallGeneralError() System.out.println(“Training succesful!“); else System.out.println(“Training was unsuccesful“); 训练开始,每个权重更新后,总体误差信息都随着更新。注意,误差在减小: 五次迭代后,误差达到最小值。神经输出的坐标图如图2-11所示。 图2-11 神经输出及坐标图

46、很神奇,不是吗?神经输出和目标输出实际上是一样的,查看最终的Weight和bias: weight = nn.getOutputLayer().getWeight(0, 0); bias = nn.getOutputLayer().getWeight(1, 0); System.out.println(“Weight found:“+String.valueOf(weight); System.out.println(“Bias found:“+String.valueOf(bias); / Weight found:0.2668421011698528 / Bias found:0.0011258204676042108 2.6 测试 我们可能会问,神经网络已经从数据中学会了吗?如何证明它已经有效地学习了?就像学生需要经历考试一样,我们需要在训练之后

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/环境 > 建筑资料


经营许可证编号:宁ICP备18001539号-1