精华内容
下载资源
问答
  • 思维进化算法有极强的全局搜索能力,能够弥补BP神经网络陷入局部最优和对初始权值和阈值敏感的问题,因此在训练BP神经网络之前,利用思维进化算法获取该网络的初始权值和阈值。实验证明,与传统的维纳滤波、BP、遗传...
  • 用改进的人工蜂群全局搜索神经网络的初始权重,防止神经网络陷入局部最优。用新的方法对神经网络训练进行分类。实验结果表明,该算法相对于标准的BP神经网络,有效提高了分类正确率,泛化能力较强。
  • 基于遗传算法优化的BP神经网络是科研中的常用方法,通过遗传算法优化初始神经网络的权值阈值,使模型更快收敛,同时降低陷入局部最优的可能,本资源代码中,只需更改加载数据,拿来即用。
  • 引入自适应变异算子对陷入局部最优的粒子进行变异,改进了粒子群算法的寻优性能; 利用改进粒子群算法优化BP神经网络的权值和阈值,训练BP神经网络预测模型求得最优解。将该预测方法应用到几个典型的非线性系统的混沌...
  • 传统的BP神经网络通过梯度下降法来调整网络的权值和阈值,使网络存在易陷入局部最优且收敛速度慢等缺陷,在很大程度上限制了BP神经网络的应用。针对BP网络存在的不足,提出利用自适应花授粉算法来优化BP网络的权值和...
  • 基于遗传算法的BP神经网络

    千次阅读 2019-04-14 16:32:40
    基于遗传算法的BP神经网络 源码地址:https://github.com/Grootzz/GA-BP 介绍: 利用遗传算法并行地优化BP网络的权值和阈值,从而避免了BP网络在优化权值和阈值时陷入局部最优的缺点 背景: 这个项目的背景为客运量...

    基于遗传算法的BP神经网络

    源码地址:https://github.com/Grootzz/GA-BP
    介绍:
    利用遗传算法并行地优化BP网络的权值和阈值,从而避免了BP网络在优化权值和阈值时陷入局部最优的缺点

    背景:
    这个项目的背景为客运量和货运量的预测

    文件介绍:

    1. freightFlow.xlsx : 货运量数据集,前7列为影响货运量的因素,第8列为货运量
    2. passengerFlow.xlsx : 客运量数据集,前7列为影响货运量的因素,第8列为客运量
    3. Data.mat:这是一个结构体,成员P为从客运量数据集,成员F为货运量数据集

    函数概述:

    1. gadecod:对输入的染色体编码,编码方式一般有两种,实数编码和二进制编码。
      此项目中对应的为实数编码,所以编码后的值即为解码后的值。
    2. getBPinfo:获取BP网络的基本信息。
    3. gabpEval:计算适应度
    4. normInit:数据获取,存入结构体Data.mat
    5. mainFun:主函数,完成训练和预测

    GAOT使用说明:

    因为项目中用到了GAOT工具包中的函数,所以需要将GAOT工具包加入路径。
    操作步骤为:点击GAOT文件—>添加到路径—>选定文件夹和子文件夹
    这样,工程中就可以调用GAOT工具包中的函数了

    初始种群的生成函数:

    [pop]=initializega(num,bounds,eevalFN,eevalOps,options)

    • 【输出参数】

    pop–生成的初始种群

    • 【输入参数】

    num–种群中的个体数目
    bounds–代表变量的上下界的矩阵
    eevalFN–适应度函数
    eevalOps–传递给适应度函数的参数
    options–选择编码形式(浮点编码或是二进制编码)[precision F_or_B]
    precision–变量进行二进制编码时指定的精度
    F_or_B–为1时选择浮点编码,否则为二进制编码,由precision指定精度)

    遗传算法函数:

    [x,endPop,bPop,traceInfo]=ga(bounds,evalFN,evalOps,startPop,opts,termFN,termOps,selectFN,selectOps,xOverFNs,xOverOps,mutFNs,mutOps)
    【输出参数】
    x--求得的最优解
    endPop--最终得到的种群
    bPop--最优种群的一个搜索轨迹
    traceInfo--每一代的最好的适应度和平均适应度
    【输入参数】
    bounds--代表变量上下界的矩阵
    evalFN--适应度函数
    evalOps--传递给适应度函数的参数
    startPop-初始种群
    opts[epsilonprob_opsdisplay]--opts(1:2)等同于initializega的options参数,第三个参数控制是否输出,一般为0。如[1e-610]
    termFN--终止函数的名称,如['maxGenTerm']
    termOps--传递个终止函数的参数,如[100]
    selectFN--选择函数的名称,如['normGeomSelect']
    selectOps--传递个选择函数的参数,如[0.08]
    xOverFNs--交叉函数名称表,以空格分开,如['arithXoverheuristicXoversimpleXover']
    xOverOps--传递给交叉函数的参数表,如[20;23;20]
    mutFNs--变异函数表,如['boundaryMutationmultiNonUnifMutationnonUnifMutationunifMutation']
    mutOps--传递给交叉函数的参数表,如[400;61003;41003;400]
    

    源码地址:https://github.com/Grootzz/GA-BP

    展开全文
  • 引入自适应变异算子对陷入局部最优的粒子进行变异, 改进了粒子群算法的寻优性能, 利用改进粒子群算法优化 BP 神经网络的权值和阈值, 然后训练 BP 神经网络预测模型求得最优解. 将该预测方法应用到实测交通流的时间...
  • 以6种水化离子浓度作为判别突水来源的依据,为克服人工神经网络采用标准BP算法修正初始权值和阈值所带来的具有随机性和易陷入局部最小缺点,拟采取具有全局最优功能的遗传算法(GA)优化BP神经网络,从而建立突水水源的GA...
  • 针对标准BP神经网络收敛速度慢,容易陷入局部极小等缺陷,采用改变传递函数和改变学习率寻找最优权2种方法对其改进。通过分析车削零件表面粗糙度的影响因素,应用改进的BP神经网络,借助计算机编程计算,进行车削加工的...
  • 为了提高BP神经网络在保险欺诈识别中的准确率,利用改进的遗传算法优化BP神经网络初始权重,以克服BP神经网络容易陷入局部极小点、收敛速度慢以及样本依赖性等问题的缺点。改进的遗传算法充分考虑了遗传算法中种群适应...
  • BP神经网络算法存在收敛速度慢和容易陷入局部最小值的缺陷,利用粒子群算法的全局最优和收敛速度快的特性改良BP神经网络,然后利用粒子群优化BP神经网络对PID的3个参数进行在线调整。仿真结果表明,经过粒子群优化后...
  • BP算法基于梯度下降原理是一种局部寻优算法,在...将二者结合起来,由GA寻找最优BP神经网络权值与相应节点的阈值。仿真结果表明:此方法既能快速收敛,又能大大提高避免陷入局部极小的能力,改善了故障诊断的精度和速度。
  • 由GA寻找最优BP神经网络权值与相应节点的阀值,可以有效防止搜索过程收敛于局部最优解。通过仿真结果得出:此方法既能快速收敛,又能大大提高避免陷入局部极小的能力,并且预测精度高,为柴油机噪声主观评价提供了...
  • 提出了一种将蚁群算法与算法相融合共同完成反传神经网络训练的方法,ACO一BP算法...将ACO一BP神经网络用于函数逼近问题,并与BP神经网络、蚁群算法神经网络和遗传神经网络的逼近结果进行了比较,验证了该算法的有效性。
  • 基于 MATLAB 的遗传算法优化神经网络

    万次阅读 多人点赞 2018-08-14 00:43:38
    面对较复杂的非线性系统问题时,由于 BP 网络设置的初始权值依赖设计者的经验和样本空间的反复试验,容易产生收敛速度慢、网络不稳定以及陷入局部最优等一系列问题.将 BP 神经网络算法与遗传算法结合,理论上可以对...

    面对较复杂的非线性系统问题时,由于 BP 网络设置的初始权值依赖设计者的经验和样本空间的反复试验,容易产生收敛速度慢、网络不稳定以及陷入局部最优等一系列问题.将 BP 神经网络算法与遗传算法结合,理论上可以对任意非线性系统进行映射,并且得到全局最优的效果,从而形成一种更加有效的非线性反演方法。本场 Chat 中遗传算法对 BP 神经网络进行如下优化,话题将从遗传算法,BP 神经网络两部分分别开始,主要进行 BP 神经网络应用的快速实用入门,学完之后能够学会调用 GA_BP 算法处理数据。

    本场 Chat 主要内容:

    • BP 神经网络的原理;
    • 遗传算法引入;
    • GA_BP 示范代码解读。

    第一步 认识 BP 神经网络

    我们主干是需要了解神经网络,因为遗传算法的的加入是对神经网络的改进,除了遗传算法还可以用小波算法,蚁群算法。遗传算法可以得到最优个体的初始权值和阈值。先从神经网络算法开始入门。

    1.1神经网络的分类

    人工神经网络分类为以下两种:

    1.1.1 依学习策略(Algorithm)分类主要有:

    监督式学习网络(Supervised Learning Network)为主。
    无监督式学习网络(Unsupervised Learning Network)。
    混合式学习网络(Hybrid Learning Network)。
    联想式学习网络(Associate Learning Network)。
    最适化学习网络(Optimization Application Network)。

    1.1.2 依网络架构(Connectionism)分类主要有:

    前向式架构(Feed Forward Network)。
    回馈式架构(Recurrent Network)。
    强化式架构(Reinforcement Network)。

    1.2 学习算法

    (1) Hebb 学习规则。
    (2) Delta 学习规则。
    (3) 梯度下降学习规则。
    (4) Kohonen 学习规则(就是SOM)。
    (5)向后传播学系规则(BP)。
    (6) 概率式学习规则(GA)。
    (7)竞争式学习规则(SOM,ART,CPN)。

    1.3 BP 神经网络

    BP 神经网络训练算法:

    (1) 初始化网络设置。
    (2) 向前传播输入。
    (3) 反向误差传播。
    (4) 网络权重与神经元偏置调整。
    (5) 判断结束。

    详细:BP 神经网络是怎样的一种定义?看这句话:一种按 “ 误差逆传播算法训练 ” 的多层前馈网络。

    BP 的思想就是:利用输出后的误差来估计输出层前一层的误差,再用这层误差来估计更前一层误差,如此获取所有各层误差估计。这里的误差估计可以理解为某种偏导数,我们就是根据这种偏导数来调整各层的连接权值,再用调整后的连接权值重新计算输出误差。

    直到输出的误差达到符合的要求或者迭代次数溢出设定值。

    说来说去,“ 误差 ” 这个词说的很多嘛,说明这个算法是不是跟误差有很大的关系?

    没错,BP 的传播对象就是 “ 误差 ”,传播目的就是得到所有层的估计误差。

    它的学习规则是:使用最速下降法,通过反向传播(就是一层一层往前传)不断调整网络的权值和阈值,最后使全局误差系数最小。

    它的学习本质就是:对各连接权值的动态调整。

    BP 网络由输入层、隐层和输出层组成,隐层可以有一层或多层:输入层(input),隐藏层(hide layer),输出层(output)BP 网络的优势就是能学习和储存大量的输入输出的关系,而不用事先指出这种数学关系。那么它是如何学习的?

    BP 利用处处可导的激活函数来描述该层输入与该层输出的关系,常用 S 型函数 δ 来当作激活函数。

    是 m × k × n 的三层 BP 网络模型,网络选用 S 型传递函数,通过反传误差函数 ( (Ti 为期望输出、Oi 为网络的计算输出),不断调节网络权值和 阈值使误差函数 E 达到极小。

    其中,n 为输入层神经元个数,m 为输出层神经元个数,a 为 [ 1, 10] 之间的常数。

    我们现在开始有监督的 BP 神经网络学习算法:

    1、正向传播得到输出层误差 e;=>输入层输入样本=>各隐藏层=>输出层。
    2、判断是否反向传播;=>若输出层误差与期望不符=>反向传播。
    3、误差反向传播;=>误差在各层显示=>修正各层单元的权值,直到误差减少到可接受程度。

    算法阐述起来比较简单,接下来通过数学公式来认识 BP 的真实面目。

    假设我们的网络结构是一个含有 N 个神经元的输入层,含有 P 个神经元的隐层,含有 Q 个神经元的输出层。

    认识好以上变量后,开始计算:

    一、 用(-1,1)内的随机数初始化误差函数,并设定精度 ε,最多迭代次数 M。

    二、随机选取第 k 个输入样本及对应的期望输出。

    重复以下步骤至误差达到要求:

    三、计算隐含层各神经元的输入和输出。

    四、计算误差函数 e 对输出层各神经元的偏导数,根据输出层期望输出和实际输出以及输出层输入等参数计算。

    五、计算误差函数对隐藏层各神经元的偏导数,根据后一层(这里即输出层)的灵敏度(稍后介绍灵敏度) δo(k),后一层连接权值 w,以及该层的输入值等参数计算

    六、利用第四步中的偏导数来修正输出层连接权值

    七、利用第五步中的偏导数来修正隐藏层连接权值

    八、计算全局误差(m 个样本,q 个类别)

    第二步 加入遗传算法

    1.1 遗传算法

    目的:神经网络里面有很多参数,但是你并不知道哪些参数训练出来的效率最高,识别率最高。这时候就可以以这个识别率为目标函数,用遗传算法来优化神经网络的参数。

    遗传神经网络算法和神经网络算法最本质的区别可以说是学习方法不同,或者说模型的优化方法不同。

    前者应该是基于遗传算法进行网络权值的学习,而后者大都是采用反向传播(BP)算法进行权值学习,而这两种算法差异很大。可以分别了解:

    1)遗传算法:

    遗传算法属于进化算法,模拟大自然生物进化的过程:优胜略汰。个体不断进化,只有高质量的个体(目标函数最小(大))才能进入下一代的繁殖。如此往复,最终找到全局最优值。遗传算法能够很好的解决常规优化算法无法解决的高度非线性优化问题,广泛应用在各行各业中。差分进化,蚁群算法,粒子群算法等都属于进化算法,只是模拟的生物群体对象不一样而已。

    2)反向传播算法

    详细介绍遗传算法:遗传算法 GA —模拟自然界遗传机制和生物进化论而成的一种并行随机搜索最优化方法。(具有 “ 生存 + 检测 ” 的迭代过程的搜索算法)基于自然界 “ 优胜劣汰,适者生存 ” 的生物进化原理引入优化参数形成的编码串联群体中,按照所选择的适应度函数并通过遗传中的选择、交叉和变异对个体进行筛选,使适应度值好的个体被保留,适应度差的个体被淘汰,新的群体既继承了上一代的信息,又优于上一代。反复循环,直至满足条件。

    种群中的每个个体是问题的一个解,称为 “ 染色体 ”,染色体是一串符号,如二进制字符串。利用 “ 适值 ”(适应性函数)测量染色体的好坏。 遗传算法基本操作分为:

    1. 选择操作:以一定概率选择旧群体个体到新群体中,个体被选中的概率跟适应度值有关个体适应度越好被选中改了吧越大。
    2. 交叉操作 – 信息交换思想选两个个体交换组合产生新的优秀个体,染色体位置互换。
    3. 变异操作 — 以一定的低概率发生,染色体位置产生变异(通常取值 0.001 - 0.01 之间)。 遗传算法是具有高效启发式搜索、并行计算等特点,应用于函数优化、组合优化及生产调度等方面。

    算法基本要素:

    1、染色体编码方法 。
    2、适应度函数。
    3、遗传操作(选择、交叉、变异) 。
    4、运行参数 —(参数:群体大小 M、遗传代数 G、交叉概率 Pc 和变异概率 Pm) 。

    1、种群初始化

    个体编码方法为实数编码,每隔个体均为一个实数串,由输入层和隐含层连接权值、隐含层阈值、隐含层与输出层连接权值以及输出层阈值 4 个部分组成。个体包含了神经网络全部的权值和阈值,在网路结构一直的情况下,就可以构成一个结构、权值、阈值确定的神经网络。

    2、适应度函数

    根据个体得到 BP 神经网络的初始权值和阈值,用训练数据训练 BP 神经网络后预测系统输出,把预测输出个期望的输出之间的误差绝对值和 E 作为个体适应度值 F。

    3、选择操作

    遗传算法选择操作有轮盘赌法、锦标赛法等多种方法。选择轮盘赌法时,即基于适应度比例的选择策略,每个个体 i 的选择概率 pi。

    4、交叉操作

    由于个体采用实数编码,所以交叉操作方法采用实数交叉法。

    5、变异操作

    选取第 i 个个体的第 j 个基因 aij 进行变异变异操作。

    1.2 神经网络加入遗传算法

    1.2.1 遗传算法在神经网络中的应用

    神经网络的设计要用到遗传算法,遗传算法在神经网络中的应用主要反映在 3 个方面: 网络的学习,网络的结构设计,网络的分析。

    1.2.1.1 遗传算法在网络学习中的应用

    在神经网络中,遗传算法可用于网络的学习。这时,它在两个方面起作用。学习规则的 优化用遗传算法对神经网络学习规则实现自动优化,从而提高学习速率。网络权系数的优化 用遗传算法的全局优化及隐含并行性的特点提高权系数优化速度。

    1.2.1.2 遗传算法在网络设计中的应用

    用遗传算法设计一个优秀的神经网络结构,首先是要解决网络结构的编码问题;然后才 能以选择、交叉、变异操作得出最优结构。

    编码方法主要有下列 3 种:

    直接编码法:这是把神经网络结构直接用二进制串表示,在遗传算法中,“ 染色体 ” 实质 上和神经网络是一种映射关系。通过对 “ 染色体 ” 的优化就实现了对网络的优化。

    参数化编码法:参数化编码采用的编码较为抽象,编码包括网络层数、每层神经元数、 各层互连方式等信息。一般对进化后的优化“染色体”进行分析,然后产生网络的结构。

    繁衍生长法:这种方法不是在 “ 染色体 ” 中直接编码神经网络的结构,而是把一些简单 的生长语法规则编码入 “ 染色体 ” 中;然后,由遗传算法对这些生长语法规则不断进行改变, 最后生成适合所解的问题的神经网络。这种方法与自然界生物地生长进化相一致。

    1.2.1.3 遗传算法在网络分析中的应用

    遗传算法可用于分析神经网络。神经网络由于有分布存储等特点,一般难以从其拓扑结构直接理解其功能。遗传算法可对神经网络进行功能分析,性质分析,状态分析。

    遗传算法虽然可以在多种领域都有实际应用,并且也展示了它潜力和宽广前景;但 是,遗传算法还有大量的问题需要研究,目前也还有各种不足。首先,在变量多,取值范围 大或无给定范围时,收敛速度下降;其次,可找到最优解附近,但无法精确确定最扰解位置; 最后,遗传算法的参数选择尚未有定量方法。

    对遗传算法,还需要进一步研究其数学基础理 论;还需要在理论上证明它与其它优化技术的优劣及原因;还需研究硬件化的遗传算法;以及遗传算法的通用编程和形式等。

    小结:遗传算法和神经网络都是计算智能领域重要的算法,遗传算法借鉴生物界适者生存,优胜劣 汰遗传机制的规律,来寻找一个问题的最优解。

    神经网络则是模拟生物神经网络的结构和功 能的数学模型或计算模型。大量细胞构成各种神经网络。通过在遗传算法调整神经网络的结 构,使得神经网络获得动态的结构,从而更加智能。用遗传算法调整权重,获得更快的速度, 同时更大程度的避免出现局部最优情况下收敛。将遗传算法应用于神经网络,大大提高神经网络的性能。

    第三步 代码赏析

    数据归一化是神经网络预测前对数据常做的一种处理方法,将数据转化为【0,1】之间的数字,取消各维数据间的数量级误差,避免因此造成的网络预测误差较大,一般有两种方法:最大最小函数法和平均数方差法;当使用最大最小归一法时可以使用函数:

    mapminmax.[inputn,inputs]=mapminmax(input_train)

    分别为 归一化后的数据 归一化后得到的结构体 训练输入测试数据归一化和反归一化的程序如下:

    Inputn_test=mapminmax(‘apply’,input_test,inputs);BPoutput=mapminmax(‘reverse’,an,outputs);%反归一

    另外归一化的方法有:

    <1> premnmx

    语法:

    [pn,minp,maxp,tn,mint,maxt] = premnmx(p,t)。

    参数:

    pn: p 矩阵按行归一化后的矩阵 minp。
    maxp:p 矩阵每一行的最小值,最大值。
    tn:t 矩阵按行归一化后的矩阵 mint。
    maxt:t 矩阵每一行的最小值,最大值。

    作用:将矩阵 p,t 归一化到 [-1,1] ,主要用于归一化处理训练数据集。

    <2> tramnmx

    语法:

    [pn] = tramnmx(p,minp,maxp)。

    参数:minp,maxp:premnmx 函数计算的矩阵的最小,最大值。pn:归一化后的矩阵。作用:主要用于归一化处理待分类的输入数据。

    <3> postmnmx

    语法:

    [p,t] =
    postmnmx(pn,minp,maxp,tn,mint,maxt)。

    参数:minp,maxp:premnmx 函数计算的 p 矩阵每行的最小值,最大值。mint,maxt:premnmx 函数计算的 t 矩阵每行的最小值,最大值。作用:将矩阵 pn,tn 映射回归一化处理前的范围。

    postmnmx 函数主要用于将神经网络的输出结果映射回归一化前的数据范围。

    BP 神经网络工具箱

    使用 Matlab 建立前馈神经网络主要会使用到下面 3 个函数:

    • newff :前馈网络创建函数。
    • train:训练一个神经网络。
    • sim :使用网络进行仿真。

    这三个函数的参数如下:net=newff(P,T,S,TF,BTF,BLF,PF,LPF,OPF,DDF)

    • P:输入数据矩阵一个 n × 2 的矩阵,第 i 行元素为输入信号 xi 的最小值和最大值;
    • T:输出数据矩阵一个 k 维行向量,其元素为网络中各层节点数;
    • S:隐含层节点数一个 k 维字符串行向量,每一分量为对应层神经元的激活函数
    • TF:节点传递函数为学习规则采用的训练算法。
    • BTF:训练函数。
    • BLF:网络学习函数。
    • PF:性能分析函数。
    • IPF:输入处理函数。
    • OPF:输出处理函数。
    • DDF:验证数据划分函数。
    • [net,tr] = train(NET,X,T,Pi,Ai)。
    • NET:待训练网络。
    • X:输入数据矩阵。
    • T:输出数据矩阵。
    • Pi:初始化输入层条件。
    • AI:初始化输出层条件。
    • Net:训练好的网络。
    • Tr:训练过程记录。
    • Y = sim (net,x)。
    • Y:网络预测数据。
    • x:输入数据。
    • net:训练好的网络。

    MORE:

    常用的激活函数

    常用的激活函数有:a) 线性函数 (Linear transfer function)f(x) = x,该函数的字符串为 purelin

    b) 对数 S 形转移函数( Logarithmic sigmoid transfer function ) 该函数的字符串为 logsig

    c) 双曲正切 S 形函数 (Hyperbolic tangent sigmoid transfer function )

    也就是上面所提到的双极 S 形函数。该函数的字符串为 tansig

    Matlab 的安装目录下的 toolbox\nnet\nnet\nntransfer 子目录中有所有激活函数的定义说明。

    常见的训练函数

    常见的训练函数有:

    • traingd :梯度下降 BP 训练函数(Gradient descent backpropagation)。
    • traingdx :梯度下降自适应学习率训练函数。
    网络配置参数

    一些重要的网络配置参数如下:

    • net.trainparam.goal:神经网络训练的目标误差。
    • net.trainparam.show : 显示中间结果的周期。
    • net.trainparam.epochs :最大迭代次数。
    • net.trainParam.lr:学习率。
    train 函数

    网络训练学习函数。

    语法:[ net, tr, Y1, E ] = train( net, X, Y )

    参数:

    • X:网络实际输入。
    • Y:网络应有输出。
    • tr:训练跟踪信息。
    • Y1:网络实际输出。
    • E:误差矩阵。
      sim 函数:
    • 语法:Y=sim(net,X)。
    参数:

    net:网络

    • X:输入给网络的K× N 矩阵,其中 K 为网络输入个数,N 为数据样本数。
    • Y:输出矩阵 Q × N,其中 Q 为网络输出个数。

    <1>隐含层节点个数 隐含层节点的个数对于识别率的影响并不大,但是节点个数过多会增加运算量,使得训练较慢。

    <2>激活函数的选择 激活函数无论对于识别率或收敛速度都有显著的影响。在逼近高次曲线时,S 形函数精度比线性函数要高得多,但计算量也要大得多。

    适应度函数:

     function error=fun(x,inputnum,hiddennum,outputnum,net,inputn,outputn)    %该函数用来计算适应度值%x          input     个体%inputnum   input     输入层节点数%outputnum  input     隐含层节点数%net        input     网络%inputn     input     训练输入数据%outputn    input     训练输出数据%error      output    个体适应度值w1=x(1:inputnum*hiddennum);    B1=x(inputnum*hiddennum+1:inputnum*hiddennum+hiddennum);    w2=x(inputnum*hiddennum+hiddennum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum);B2=x(inputnum*hiddennum+hiddennum+hiddennum*outputnum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum+outputnum);net=newff(inputn,outputn,hiddennum);%网络进化参数    net.trainParam.epochs=20;    net.trainParam.lr=0.1;     net.trainParam.goal=0.00001;    net.trainParam.show=100;    net.trainParam.showWindow=0;    %网络权值赋值    net.iw{1,1}=reshape(w1,hiddennum,inputnum);    net.lw{2,1}=reshape(w2,outputnum,hiddennum);    net.b{1}=reshape(B1,hiddennum,1);30.    net.b{2}=B2;    %网络训练    net=train(net,inputn,outputn);    an=sim(net,inputn);    error=sum(abs(an-outputn));

    选择操作函数

    1.    function ret=select(individuals,sizepop)2.    % 该函数用于进行选择操作3.    % individuals input    种群信息4.    % sizepop     input    种群规模5.    % ret         output   选择后的新种群6.     7.    %求适应度值倒数   8.    fitness1=10./individuals.fitness; %individuals.fitness为个体适应度值9.     10.    %个体选择概率11.    sumfitness=sum(fitness1);12.    sumf=fitness1./sumfitness;13.     14.    %采用轮盘赌法选择新个体15.    index=[]; 16.    for i=1:sizepop   %sizepop为种群数17.        pick=rand;18.        while pick==0    19.            pick=rand;        20.        end21.        for i=1:sizepop    22.            pick=pick-sumf(i);        23.            if pick<0        24.                index=[index i];            25.                break;  26.            end27.        end28.    end29.     30.    %新种群31.    individuals.chrom=individuals.chrom(index,:);   %individuals.chrom为种群中个体32.    individuals.fitness=individuals.fitness(index);33.    ret=individuals;

    交叉操作:

    1.    function ret=Cross(pcross,lenchrom,chrom,sizepop,bound)2.    %本函数完成交叉操作3.    % pcorss                input  : 交叉概率4.    % lenchrom              input  : 染色体的长度5.    % chrom     input  : 染色体群6.    % sizepop               input  : 种群规模7.    % ret                   output : 交叉后的染色体8.     for i=1:sizepop  %每一轮for循环中,可能会进行一次交叉操作,染色体是随机选择的,交叉位置也是随机选择的,%但该轮for循环中是否进行交叉操作则由交叉概率决定(continue控制)9.         % 随机选择两个染色体进行交叉10.         pick=rand(1,2);11.         while prod(pick)==012.             pick=rand(1,2);13.         end14.         index=ceil(pick.*sizepop);15.         % 交叉概率决定是否进行交叉16.         pick=rand;17.         while pick==018.             pick=rand;19.         end20.         if pick>pcross21.             continue;22.         end23.         flag=0;24.         while flag==025.             % 随机选择交叉位26.             pick=rand;27.             while pick==028.                 pick=rand;29.             end30.             pos=ceil(pick.*sum(lenchrom)); %随机选择进行交叉的位置,即选择第几个变量进行交叉,注意:两个染色体交叉的位置相同31.             pick=rand; %交叉开始32.             v1=chrom(index(1),pos);33.             v2=chrom(index(2),pos);34.             chrom(index(1),pos)=pick*v2+(1-pick)*v1;35.             chrom(index(2),pos)=pick*v1+(1-pick)*v2; %交叉结束36.             flag1=test(lenchrom,bound,chrom(index(1),:));  %检验染色体1的可行性37.             flag2=test(lenchrom,bound,chrom(index(2),:));  %检验染色体2的可行性38.             if   flag1*flag2==039.                 flag=0;40.             else flag=1;41.             end    %如果两个染色体不是都可行,则重新交叉42.         end43.     end44.    ret=chrom;

    变异操作:

    1.    function ret=Mutation(pmutation,lenchrom,chrom,sizepop,num,maxgen,bound)2.    % 本函数完成变异操作3.    % pcorss                input  : 变异概率4.    % lenchrom              input  : 染色体长度5.    % chrom     input  : 染色体群6.    % sizepop               input  : 种群规模7.    % opts                  input  : 变异方法的选择8.    % pop                   input  : 当前种群的进化代数和最大的进化代数信息9.    % bound                 input  : 每个个体的上届和下届10.    % maxgen                input  :最大迭代次数11.    % num                   input  : 当前迭代次数12.    % ret                   output : 变异后的染色体13.     14.    for i=1:sizepop   %每一轮for循环中,可能会进行一次变异操作,染色体是随机选择的,变异位置也是随机选择的,15.        %但该轮for循环中是否进行变异操作则由变异概率决定(continue控制)16.        % 随机选择一个染色体进行变异17.        pick=rand;18.        while pick==019.            pick=rand;20.        end21.        index=ceil(pick*sizepop);22.        % 变异概率决定该轮循环是否进行变异23.        pick=rand;24.        if pick>pmutation25.            continue;26.        end27.        flag=0;28.        while flag==029.            % 变异位置30.            pick=rand;31.            while pick==0      32.                pick=rand;33.            end34.            pos=ceil(pick*sum(lenchrom));  %随机选择了染色体变异的位置,即选择了第pos个变量进行变异35.        36.            pick=rand; %变异开始     37.            fg=(rand*(1-num/maxgen))^2;38.            if pick>0.539.                chrom(i,pos)=chrom(i,pos)+(bound(pos,2)-chrom(i,pos))*fg;40.            else41.                chrom(i,pos)=chrom(i,pos)-(chrom(i,pos)-bound(pos,1))*fg;42.            end   %变异结束43.            flag=test(lenchrom,bound,chrom(i,:));     %检验染色体的可行性44.        end45.    end46.    ret=chrom;

    主函数:

    步骤:
    1、随机初始化种群。
    2、计算种群适应度值从中找出最优个体。
    3、选择操作。
    4、交叉操作。
    5、变异操作。
    6、判断进化是否结束,否返回步骤 2。

    input 为输入数据,output 为输出

    1.    % 清空环境变量2.    clc3.    clear4.    % 5.    %% 网络结构建立6.    %读取数据7.    load data input output8.     9.    %节点个数10.    inputnum=2;11.    hiddennum=5;12.    outputnum=1;13.     14.    %训练数据和预测数据15.    input_train=input(1:1900,:)';16.    input_test=input(1901:2000,:)';17.    output_train=output(1:1900)';18.    output_test=output(1901:2000)';19.     20.    %选连样本输入输出数据归一化21.    [inputn,inputps]=mapminmax(input_train);22.    [outputn,outputps]=mapminmax(output_train);23.     24.    %构建网络25.    net=newff(inputn,outputn,hiddennum);26.     27.    %% 遗传算法参数初始化28.    maxgen=10;                         %进化代数,即迭代次数29.    sizepop=10;                        %种群规模30.    pcross=[0.3];                       %交叉概率选择,0和1之间31.    pmutation=[0.1];                    %变异概率选择,0和1之间32.     33.    %节点总数34.    numsum=inputnum*hiddennum+hiddennum+hiddennum*outputnum+outputnum;35.     36.    lenchrom=ones(1,numsum);        37.    bound=[-3*ones(numsum,1) 3*ones(numsum,1)];    %数据范围38.     39.    %------------------------------------------------------种群初始化--------------------------------------------------------40.    individuals=struct('fitness',zeros(1,sizepop), 'chrom',[]);  %将种群信息定义为一个结构体41.    avgfitness=[];                      %每一代种群的平均适应度42.    bestfitness=[];                     %每一代种群的最佳适应度43.    bestchrom=[];                       %适应度最好的染色体44.    %初始化种群45.    for i=1:sizepop46.        %随机产生一个种群47.        individuals.chrom(i,:)=Code(lenchrom,bound);    %编码(binary和grey的编码结果为一个实数,float的编码结果为一个实数向量)48.        x=individuals.chrom(i,:);49.        %计算适应度50.        individuals.fitness(i)=fun(x,inputnum,hiddennum,outputnum,net,inputn,outputn);   %染色体的适应度51.    end52.     53.    %找最好的染色体54.    [bestfitness bestindex]=min(individuals.fitness);55.    bestchrom=individuals.chrom(bestindex,:);  %最好的染色体56.    avgfitness=sum(individuals.fitness)/sizepop; %染色体的平均适应度57.    % 记录每一代进化中最好的适应度和平均适应度58.    trace=[avgfitness bestfitness]; 59.     60.    %% 迭代求解最佳初始阀值和权值61.    % 进化开始62.    for i=1:maxgen63.        i64.        % 选择65.        individuals=Select(individuals,sizepop); 66.        avgfitness=sum(individuals.fitness)/sizepop;67.        %交叉68.        individuals.chrom=Cross(pcross,lenchrom,individuals.chrom,sizepop,bound);69.        % 变异70.        individuals.chrom=Mutation(pmutation,lenchrom,individuals.chrom,sizepop,i,maxgen,bound);71.        72.        % 计算适应度 73.        for j=1:sizepop74.            x=individuals.chrom(j,:); %解码75.            individuals.fitness(j)=fun(x,inputnum,hiddennum,outputnum,net,inputn,outputn);   76.        end77.        78.      %找到最小和最大适应度的染色体及它们在种群中的位置79.        [newbestfitness,newbestindex]=min(individuals.fitness);80.        [worestfitness,worestindex]=max(individuals.fitness);81.        % 代替上一次进化中最好的染色体82.        if bestfitness>newbestfitness83.            bestfitness=newbestfitness;84.            bestchrom=individuals.chrom(newbestindex,:);85.        end86.        individuals.chrom(worestindex,:)=bestchrom;87.        individuals.fitness(worestindex)=bestfitness;88.        89.        avgfitness=sum(individuals.fitness)/sizepop;90.        91.        trace=[trace;avgfitness bestfitness]; %记录每一代进化中最好的适应度和平均适应度92.     93.    end94.    %% 遗传算法结果分析 95.     figure(1)96.    [r c]=size(trace);97.    plot([1:r]',trace(:,2),'b--');98.    title(['适应度曲线  ' '终止代数=' num2str(maxgen)]);99.    xlabel('进化代数');ylabel('适应度');100.    legend('平均适应度','最佳适应度');101.    disp('适应度                   变量');102.    x=bestchrom;103.    104.    %% 把最优初始阀值权值赋予网络预测105.    % %用遗传算法优化的BP网络进行值预测106.    w1=x(1:inputnum*hiddennum);107.    B1=x(inputnum*hiddennum+1:inputnum*hiddennum+hiddennum);108.    w2=x(inputnum*hiddennum+hiddennum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum);109.    B2=x(inputnum*hiddennum+hiddennum+hiddennum*outputnum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum+outputnum);110.    111.    net.iw{1,1}=reshape(w1,hiddennum,inputnum);112.    net.lw{2,1}=reshape(w2,outputnum,hiddennum);113.    net.b{1}=reshape(B1,hiddennum,1);114.    net.b{2}=B2;115.    116.    %% BP网络训练117.    %网络进化参数118.    net.trainParam.epochs=100;119.    net.trainParam.lr=0.1;120.    %net.trainParam.goal=0.00001;121.    122.    %网络训练123.    [net,per2]=train(net,inputn,outputn);124.    125.    %% BP网络预测126.    %数据归一化127.    inputn_test=mapminmax('apply',input_test,inputps);128.    an=sim(net,inputn_test);129.    test_simu=mapminmax('reverse',an,outputps);130.    error=test_simu-output_test;

    使用时将程序视为输入输出的系统,需要根据需要修改使用 save data 生成的 .mat 数据库文件,然后再调用数据,确定传递函数等就可以观察到结果。

    神经网络的初始化数据:

    load data input output%节点个数inputnum=2;hiddennum=5;outputnum=1;%训练数据和预测数据input_train=input(1:1900,:)’;input_test=input(1901:2000,:)’;output_train=output(1:1900)’;output_test=output(1901:2000)’;遗传算法的初始化数据:maxgen=10; %进化代数,即迭代次数sizepop=10; %种群规模pcross=[0.3]; %交叉概率选择,0和1之间pmutation=[0.1]; %变异概率选择,0和1之间

    本文首发于GitChat,未经授权不得转载,转载需与GitChat联系。

    阅读全文: http://gitbook.cn/gitchat/activity/5b600a5b5ecd332382c04076

    您还可以下载 CSDN 旗下精品原创内容社区 GitChat App ,阅读更多 GitChat 专享技术内容哦。

    FtooAtPSkEJwnW-9xkCLqSTRpBKX

    展开全文
  • 充分利用BP神经网络的非线性拟合能力,将遗传算法与其相结合,避免BP网络陷入局部最优.利用编写的程序确定隐含层节点数,相比以往经验公式取值更具优势.最后在任家庄煤矿成功应用.研究结果表明:利用粗糙集与改进神经...
  • 神经网络

    2019-04-23 10:10:34
    神经网络 参考资料: TENSORFLOW系列专题 TensorFlow 从入门到精通 深度学习的概念是从人工神经网络...对于多层感知器,我们使用BP算法进行模型的训练,但是我们发现BP算法有着收敛速度慢,以及容易陷入局部最优...

    神经网络

    参考资料:

    深度学习发展简史

    深度学习的概念是从人工神经网络的研究中发展而来的,早期的感知器模型只能解决简单的线性分类问题,后来发现通过增加网络的层数可以解决类似于“异或问题”的线性不可分问题,这种多层的神经网络又被称为多层感知器。对于多层感知器,我们使用BP算法进行模型的训练,但是我们发现BP算法有着收敛速度慢,以及容易陷入局部最优等缺点,导致BP算法无法很好的训练多层感知器。另外,当时使用的激活函数也存在着梯度消失的问题,这使得人工神经网络的发展几乎陷入了停滞状态。为了让多层神经网络能够训练,学者们探索了很多的改进方案,直到2006年Hinton等人基于深度置信网络(DBN)提出了非监督贪心逐层训练算法,才让这一问题的解决有了希望,而深度学习的浪潮也由此掀起。

    前馈神经网络综述

    本节内容主要包括四个部分,第一部分我们介绍一下神经网络的基本结构,从基本的感知器模型到多层的神经网络结构;第二部分介绍神经网络中常用的激活函数;第三部分介绍损失函数和输出单元的选择;第四部分介绍神经网络模型中的一个重要的基础知识——反向传播算法。

    (1)神经网络的基本结构

    1. 感知机模型

    感知器(Perceptron)是一种最简单的人工神经网络,也可以称之为单层神经网络,如图1所示。感知器是由Frank Rosenblatt在1957年提出来的,它的结构很简单,输入是一个实数值的向量,输出只有两个值:1或-1,是一种两类线性分类模型。

    图1 感知器模型

    如上图所示,感知器对于输入的向量先进行了一个加权求和的操作,得到一个中间值,假设该值为Z,则有:

    接着再经过一个激活函数得到最终的输出,该激活函数是一个符号函数:

    公式1中的b可以看做是一个阈值(我们通常称之为偏置项),当输入向量的加权和大于该阈值时(两者之和),感知器的输出为1,否则输出为-1。

    2. 多层神经网络

    感知器只能解决线性可分的问题,以逻辑运算为例:

    图2 逻辑运算

    感知器可以解决逻辑“与”和逻辑“或”的问题,但是无法解决“异或”问题,因为“异或”运算的结果无法使用一条直线来划分。为了解决线性不可分的问题,我们需要引入多层神经网络,理论上,多层神经网络可以拟合任意的函数。

    与单层神经网络相比,多层神经网络除了有输入层和输出层以外,还至少需要有一个隐藏层,如图3所示是含有一个隐藏层的两层神经网络:

    图3 两层神经网络

    (2)激活函数

    线性模型在处理非线性问题时往往手足无措,这时我们需要引入激活函数来解决线性不可分问题。激活函数(Activation function),又名激励函数,往往存在于神经网络的输入层和输出层之间,作用是给神经网络中增加一些非线性因素,使得神经网络能够解决更加复杂的问题,同时也增强了神经网络的表达能力和学习能力。另外我们使用基于梯度的方式来训练模型,因此激活函数也必须是连续可导的。

    常用的激活函数有Sigmoid函数、双曲正切激活函数(tanh)、修正线性单元(ReLU)等。

    1. Logistic函数

    Logistic函数(又称为sigmoid函数)的数学表达式和函数图像如图4所示:

    图4 Logistic函数表达式及函数图像

    Logistic函数在定义域上单调递增,值域为[0,1],越靠近两端,函数值的变化越平缓。因为Logistic函数简单易用,以前的神经网络经常使用它作为激活函数,但是Sigmoid函数也有两个很大的缺点:首先是Sigmoid函数会造成梯度消失问题,从图像中我们也可以得知,当输入特别大或是特别小时,神经元的梯度几乎接近于0,这就导致神经网络不收敛,模型的参数不会更新,训练过程将变得非常困难。另一方面,Sigmoid函数的输出不是以0为均值的,导致传入下一层神经网络的输入是非0的。这就导致一个后果:若Sigmoid函数的输出全部为正数,那么传入下一层神经网络的值永远大于0,这时参数无论怎么更新梯度都为正。正是基于上述的缺点,Sigmoid函数近年来的使用频率也在渐渐减弱。

    2. Tanh函数

    Tanh函数(双曲正切激活函数)的数学表达式和函数图像如图5所示:

    图5 Tanh函数表达式及函数图像

    Tanh函数是Sigmoid函数的变形,其值域为[-1,1],且Tanh函数的输出是以为0均值的,这就一定程度上解决了上述Sigmoid函数的第二个缺点,所以在实际应用上,Tanh函数要优于Logistic函数,但是Tanh函数也同样面临着在其大部分定义域内都饱和的问题。

    3. ReLu函数

    ReLU函数(又称修正线性单元或整流线性单元)是目前最受欢迎,也是使用最多的激活函数,其数学表达式和函数图像如图6所示:

    图6 ReLU函数表达式及函数图像

    ReLU激活函数的收敛速度相较于Logistic函数和Tanh函数要快很多,ReLU函数在轴左侧的值恒为零,这使得网络具有一定的稀疏性,从而减小参数之间的依存关系,缓解过拟合的问题,并且ReLU函数在轴右侧的部分导数是一个常数值1,因此其不存在梯度消失的问题。

    但是ReLU函数也有一些缺点,例如ReLU的强制稀疏处理虽然可以缓解过拟合问题,但是也可能产生特征屏蔽过多,导致模型无法学习到有效特征的问题。还有训练的时候不适合大梯度的输入数据,因为在参数更新之后,ReLU的神经元不会再任何数据节点被激活,这就会导致梯度永远为0。比如:输入的数据小于0时,梯度就会为0,这就导致了负的梯度被置0,而且今后也可能不会被任何数据所激活,也就是说ReLU的神经元“坏死”了。所以针对ReLU函数上述的缺点,又出现了带泄露的ReLU(Leaky ReLU)和带参数的ReLU(Parametric ReLU)。

    Leaky ReLU是ReLU激活函数的变形,主要是针对ReLU函数中神经元容易坏死的缺陷,将原点左侧小于0的部分,赋予一个很小的斜率。其效果通常要好于ReLU激活函数,但实践中使用的频率并没有那么高。数据公式为:f(x) = max(0, x) + γmin(0, x)。通常,γ是一个很小的常数,如:0.01。

    Parametric ReLU是ReLU激活函数的另一种变形,和Leaky ReLU函数一样是非饱和函数,解决了坏死难题。不同之处在于其在函数中引入一个可学习的参数,往往不同的神经元有不同的参数,所以第i个神经元的数学表达式为:f(x) = max(0, x) + γi min(0, x)。当γi 取0时,便可以视为ReLU函数,取很小的常数时,可视为Leaky ReLU函数。相对而言,Parametric ReLU激活函数的使用频率也不是很高。

    上述两种ReLU激活函数的变形Leaky ReLU、Parametric ReLU函数图如图7所示:

    图7 Leaky ReLU/Parametric ReLU函数图像

    (3)损失函数和输出单元

    损失函数(Loss Function)又称为代价函数(Cost Function),它是神经网络设计中的一个重要部分。损失函数用来表征模型的预测值与真实类标之间的误差,深度学习模型的训练就是使用基于梯度的方法最小化损失函数的过程。损失函数值越小,说明模型的预测值就越接近真实值,模型的健壮性也就越好。损失函数的选择与输出单元的选择也有着密切的关系。

    1. 损失函数的选择

    1.1 均方误差损失函数

    均方误差(Mean Squared Error,MSE)是一个较为常用的损失函数,我们用预测值和实际值之间的距离(即误差)来衡量模型的好坏,为了保证一致性,我们通常使用距离的平方。在深度学习算法中,我们使用基于梯度的方式来训练参数,每次将一个批次的数据输入到模型中,并得到这批数据的预测结果,再利用这批预测结果和实际值之间的距离更新网络的参数。均方误差损失函数将这一批数据的误差的期望作为最终的误差值,均方误差的公式如下:

    上式中yk为样本数据的实际值,^yk为模型的预测值。为了简化计算,我们一般会在均方误差的基础上乘以1/2,作为最终的损失函数:

    1.2 交叉熵损失函数

    交叉熵(Cross Entropy)损失函数使用训练数据的真实类标与模型预测值之间的交叉熵作为损失函数,相较于均方误差损失函数其更受欢迎。假设我们使用均方误差这类二次函数作为代价函数,更新神经网络参数的时候,误差项中会包含激活函数的偏导。在前面介绍激活函数的时候我们有介绍,Logistic等激活函数很容易饱和,这会使得参数的更新缓慢,甚至无法更新。交叉熵损失函数求导不会引入激活函数的导数,因此可以很好地避免这一问题,交叉熵的定义如下:

    上式中为p样本数据的真实分布,q为模型预测结果的分布。以二分类问题为例,交叉熵损失函数的形式如下:

    上式中为y真实值,^y为预测值。对于多分类问题,我们对每一个类别的预测结果计算交叉熵后求和即可。

    1.3 Hinge损失函数(hinge loss function)

    Hinge损失函数通常适用于二分类的场景中,可以用来解决间隔最大化的问题,常应用于著名的SVM算法中。其数学公式为:

    其中在上式中,t是目标值{-1,+1},y为预测值的输出,取值范围在(-1,1)之间。

    1.4 对数损失函数(Log Loss)

    对数损失函数也是常见的一种损失函数,常用于逻辑回归问题中,其标准形式为:

    上式中,y为已知分类的类别,x为样本值,我们需要让概率p(y|x)达到最大值,也就是说我们要求一个参数值,使得输出的目前这组数据的概率值最大。因为概率P(Y|X)的取值范围为[0,1],log(x)函数在区间[0,1]的取值为负数,所以为了保证损失值为正数要在log函数前加负号。

    2. 输出单元的选择

    2.1 线性单元

    线性输出单元常用于回归问题,当输出层采用线性单元时,收到上一层的输出后,输出层输出一个向量。线性单元的一个优势是其不存在饱和的问题,因此很适合采用基于梯度的优化算法。

    2.2 Sigmoid单元

    Sigmoid输出单元常用于二分类问题,Sigmoid单元是在线性单元的基础上,增加了一个阈值来限制其有效概率,使其被约束在区间之中,线性输出单元的定义为:

    上式中是Sigmoid函数的符号表示,其数学表达式在感知机模型小节中有介绍。

    2.3 Softmax****单元

    Softmax输出单元适用于多分类问题,可以将其看作是Sigmoid函数的扩展。对于Sigmoid输出单元的输出,我们可以认为其值为模型预测样本为某一类的概率,而Softmax则需要输出多个值,输出值的个数对应分类问题的类别数。Softmax函数的形式如下:

    我们以一个简单的图示来解释Softmax函数的作用,如图8所示。原始输出层的输出为,,,增加了Softmax层后,最终的输出为:

    上式中、和的值可以看做是分类器预测的结果,值的大小代表分类器认为该样本属于该类别的概率,、和的和为1。

    图8 Softmax输出单元

    需要注意的是,Softmax层的输入和输出的维度是一样的,如果不一致,可以通过在Softmax层的前面添加一层全连接层来解决问题。

    (4)BP算法原理

    反向传播算法(Backpropagation Algorithm,简称BP算法)是深度学习的重要思想基础,对于初学者来说也是必须要掌握的基础知识。

    我们使用一个如图9所示的神经网络,该图所示是一个三层神经网络,两层隐藏层和一层输出层,输入层有两个神经元,接收输入样本 , ^y为网络的输出。假设我们使用这个神经网络来解决二分类问题,我们给这个网络一个输入样本 ,通过前向运算得到输出 。输出值^y的值域为[0, 1] ,例如^y 的值越接近0,代表该样本是“0”类的可能性越大,反之是“1”类的可能性越大。

    图9 一个三层神经网络

    1.前馈计算的过程

    为了理解神经网络的运算过程,我们需要先搞清楚前馈计算,即数据沿着神经网络前向传播的计算过程,以图9所示的网络为例:

    输入的样本为:

    第一层网络的参数为:

    第二层网络的参数为:

    第三层网络的参数为:

    • 第一层隐藏层的计算

    图10 计算第一层隐藏层

    第一层隐藏层有三个神经元:neu1 、neu2 和neu3 。该层的输入为:

    以 neu1神经元为例,则其输入为:

    同理有:

    假设我们选择函数 f(x) 作为该层的激活函数(图9中的激活函数都标了一个下标,一般情况下,同一层的激活函数都是一样的,不同层可以选择不同的激活函数),那么该层的输出为: f1(z1)、f2(z2) 和f3(z3) 。

    • 第二层隐藏层的计算

    图11 计算第二层隐藏层

    第二层隐藏层有两个神经元:neu4 和neu5 。该层的输入为:

    即第二层的输入是第一层的输出乘以第二层的权重,再加上第二层的偏置。因此得到neu4 和neu5 的输入分别为:

    该层的输出分别为: f4(z4)和f5(z5) 。

    • 输出层的计算

    图12 计算输出层

    输出层只有一个神经元:neu6 。该层的输入为:

    即:

    因为该网络要解决的是一个二分类问题,所以输出层的激活函数也可以使用一个Sigmoid型函数,神经网络最后的输出为: f6(z6)。

    2. 反向传播的计算

    上一小节里我们已经了解了数据沿着神经网络前向传播的过程,这一节我们来介绍更重要的反向传播的计算过程。假设我们使用随机梯度下降的方式来学习神经网络的参数,损失函数定义为L(y,^y) ,其中 y是该样本的真实类标。使用梯度下降进行参数的学习,我们必须计算出损失函数关于神经网络中各层参数(权重w和偏置b)的偏导数。

    3. BP算法流程

    下面是基于随机梯度下降更新参数的反向传播算法:

    输入: 训练集:D={(xi,yi)}, i=1,2,….,N

    学习率:γ

    训练回合数(epoch):T

    初始化网络各层参数w(t) 和b(t)

    for t=1 …T do

    打乱训练集中样本的顺序

    for i=1… N do

    (1)获取一个训练样本,前馈计算每一层的输入 和输出

    (2)利用公式*反向传播计算每一层的误差项

    (3)利用公式和公式*计算每一层参数的导数

    (4)更新参数:

    4. 图解BP算法

    我们依然使用如图9所示的简单的神经网络,其中所有参数的初始值如下:

    输入的样本为(假设其真实类标为“1”):

    第一层网络的参数为:

    第二层网络的参数为:

    第三层网络的参数为:

    4.1 前向传播

    我们首先初始化神经网络的参数,计算第一层神经元:

    4.2 误差反向传播

    接着计算第二层隐藏层的误差项,根据误差项的计算公式有:

    最后是计算第一层隐藏层的误差项:

    4.3 更新参数

    上一小节中我们已经计算出了每一层的误差项,现在我们要利用每一层的误差项和梯度来更新每一层的参数,权重W和偏置b的更新公式如下:

    通常权重W的更新会加上一个正则化项来避免过拟合,这里为了简化计算,我们省去了正则化项。上式中的 a 是学习率,我们设其值为0.1。参数更新的计算相对简单,每一层的计算方式都相同,因此本文仅演示第一层隐藏层的参数更新:

    卷积神经网络综述

    卷积介绍

    我们尝试用一个简单的神经网络,来探讨如何解决这个问题。假设有4个输入节点和4个隐藏层节点的神经网络,如图所示:

    图1 全连接神经网络

    每一个输入节点都要和隐藏层的 4 个节点连接,每一个连接需要一个权重参数 w:

    图2 一个输入节点向下一层传播

    一共有 4 个输入节点,,所以一共需要 4*4=16个参数。

    相应的每一个隐藏层节点,都会接收所有输入层节点:

    图3 每个隐藏层节点接收所有输入层节点输入

    这是一个简化版的模型,例如手写数据集 MNIST 28 * 28 的图片,输入节点有 784 个,假如也只要一个隐藏层有 784 个节点,那么参数的个数都会是:784 * 784=614656,很明显参数的个数随着输入维度指数级增长。

    因为神经网络中的参数过多,会造成训练中的困难,所以降低神经网络中参数的规模,是图像处理问题中的一个重要问题。

    有两个思路可以进行尝试:

    1.隐藏层的节点并不需要连接所有输入层节点,而只需要连接部分输入层。

    如图所示:

    图4 改为局部连接之后的网络结构

    每个隐藏层节点,只接受两个输入层节点的输入,那么,这个网络只需要 3 * 2 =6个连接。使用局部连接之后,单个输出层节点虽然没有连接到所有的隐藏层节点,但是隐藏层汇总之后所有的输出节点的值都对网络有影响。

    2.局部连接的权重参数,如果可以共享,那么网络中参数规模又会明显的下降。如果把局部连接的权重参数当做是一个特征提取器的话,可以尝试将这个特征提取器用在其他的地方。

    那么这个网络最后只需要 2 个参数,就可以完成输入层节点和隐藏层节点的连接。

    这两个思路就是卷积神经网络中的稀疏交互和权值共享。

    稀疏交互

    在神经网络中,稀疏交互就是下一层节点只和上一层中的部分节点进行连接的操作。稀疏交互可以显著的降低神经网络中参数的数量。

    左边是全连接方式,隐藏节点都需要所有的输入;右边是稀疏交互,隐藏层节点只接受一个区域内的节点输入。

    ./images/5-5.png

    稀疏交互的实现

    以 MNIST 数据集为例,来实现稀疏交互,并输出结果对应的图片。

    MNIST 原始图片:

    ./images/Figure_1.png

    为了进行局部连接,有两个重要的参数需要选择:

    1.局部区域的大小

    局部区域的大小,首先以 5 * 5 的局部区域为例:

    2.局部特征的抽取次数

    针对局部区域可以进行多次特征抽取,可以选择局部特征抽取的次数,首先以抽取 5 次为例。

    3.步长

    在确定局部区域大小之后,可以平滑的每次移动一个像素,也可以间隔 N 个像素进行移动。
    如图:

    ./images/5-10.jpg

    也可以使用不同的特征提取器对同一片区域,进行多次特征提取,如图所示:

    4.边缘填充

    在进行一次局部连接的过程中,如果不进行边缘填充,图像的维度将会发生变化,如图所示:

    4 * 4 的图像,进行了 3 * 3 的局部连接,维度发生了变化。

    ./images/5-11.png

    对于边缘的两种处理方法:

    权值共享

    降低网络中参数的个数,还有一个方法就是共享参数。每一组参数都可以认为是一个特征提取器,即使图像有一定的偏移,还是可以将相应的特征用同一组参数提取出来。

    池化

    除了之前的两种方式,在数据量很大,类比现实生活中事情纷繁复杂的时候,我们总是想抓住重点,在图像中,可以在一个区域选取一个重要的点。

    一般是选择值最大的点,作为这一个区域的代表:

    如图所示:


    这个池化选取的是 2 * 2 的区域,留下值最大点,步长为 2。原来 4 * 4 的图片矩阵池化之后变成了 2 * 2 的图片矩阵。

    RNN循环神经网络综述

    前馈神经网络不考虑数据之间的关联性,网络的输出只和当前时刻网络的输入相关。然而在解决很多实际问题的时候我们发现,现实问题中存在着很多序列型的数据,例如文本、语音以及视频等。这些序列型的数据往往都是具有时序上的关联性的,既某一时刻网络的输出除了与当前时刻的输入相关之外,还与之前某一时刻或某几个时刻的输出相关。而前馈神经网络并不能处理好这种关联性,因为它没有记忆能力,所以前面时刻的输出不能传递到后面的时刻。

    此外,我们在做语音识别或机器翻译的时候,输入和输出的数据都是不定长的,而前馈神经网络的输入和输出的数据格式都是固定的,无法改变。因此,需要有一种能力更强的模型来解决这些问题。

    在过去的几年里,循环神经网络的实力已经得到了很好的证明,在许多序列问题中,例如文本处理、语音识别以及机器翻译等,循环神经网络都取得了显著的成绩。循环神经网络也正被越来越多的应用到其它领域。

    在本节中,我们将会从最简单的循环神经网络开始介绍,通过实例掌握循环神经网络是如何解决序列化数据的,以及循环神经网络前向计算和参数优化的过程及方法。在此基础上我们会介绍几种循环神经网络的常用结构,即双向循环神经网络、深度循环神经网络以及递归神经网络。

    此外,我们还会学习一类结构更为复杂的循环神经网络——门控循环神经网络,包括长短期记忆网络(LSTM)和门控制循环单元(GRU),这也是目前最常使用的两种循环神经网络结构。最后我们还会介绍一种注意力模型:Attention-based model,这是近两年来的研究热点。

    1. 简单循环神经网络

    简单循环网络(simple recurrent networks,简称SRN)又称为Elman network,是由Jeff Elman在1990年提出来的。Elman在Jordan network(1986)的基础上进行了创新,并且简化了它的结构,最终提出了Elman network。Jordan network和Elman network的网络结构如下图所示。

    图1 Jordan network(左)和Elman network(右)

    从图1中可以很直观的看出,两种网络结构最主要的区别在于记忆单元中保存的内容不同。Jordan network的记忆单元中保存的是整个网络最终的输出,而Elman network的记忆单元只保存中间的循环层,所以如果是基于Elman network的深层循环神经网络,那么每一个循环的中间层都会有一个相应的记忆单元。

    Jordan network和Elman network都可以扩展应用到深度学习中来,但由于Elman network的结构更易于扩展(Elman network的每一个循环层都是相互独立的,因此网络结构的设计可以更加灵活。另外,当Jordan network的输出层与循环层的维度不一致时还需要额外的调整,而Elman network则不存在该问题。),因此当前主流的循环神经网络都是基于Elman network的,例如我们后面会介绍的LSTM等。所以,通常我们所说的循环神经网络(RNN),默认指的就是Elman network结构的循环神经网络。本书中所提到的循环神经网络,如果没有特别注明,均指Elman network结构的循环神经网络。

    2. RNN的基本结构

    循环神经网络的基本结构如下图所示(注意:为了清晰,图中没有画出所有的连接线。):

    图2 循环神经网络的基本结构

    关于循环神经网络的结构有很多种不同的图形化描述,但是其所表达的含义都与图2一致。将循环神经网络的结构与一般的全连接神经网络比较,我们会发现循环神经网络只是多了一个记忆单元,而这个记忆单元就是循环神经网络的关键所在。

    从图2我们可以看到,循环神经网络的记忆单元会保存t时刻时循环层(既图2中的隐藏层)的状态,并在t时刻,将记忆单元的内容和t-1时刻的输入一起给到循环层。为了更直观的表示清楚,我们将循环神经网络按时间展开,如图3所示。

    图3 循环神经网络及其按时间展开后的效果图

    左边部分是一个简化的循环神经网络示意图,右边部分是将整个网络按时间展开后的效果。在左边部分中,x是神经网络的输入,U是输入层到隐藏层之间的权重矩阵,W是记忆单元到隐藏层之间的权重矩阵,V是隐藏层到输出层之间的权重矩阵,s是隐藏层的输出,同时也是要保存到记忆单元中,并与下一时刻的x一起作为输入,o是神经网络的输出。

    从右边的展开部分可以更清楚的看到,RNN每个时刻隐藏层的输出都会传递给下一时刻,因此每个时刻的网络都会保留一定的来自之前时刻的历史信息,并结合当前时刻的网络状态一并再传给下一时刻。

    理论上来说,RNN是可以记忆任意长度序列的信息的,即RNN的记忆单元中可以保存此前很长时刻网络的状态,但是在实际的使用中我们发现,RNN的记忆能力总是很有限,它通常只能记住最近几个时刻的网络状态。

    3. RNN的运算过程和参数更新

    3.1 RNN的前向运算

    在一个全连接的循环神经网络中,假设隐藏层只有一层。在时刻神经网络接收到一个输入,则隐藏层的输出为:

    上式中,f(x)函数是隐藏层的激活函数,在TensorFlow中默认是tanh函数。参数U和W分别是输入层到隐藏层之间的权重矩阵和记忆单元到隐藏层之间的权重矩阵,参数b是偏置项。在神经网络刚开始训练的时候,记忆单元中没有上一个时刻的网络状态,这时候ht-1就是一个初始值。

    在得到隐藏层的输出后,神经网络的输出为:

    上式中,函数g是输出层的激活函数,当我们在做分类问题的时候,函数g通常选为Softmax函数。参数V是隐藏层到输出层的参数矩阵,参数b是偏置项。

    我们先看看TensorFlow源码中关于RNN隐藏层部分的计算。这部分代码在TensorFlow源码中的位置是:https://github.com/tensorflow/tensorflow/tree/master/tensorflow/python/ops/rnn_cell_impl.py。

    在rnn_cell_impl.py文件中定义了一个抽象类RNNCell,其它实现RNN的类都会继承这个类,例如BasicRNNCell、BasicLSTMCell以及GRUCell等。我们以BasicRNNCell类为例,所有继承了RNNCell的类都需要实现一个call方法,BasicRNNCell类中的call方法的实现如下:

    def call(self, inputs, state):  
       """Most basic RNN: output = new_state  
                                 = act(W * input + U * state + B)."""  
       gate_inputs = math_ops.matmul(  
           array_ops.concat([inputs, state], 1), self._kernel)  
       gate_inputs = nn_ops.bias_add(gate_inputs, self._bias)  
       output = self._activation(gate_inputs)  
       return output, output
    

    从上面的TensorFlow源码里可以看到,TensorFlow隐藏层的计算结果即是该层的输出,同时也作为当前时刻的状态,作为下一时刻的输入。第2、3行的注释说明了“call”方法的功能:output = new_state = act(W * input + U * state + B),其实就是实现了我们前面给出的公式6.1。第5行代码中的“self._kernel”是权重矩阵,第6行代码中的“self._bias”是偏置项。

    这里有一个地方需要注意一下,这段代码在实现 W * input + U * state + B 时,没有分别计算W * input和U * state,然后再相加,而是先用“concat”方法,将前一时刻的状态“state”和当前的输入“inputs”进行拼接,然后用拼接后的矩阵和拼接后的权重矩阵相乘。可能有些读者刚开始看到的时候不太能理解,其实效果是一样的,我们看下面这个例子:

    我们有四个矩阵:a、b、c和d:

    假设我们想要计算,则有:

    如果我们把矩阵a和b、c和d先分别拼接到一起,得到e和f两个矩阵:

    再来计算,会得到同样的结果:

    下面我们用一段代码实现循环神经网络中完整的前向计算过程。

    import numpy as np  
    
    # 输入数据,总共三个time step  
    dataset = np.array([[1, 2], [2, 3], [3, 4]])  
    
    # 初始化相关参数  
    state = [0.0, 0.0]            # 记忆单元  
    
    np.random.seed(2)          # 给定随机数种子,每次产生相同的随机数  
    W_h = np.random.rand(4, 2)  # 隐藏层权重矩阵  
    b_h = np.random.rand(2)     # 隐藏层偏置项  
    
    np.random.seed(3)  
    W_o = np.random.rand(2)    # 输出层权重矩阵  
    b_o = np.random.rand()      # 输出层偏置项  
    
    for i in range(len(dataset)):  
      # 将前一时刻的状态和当前的输入拼接  
      value = np.append(state, dataset[i])  
    
      # 隐藏层  
      h_in = np.dot(value, W_h) + b_h  # 隐藏层的输入  
      h_out = np.tanh(h_in)           # 隐藏层的输出  
      state = h_out                  # 保存当前状态  
    
      # 输出层  
      y_in = np.dot(h_out, W_o) + b_o  # 输出层的输入  
      y_out = np.tanh(y_in)           # 输出层的输出(即最终神经网络的输出)  
    
      print(y_out)
    

    上面代码里所使用的RNN结构如下:

    图4 代码中使用的RNN网络结构

    在上面的示例代码中,我们用了一个如图4所示的简单循环神经网络。该网络结构输入层有两个单元,隐藏层有两个神经元,输出层一个神经元,所有的激活函数均为tanh函数。在第四行代码中我们定义了输入数据,总共三个time-step,每个time-step处理一个输入。我们将程序运行过程中各个参数以及输入和输出的值以表格的形式展示如下(读者可以使用下表的数据验算一遍RNN的前向运算,以加深印象):

    3.2 RNN的参数更新

    循环神经网络中参数的更新主要有两种方法:随时间反向传播(backpropagation through time,BPTT)和实时循环学习(real-time recurrent learning,RTRL)。这两种算法都是基于梯度下降,不同的是BPTT算法是通过反向传播的方式来更新梯度,而RTRL算法则是使用前向传播的方式来更新梯度。目前,在RNN的训练中,BPTT是最常用的参数更新的算法。

    BPTT算法和我们在前馈神经网络上使用的BP算法本质上没有任何区别,只是RNN中的参数存在时间上的共享,因此RNN中的参数在求梯度的时候,存在沿着时间的反向传播。所以RNN中参数的梯度,是按时间展开后各级参数梯度的总和。

    4. 多层循环神经网络(深度循环神经网络)

    多层循环神经网络是最容易想到的一种变种结构,它的结构也很简单,就是在基本的循环神经网络的基础上增加了隐藏层的数量。

    图5 多层循环神经网络结构

    多层循环神经网络按时间展开后,每一层的参数和基本的循环神经网络结构一样,参数共享,而不同层的参数则一般不会共享(可以类比CNN的网络结构)。和基本结构的循环神经网络相比,多层循环神经网络的泛化能力更强,不过训练的时间复杂度和空间复杂度也更高。

    5. 双向循环神经网络

    无论是简单循环神经网络还是深度循环神经网络,网络中的状态都是随着时间向后传播的,然而现实中的许多问题,并不都是这种单向的时序关系。例如在做词性标注的时候,我们需要结合这个词前后相邻的几个词才能对该词的词性做出判断,这种情况就需要双向循环神经网络来解决问题。

    图6 双向循环神经网络结构

    双向循环神经网络可以简单的看成是两个单向循环神经网络的叠加,按时间展开后,一个是从左到右,一个是从右到左。双向循环神经网络的计算与单向的循环神经网络类似,只是每个时刻的输出由上下两个循环神经网络的输出共同决定。双向循环神经网络也可以在深度上进行叠加:

    图7 深度双向循环神经网络结构

    6. 递归神经网络

    递归神经网络(recursive neural network,RNN)是循环神经网络的又一个变种结构,看它们的名称缩写,很容易将两者混淆(通常我们说的RNN均特指recurrent neural network,同时也不建议将recurrent neural network说成是递归神经网络。一般默认递归神经网络指的是recursive neural network,而循环神经网络指的是recurrent neural network)。我们前面所介绍的循环神经网络是时间上的递归神经网络,而这里所说的递归神经网络是结构上的递归。递归神经网络相较于循环神经网络有它一定的优势,当然这个优势只适用于某些特定场合。目前递归神经网络在自然语言处理和计算机视觉领域已经有所应用,并获得了一定的成功,但是由于其对输入数据的要求相对循环神经网络更为苛刻,因此并没有被广泛的应用。

    图8 递归神经网络结构示意图

    7. 长期依赖问题及其优化

    7.1 长期依赖问题

    什么是长期依赖?

    我们知道循环神经网络具有记忆能力,凭着它的记忆能力,能够较好的解决一般的序列问题,这些序列问题的数据内部基本上都存在着一定的依赖性,例如我们在前面提到过的词性标注的问题。在有些现实问题中,数据间的依赖都是局部的、较短时间间隔的依赖。还是以词性标注为例,判断一个词是动词还是名词,或者是形容词之类,我们往往只需要看一下这个词前后的两个或多个词就可以做出判断,这种依赖关系在时间上的跨度很小。

    图9 时间跨度较小的依赖关系示意图

    如上图所示,时刻网络的输出(上图中到是隐藏层的输出)除了与当前时刻的输入相关之外,还受到和时刻网络的状态影响。像这种依赖关系在时间上的跨度较小的情况下,RNN基本可以较好地解决,但如果出现了像下图所示的依赖情况,就会出现长期依赖问题:梯度消失和梯度爆炸

    图10 时间跨度较大的依赖关系示意图

    什么是梯度消失和梯度爆炸?

    图11是一个较为形象的描述,在深层的神经网络中,由于多个权重矩阵的相乘,会出现很多如图所示的陡峭区域,当然也有可能会出现很多非常平坦的区域。在这些陡峭的地方,Loss函数的倒数非常大,导致最终的梯度也很大,对参数进行更新后可能会导致参数的取值超出有效的取值范围,这种情况称之为梯度爆炸。而在那些非常平坦的地方,Loss的变化很小,这个时候梯度的值也会很小(可能趋近于0),导致参数的更新非常缓慢,甚至更新的方向都不明确,这种情况称之为梯度消失。长期依赖问题的存在会导致循环神经网络没有办法学习到时间跨度较长的依赖关系。

    图11 导致梯度爆炸的情况

    正如上面所说,长期依赖问题普遍存在于层数较深的神经网络之中,不仅存在于循环神经网络中,在深层的前馈神经网络中也存在这一问题,但由于循环神经网络中循环结构的存在,导致这一问题尤为突出,而在一般的前馈神经网络中,这一问题其实并不严重。

    值得注意的是,在介绍激活函数的时候我们其实已经提到过梯度消失的问题,这是由于Sigmoid型的函数在其函数图像两端的倒数趋近于0,使得在使用BP算法进行参数更新的时候会出现梯度趋近于0的情况。针对这种情况导致的梯度消失的问题,一种有效的方法是使用ReLU激活函数。但是由于本节所介绍的梯度消失的问题并不是由激活函数引起的,因此使用ReLU激活函数也无法解决问题。下面我们来看一个简单的例子。

    图12 参数W在循环神经网络中随时间传递的示意图

    如上图所示,我们定义一个简化的循环神经网络,该网络中的所有激活函数均为线性的,除了在每个时间步上共享的参数W以外,其它的权重矩阵均设为1,偏置项均设为0。假设输入的序列中除了的值为1以外,其它输入的值均为0,则根据之前讲解RNN的原理内容,可以知道:

    最终可以得到,神经网络的输出是关于权重矩阵W的指数函数。当W的值大于1时,随着n的增加,神经网络最终输出的值也成指数级增长,而当W的值小于1时,随着n的值增加,神经网络最终的输出则会非常小。这两种结果分别是导致梯度爆炸和梯度消失的根本原因。

    从上面的例子可以看到,循环神经网络中梯度消失和梯度爆炸问题产生的根本原因,是由于参数共享导致的。

    7.2 长期依赖问题的优化

    对于梯度爆炸的问题,一般来说比较容易解决。我们可以用一个比较简单的方法叫做“梯度截断”,“梯度截断”的思路是设定一个阈值,当求得的梯度大于这个阈值的时候,就使用某种方法来进行干涉,从而减小梯度的变化。还有一种方法是给相关的参数添加正则化项,使得梯度处在一个较小的变化范围内。

    梯度消失是循环神经网络面临的最大问题,相较于梯度爆炸问题要更难解决。目前最有效的方法就是在模型上做一些改变,这就是我们下一节要介绍的门控循环神经网络。

    8. 门控循环神经网络

    门控循环神经网络在简单循环神经网络的基础上对网络的结构做了调整,加入了门控机制,用来控制神经网络中信息的传递。门控机制可以用来控制记忆单元中的信息有多少需要保留,有多少需要丢弃,新的状态信息又有多少需要保存到记忆单元中等。这使得门控循环神经网络可以学习跨度相对较长的依赖关系,而不会出现梯度消失和梯度爆炸的问题。如果从数学的角度来理解,一般结构的循环神经网络中,网络的状态和之间是非线性的关系,并且参数W在每个时间步共享,这是导致梯度爆炸和梯度消失的根本原因。门控循环神经网络解决问题的方法就是在状态和之间添加一个线性的依赖关系,从而避免梯度消失或梯度爆炸的问题。

    8.1 长短期记忆网络(LSTM)

    长短期记忆网络(Long Short-term Memory,简称LSTM)的结构如图13所示,LSTM的网络结构看上去很复杂,但实际上如果将每一部分拆开来看,其实也很简单。在一般的循环神经网络中,记忆单元没有衡量信息的价值量的能力,因此,记忆单元对于每个时刻的状态信息等同视之,这就导致了记忆单元中往往存储了一些无用的信息,而真正有用的信息却被这些无用的信息挤了出去。LSTM正是从这一点出发做了相应改进,和一般结构的循环神经网络只有一种网络状态不同,LSTM中将网络的状态分为内部状态和外部状态两种。LSTM的外部状态类似于一般结构的循环神经网络中的状态,即该状态既是当前时刻隐藏层的输出,也是下一时刻隐藏层的输入。这里的内部状态则是LSTM特有的。

    在LSTM中有三个称之为“门”的控制单元,分别是输入门(input gate)、输出门(output gate)和遗忘门(forget gate),其中输入门和遗忘门是LSTM能够记忆长期依赖的关键。输入门决定了当前时刻网络的状态有多少信息需要保存到内部状态中,而遗忘门则决定了过去的状态信息有多少需要丢弃。最后,由输出门决定当前时刻的内部状态有多少信息需要输出给外部状态。

    图13 单个时间步的LSTM网络结构示意图

    从上图我们可以看到,一个LSTM单元在每个时间步都会接收三个输入,当前时刻的输入,来自上一时刻的内部状态以及上一时刻的外部状态。其中,和同时作为三个“门”的输入。为Logistic函数,。

    接下来我们将分别介绍LSTM中的几个“门”结构。首先看一下输入门,如图2所示:

    从上图我们可以看到,一个LSTM单元在每个时间步都会接收三个输入,当前时刻的输入,来自上一时刻的内部状态以及上一时刻的外部状态。其中,xt和ht-1同时作为三个“门”的输入。为Logistic函数,。

    接下来我们将分别介绍LSTM中的几个“门”结构。首先看一下输入门,如图14所示:

    图14 LSTM的输入门结构示意图

    LSTM中也有类似于RNN(这里特指前面介绍过的简单结构的循环神经网络)的前向计算过程,如图14,如果去掉输入门部分,剩下的部分其实就是RNN中输入层到隐藏层的结构,“tanh”可以看作是隐藏层的激活函数,从“tanh”节点输出的值为:

    上式中,参数的下标“c”代表这是“tanh”节点的参数,同理,输入门参数的下标为“i”,输出门参数的下标为“o”,遗忘门参数的下标为“f”。上式与简单结构循环神经网络中隐藏层的计算公式一样。在LSTM中,我们将“tanh”节点的输出称为候选状态。

    输入门是如何实现其控制功能的?输入门的计算公式如下:

    由于为Logistic函数,其值域为[0,1],因此输入门的值就属于[0,1]。LSTM将“tanh”节点的输出(即候选状态)乘上输入门的值后再用来更新内部状态。如果i的值趋向于0的话,那么候选状态就只有极少量的信息会保存到内部状态中,相反的,如果i的值趋近于1,那么候选状态就会有更多的信息被保存。输入门就是通过这种方法来决定保存多少中的信息,i值的大小就代表了新信息的重要性,不重要的信息就不会被保存到内部状态中。

    再来看遗忘门,如图15所示:

    图15 LSTM的遗忘门结构示意图

    遗忘门的计算公式如下:

    和输入门是同样的方法,通过f_t的值来控制上一时刻的内部状态c_(t-1)有多少信息需要“遗忘”。当f_t的值越趋近于0,被遗忘的信息越多。同样的原理,我们来看“输出门”,如图16所示。

    图16 LSTM的输出门结构示意图

    输出门的计算公式如下:

    当o_t的值月接近于1,则当前时刻的内部状态c_t就会有更多的信息输出给当前时刻的外部状态h_t。

    以上就是LSTM的整个网络结构以及各个“门”的计算公式。通过选择性的记忆和遗忘状态信息,使得LSTM要比一般的循环神经网络能够学习更长时间间隔的依赖关系。根据不同的需求,LSTM还有着很多不同的变体版本,这些版本的网络结构大同小异,但都在其特定的应用中表现出色。

    8.2 门控制循环单元(GRU)

    门控制循环单元(gated recurrent unit,GRU)网络是另一种基于门控制的循环神经网络,GRU的网络结构相比LSTM要简单一些。GRU将LSTM中的输入门和遗忘门合并成了一个门,称为更新门(update gate)。在GRU网络中,没有LSTM网络中的内部状态和外部状态的划分,而是通过直接在当前网络的状态h_t和上一时刻网络的状态h_(t-1)之间添加一个线性的依赖关系,来解决梯度消失和梯度爆炸的问题。

    图17 单个时间步的GRU网络结构示意图

    在GRU网络中,更新门用来控制当前时刻输出的状态h_t中要保留多少历史状态h_(t-1),以及保留多少当前时刻的候选状态h ̃_t。更新门的计算公式如下:

    如图17所示,更新门的输出分别和历史状态h_(t-1)以及候选状态h ̃_t进行了乘操作,其中和h ̃_t相乘的是1-z_t。最终当前时刻网络的输出为:

    重置门的作用是决定当前时刻的候选状态是否需要依赖上一时刻的网络状态以及需要依赖多少。从图17可以看到,上一时刻的网络状态h_t先和重置门的输出r_t相乘之后,再作为参数用于计算当前时刻的候选状态。重置门的计算公式如下:

    r_t的值决定了候选状态h ̃_t对上一时刻的状态h_(t-1)的依赖程度,候选状态h ̃_t的计算公式如下:

    其实当z_t的值为0且r_t的值为1时,GRU网络中的更新门和重置门就不再发挥作用了,而此时的GRU网络就退化成了简单循环神经网络,因为此时有:

    展开全文
  • 针对BP神经网络初始权值随机获取所导致的易陷入局部最优的问题,采用贝叶斯正则化(Bayesian Regularization,BR)算法改进传统BP神经网络模型。该算法在保证网络误差最小的前提下,通过历史数据的先验概率调整BP...
  • 基本萤火虫算法存在容易陷入局部最优及收敛速度低的问题,提出了一种改进进化机制的萤火虫算法(IEMFA)。在群体进化过程中赋予萤火虫改进的位置移动策略,并利用改进后的萤火虫算法来优化传统BP神经网络的网络参数...
  • 作为深度学习领域的一个重要算法,BP算法为神经网络中权值计算找出最优权值值 BP算法优缺点 优点: 自适应,自主学习.通过不断的参数更新找出最适宜的权值 非线性映射 缺点: 参数过多时,每次更新都需要操作过多权值,...

    作为深度学习领域的一个重要算法,BP算法为神经网络中权值计算找出最优权值值

    BP算法优缺点

    优点:

    1. 自适应,自主学习.通过不断的参数更新找出最适宜的权值
    2. 非线性映射
      缺点:
    3. 参数过多时,每次更新都需要操作过多权值,导致收敛速度慢
    4. 容易陷入局部最小值

    BP算法主要组成

    1. 正向传播
    2. 逆向传播

    正向传播

    首先,我们要根据设计好的神经网络图来对参数进行正向传播,这里使用341的神经网络来作为例子

    1.向隐藏层的正向传播
    在这里插入图片描述
    在这里插入图片描述

    以此类推,我们相继求出h1,h2,h3和h4
    (这里注意两个地方,一是b1和b2是偏置值,因此数据为1.二是权值总共有(3+1)*4=16个,因此要设16个权值,并不是只有v1到v4

    2.向输出层的正向传播
    在这里插入图片描述
    在这里插入图片描述

    由此,就完成了一次正向的传播

    反向传播

    反向传播的核心思想在于对误差进行权值的求偏导,找出权值为何值的时候误差最小

    首先找出误差值
    在这里插入图片描述

    现在,我们要分析的问题是:error为何值时,权值最小,这里用求w1何值时最小来作为例子
    在这里插入图片描述
    在这里插入图片描述

    这里的out2就是o1
    因此,我们分类求出这三个值
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    现在,我们整合这三个式子
    在这里插入图片描述

    现在,我们找到了误差权值和最适权值的变化范围,直接更新

    在这里插入图片描述

    用同样的方法,找出w2,w3,w4,w5的最适权值,向隐藏层的一次反向传播就到此结束,但并不意味着找到了最适,我们还需要多次的反向传播,才能确定出最合适的权值

    现在,我们要分析的问题是:error为何值时,权值最小,这里用由w1求v1何值时最小来作为例子
    在这里插入图片描述
    在这里插入图片描述

    由于上面已经求出error关于net2偏导,这里不过多叙述

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述
    用同样的方法,找出v1,v2,v3,v4的最适权值,向输入层的一次反向传播就到此结束,但并不意味着找到了最适,我们还需要多次的反向传播,才能确定出最合适的权值


    实战案例

    鸢尾花数据python-Numpy实现BP算法

    展开全文
  • 为了解决传统神经网络BP梯度下降算法在解决柔性制造系统调度策略时易陷入局部最优的问题,在规则化神经网络结构的基础上,提出了一种基于最大熵的神经网络权值优化算法。利用神经网络隐层节点变量的条件概率,在计算...
  • 为了解决传统的径向基函数神经网络在多水质传感器数据融合中容易陷入局部最优,训练速度慢的问题,提出了一种基于改进的布谷鸟搜索的RBF神经网络优化方法。 (ICS)。 该方法使用RBF神经网络构建多个水质传感器数据...
  • 针对传统的神经网络训练算法收敛速度慢、易陷入局部最优的问题,提出了一种基于改进的分期变异微粒群优化算法(SMPSO)的神经网络相关性剪枝优化方法。SMPSO在初期使适应度过低的微粒发生变异,在后期使停滞代数过高...
  • GA-BP算法实例

    2018-09-22 21:52:50
    遗传算法是一种概率性的自适应迭代寻优过程,遵循“优胜劣汰”的原则,具有良好的全局搜索性能,较好的克服了BP算法局部最优的缺陷,同时可优化BP神经网络初始权重和阈值,进一步提高BP神经网络的计算精度。
  • 传统BP神经网络参数的选取是随机的,这样易使网络陷入局部最优,针对这一缺点,提出了利用蝙蝠算法优化BP网络参数的改进算法——蝙蝠-BP算法(BA-BP),并将其应用于企业经营状况的评价研究中。建立了基于BA-BP算法的企业...
  • 在简要分析常用储量计算方法与BP神经网络预测方法存在缺陷的基础上,分析了径向基神经网络隐层节点参数在映射机理上与地质统计学方法理论上的一致性,以及其权系数能解析方式求解、可避免网络训练过程陷入局部最优乃至...
  • 针对传统非线性反演方法易陷入局部最优,收敛速度慢等问题,研究了一种基于BP神经网络和遗传算法的微震源定位反演方法。重点论述了BP-GA混合算法的理论基础与模型建立,并结合实例进行了3层介质模型微震源定位反演...
  • 为了改进BP神经网络用于冲击地压预测的精度和泛化能力,利用BP算法和混沌优化算法优缺点的互补性,构建了一种组合式优化预测模型(COBP).将该模型应用于重庆砚石台煤矿冲击地压的预测,结果显示,该模型既利用混沌优化...
  • 简而言之,神经网络是个“黑匣子”,优化目标是基于经验风险最小化,易陷入局部最优,训练结果不太稳定,一般需要大样本; 而支持向量机有严格的理论和数学基础,基于结构风险最小化原则, 泛化能力优于前者,算法...
  • 文中针对BP神经网络收敛速度慢和易陷入局部最优的问题,构建了基于波段比值参数的PSO-BP内陆水体叶绿素a浓度估算模型。选择特征波段比值作为BP神经网络输入变量,借助PSO算法优化了BP网络的初始连接权值和阈值,利用...

空空如也

空空如也

1 2 3
收藏数 42
精华内容 16
关键字:

bp神经网络陷入局部最优