精华内容
下载资源
问答
  • MATLAB源码集锦-基于双隐含层BP神经网络的预测
  • 基于BP神经网络的预测,代码已经调是成功,可直接运行。
  • 运用双隐含层Elman神经网络进行一天24小时的电力负荷预测。
  • BP网络的产生主要是误差的反向传播,根据输出函数和目标函数的误差来修正权值和阈值。...以三层结构(输入层-隐含层-输出层)的模型为案例进行讲解: 一:BP神经网络输入层-隐含层-输出层现在给出模型构建所需的参数 ...

    BP网络的产生主要是误差的反向传播,根据输出函数和目标函数的误差来修正权值和阈值。现在就给大家讲讲标准梯度下降法修正权值和阈值具体算法实现。以三层结构(输入层-隐含层-输出层)的模型为案例进行讲解:    

    一:BP神经网络

    b12136a0fabeb3f53d88ce7df0a86aec.png

    输入层-隐含层-输出层

    现在给出模型构建所需的参数

         cb7a3db799af1092c545a685ecebd157.png             

    133ce111a027f2e98f69e03ea8c58027.png    

    28a55ca4e078db2a0329bb956fa3d313.png

    906cafd352ab558457e51efd415c90e2.png

         58a1ec635fedbfcb2bd40aa2d0c856a1.png       

     59040a5bf02f7a93ba25e2d8f6b86f1c.png

    9f5cd6694488ad8db396c8e7d472ab42.png

    2de98557a0d7b410e1c1d3afe7fba23e.png

                   e8e9bcbf9319f874591d339c63024d77.png             

        9b16c51a4408c466aeffa1a9a9c25bdc.png      

        66f376945487fb875defde09b1ba5154.png

        7959efb3fbcf3d53de3395ddc7f812ff.png      

                                                       755e75e1059832bb63fef18a10e5b981.png                                             83652fa642d5cec772962435fac61fe3.png

                    fb08cc8515ba4718fb516abf8cd5e7f3.png                 

    5d208581261e1438cdc0e1166019f3d5.png

                 653f8d1801de6836c594e1b5fe1d7e77.png        

             5d812a1c803f2b5a6602fd67b8cc5f17.png

    根据模型,隐含层中神经元的输出为:

    86755ba9c0e06db5ab305737c82e4a61.png

    输出层中神经的输出为:

    f90a35ae9bf952490bef793c4b78d5d6.png

    定义误差函数为:

    539c1d8f48858293083857aca547cf51.png

    二:权值阈值的更新

      权值和阈值的变化率涉及到矩阵的求导,关于矩阵运算的基本规则、会在后期单独介绍,在此就不介绍矩阵求导规则。

    输出层的权值、阈值梯度变化:

    b17ad0acbee99bb5f77f4233cfe74fa5.png

    b0dc24bdd9251ca71839d1732f22ac59.png

    4d883fa1f8fa83a58d52aba36f1d5741.png

    e52680a7773bdbbbe8b44edfb8026042.png

    隐含层的权值、阈值梯度变化:

    a798931cc856cad27f7dc1a19d90d4ca.png

    0c1fd83bfcbea2d7c7d08f8c4645c727.png

    4f3b1a1b9655a233be21d49c7ec44919.pngb8c94ef29f351091c18a183cc06314e4.png

      将权值和阈值的变化值加到权值阈值上即可得到权值阈值的更新值,经过不断训练即可得到使得误差最小的权值、阈值。

    c372d4c0e69e36c31198e15fb0acf99e.png

    此方法是BP网络训练权值、阈值的最初的方法,随着对人工网络的深入研究,基于标准梯度下降法又提出了附加动量的bp算法、可变学习速率的bp算法、拟牛顿法等。请持续关注MATLAB爱好者公众号,作者会持续更新关于权值阈值的学习算法。

    5cba00c42eea10e97b4c2fa475c02d1c.png

    误差变化图

    三:标准梯度下降法MATLAB代码

    现给出单隐含层和双隐含层的权值阈值学习代码案例:

    clear allP=[0.1 0.3 0.14 0.5 ;0.2 0.5 0.2 0.1; 0.3 0.6 0.6 0.2;0.4 0.7 0.1 0.3; 0.1 0.4 0.6 0.6];T=[0.5;0.6;0.3;0.4;0.2];W1=rand(3,4) ; B1=rand(3,1)*ones(1,5);W2=rand(1,3) ; B2=ones(1,5)*rand(1,1);x=W1*P'+B1;fx='tansig(x)';A1=eval(fx);y=W2*A1+B2;fy='purelin(y)';A2=eval(fy);E=T'-A2;SSE=sumsqr(E);fyd=ones(1,5);Lp.lr= 0.0028;M=cell(4,25);for epoch=1:100;    dW2=0.0028*((E.*fyd).*ones(1,5))*pinv(A1);%0.0028:为设置的一个常数系数,表示下降速率;fyd为purelin的导数    dB2=0.0028*((E.*fyd).*ones(1,5));%0.0028*((E.*fyd):为系数所以点成的形式乘以矩阵    dW1=0.0028*(((((ones(3,1)*(E.*fyd))).*((4*exp(-2*A1))./(exp(-2*A1) + 1).^2))*ones(5,1)).*pinv(W2))*ones(1,5)*pinv(P');%((4*exp(-2*A1))./(exp(-2*A1) + 1).^2)为tansig函数的导数    dB1=0.0028*(((((ones(3,1)*(E.*fyd))).*((4*exp(-2*A1))./(exp(-2*A1) + 1).^2))*ones(5,1)).*pinv(W2))*ones(1,5);    W1=W1+dW1;    B1=B1+dB1;    W2=W2+dW2;    B2=B2+dB2;    x=W1*P'+B1;    fx='tansig(x)';    A1=eval(fx);    y=W2*A1+B2    fy='purelin(y)'    A2=eval(fy);    E=T'-A2;    SSE=sumsqr(E);    M{epoch}=SSEend

    往期相关推荐(点击下方文字直接访问)

    神经网络连载(三)

    神经网络连载(二)

    神经网络连载(一)

    9b6c898daeac53c6508cf763f8af1bce.png

    本文作者:过冷水

    a653a750b5c723127d1a16a5f58faf76.png1c2541c62b2c2fe69ba0261dbd68c1d8.pngc2b8ee1eb9b50d9803b0787fc78bedc1.png

    ceb9bfe0fec73c2ee84e271559a36415.png

    展开全文
  • 隐含层神经网络的推导步骤非常类似于单隐含层神经网络的步骤,只不过是多重复几遍。 关于单隐含层神经网络公式的推导可以参考: http://blog.csdn.net/fengbingchun/article/details/79370310 逻辑回归是一个...

            多隐含层神经网络的推导步骤非常类似于单隐含层神经网络的步骤,只不过是多重复几遍

            关于单隐含层神经网络公式的推导可以参考: http://blog.csdn.net/fengbingchun/article/details/79370310 

            逻辑回归是一个浅层模型(shadow model),或称单层神经网络;单隐含层神经网络是一个双层神经网络。当我们数神经网络有几层的时候,我们不能把输入层数进去,只算上隐含层和输出层的数量

           符号约定:L:表示神经网络的层数;n[l]:第l层上节点(单元)的数量,如n[1]表示第一个隐含层单元数量;输入层作为第0层,即n[0]表示输入层单元数量;a[l]:表示第l层中的激活函数;a[l]=g[l](z[l]);w[l]:表示第l层中的权值,即在a[l]中计算z[l]值的权重;b[l]:表示第l层中的偏置,即计算z[l]值的偏置项;x:输入特征,x也是第0层的激活函数,即a[0]=x;最后一层的激活函数a[L]=y’(或称y hat),即a[L]等于预测输出;

            正向传播(单个样本):第1层到第L层(也就是从输入层到输出层的整个神经网络)

                    z[1]=w[1]*x+b[1];// x=a[0](输入特征向量x也是第0层的激活函数)

                    a[1]=g[1](z[1]);

                    z[2]=w[2]*a[1]+b[2];

                    a[2]=g[2](z[2]);

                    … …

                    z[L]=w[L]*a[L-1]+b[L];

                    a[L]=g[L](z[L]);

            正向传播基本规律公式

                    z[l]=w[l]*a[l-1]+b[l];

                    a[l]=g[l](z[l]);

            反向传播基本规律公式

                    dz[l]=da[l]*g[l]’(z[l]);

                    dw[l]=dz[l]*a[l-1];

                    db[l]=dz[l];

                    da[l-1]=w[l]T*dz[l];


            各层矩阵w、b维数的确定

                         w[l]的维度必须是:(n[l],n[l-1]);其中n[0]=nx,即输入特征x的长度,x的维度是(n[0],1);

                         b[l]的维度一般是:(n[l],1);

            z[l]和a[l]矩阵的维度应该是相等的(a[L]=g[L](z[L]));dz[l]和z[l]的维度是相等的;da[l]和a[l]的维度是相等的。

            在反向传播中,dw[l]的维度应该和w[l]的维度相同,即为(n[l],n[l-1]);db[l]的维度应该和b[l]的维度相同,即(n[l],1)。

            深度神经网络(deep neural network)很好用的原因

            假如你在建一个人脸识别或人脸检测系统,深度神经网络所做的事就是:当你输入一张脸部的照片,然后你可以把深度神经网络的第1层当成一个特征检测器或边缘检测器,例如在第1层创建一个大概有20个隐层单元的深度神经网络,隐层单元就是下图的这些小方块,一个小方块就是一个隐层单元,它会去找这张照片里的垂直或水平边缘的方向等,即第1层去找这张照片的各个边缘;然后它可以把检测到的边缘组合成面部的不同部分,比如说,可能有一个神经元会去找眼睛的部分,另外还有别的在找鼻子的部分,然后把这些许多的边缘结合在一起,就可以开始检测人脸的不同部分;最后再把这些部分放在一起,比如鼻子、眼睛、下巴,就是识别或检测不同的人脸。你可以直觉上把这种神经网络的前几层当做检测简单的函数,比如边缘,之后把它们跟后几层结合在一起,那么总体上就能学习更多复杂的函数。边缘(edge)检测器其实相对来说都是针对照片中非常小块的面积;面部检测器就会针对于大一些的区域。一般的概念是,一般会从比较小的细节入手,比如边缘,然后在一步步到更大更复杂的区域,比如一只眼睛或是一个鼻子;再把眼睛鼻子装一块组成更复杂的部分。这种从简单到复杂的金字塔状表示方法或者组成方法,也可以应用在图像或者人脸识别以外的其它数据上。


            参数和超参数(hyper parameters):参数包括各层的w和b。学习率α、梯度下降法中的迭代次数、隐含层数、各隐含层的单元数、激活函数的选择,这些都需要自己来设置,这些数字实际上控制了最终参数w和b的值。所以它们被称为超参数。因为这些超参数在某种程度上决定了最终得到的w和b。

            今天的深度学习应用领域,还是很经验性的过程:


            机器学习里的复杂性是来源于数据本身而不是一行行的代码

            GitHub: https://github.com/fengbingchun/NN_Test 

    展开全文
  • Matlab的双隐层的BP神经网络该如何创建-ANNBP2...两输入、双隐含层(第一隐含层神经元个数可在4-20范围内变化,第二隐含层可在5-10范围内变化) 不知道这个程序该怎样写 请高手赐教! 本人QQ :41402066
  • 本文转载修改自:知乎-科言君感知机(perceptron)神经网络技术起源于上世纪五、六十年代,当时叫感知机(perceptron),拥有输入层、输出层和一个隐含层。输入的特征向量通过隐含层变换达到输出层,在输出层得到分类...

    本文转载修改自:知乎-科言君

    感知机(perceptron)

    神经网络技术起源于上世纪五、六十年代,当时叫感知机(perceptron),拥有输入层、输出层和一个隐含层。输入的特征向量通过隐含层变换达到输出层,在输出层得到分类结果。早期感知机的推动者是Rosenblatt。但是,Rosenblatt的单层感知机有一个严重得不能再严重的问题,即它对稍复杂一些的函数都无能为力(比如最为典型的“异或”操作)。

    随着数学的发展,这个缺点直到上世纪八十年代才被Rumelhart、Williams、Hinton、LeCun等人发明的多层感知机(multilayer perceptron)克服。多层感知机,顾名思义,就是有多个隐含层的感知机。我们看一下多层感知机的结构:

    图1 上下层神经元全部相连的神经网络——多层感知机

    多层感知机可以摆脱早期离散传输函数的束缚,使用sigmoid或tanh等连续函数模拟神经元对激励的响应,在训练算法上则使用Werbos发明的反向传播BP算法,这就是所说的神经网络NN。多层感知机解决了之前无法模拟异或逻辑的缺陷,同时更多的层数也让网络更能够刻画现实世界中的复杂情形。多层感知机给我们带来的启示是,神经网络的层数直接决定了它对现实的刻画能力——利用每层更少的神经元拟合更加复杂的函数。

    神经网络(Neural Network)

    即便大牛们早就预料到神经网络需要变得更深,但是有一个梦魇总是萦绕左右。随着神经网络层数的加深,优化函数越来越容易陷入局部最优解,并且这个“陷阱”越来越偏离真正的全局最优。利用有限数据训练的深层网络,性能还不如较浅层网络。同时,另一个不可忽略的问题是随着网络层数增加,“梯度消失”现象更加严重。具体来说,我们常常使用sigmoid作为神经元的输入输出函数。对于幅度为1的信号,在BP反向传播梯度时,每传递一层,梯度衰减为原来的0.25。层数一多,梯度指数衰减后低层基本上接受不到有效的训练信号。

    2006年,Hinton利用预训练方法缓解了局部最优解问题,将隐含层推动到了7层,神经网络真正意义上有了“深度”,由此揭开了深度学习的热潮。这里的“深度”并没有固定的定义——在语音识别中4层网络就能够被认为是“较深的”,而在图像识别中20层以上的网络屡见不鲜。为了克服梯度消失,ReLU、maxout等传输函数代替了sigmoid,形成了如今DNN的基本形式。单从结构上来说,全连接的DNN和图1的多层感知机是没有任何区别的。

    值得一提的是,今年出现的高速公路网络(highway network)和深度残差学习(deep residual learning)进一步避免了梯度消失,网络层数达到了前所未有的一百多层(深度残差学习:152层)

    图2 缩减版的深度残差学习网络,仅有34层,终极版有152层

    如图1所示,我们看到全连接DNN的结构里下层神经元和所有上层神经元都能够形成连接,带来的潜在问题是参数数量的膨胀。假设输入的是一幅像素为1K×1K的图像,隐含层有1M个节点,光这一层就有10^12个权重需要训练,这不仅容易过拟合,而且极容易陷入局部最优。另外,图像中有固有的局部模式(比如轮廓、边界,人的眼睛、鼻子、嘴等)可以利用,显然应该将图像处理中的概念和神经网络技术相结合。此时我们可以引出的卷积神经网络CNN。对于CNN来说,并不是所有上下层神经元都能直接相连,而是通过“卷积核”作为中介。同一个卷积核在所有图像内是共享的,图像通过卷积操作后仍然保留原先的位置关系。两层之间的卷积传输的示意图如下:

    图3 卷积神经网络隐含层(摘自Theano教程)

    通过一个例子简单说明卷积神经网络的结构。假设图3中m-1=1是输入层,我们需要识别一幅彩色图像,这幅图像具有四个通道ARGB(透明度和红绿蓝,对应了四幅相同大小的图像),假设卷积核大小为100×100,共使用100个卷积核w1到w100(从直觉来看,每个卷积核应该学习到不同的结构特征)。用w1在ARGB图像上进行卷积操作,可以得到隐含层的第一幅图像;这幅隐含层图像左上角第一个像素是四幅输入图像左上角100×100区域内像素的加权求和,以此类推。同理,算上其他卷积核,隐含层对应100幅“图像”。每幅图像对是对原始图像中不同特征的响应。按照这样的结构继续传递下去。CNN中还有max-pooling等操作进一步提高鲁棒性。

    图4 一个典型的卷积神经网络结构,注意到最后一层实际上是一个全连接层(摘自Theano教程)

    在这个例子里,我们注意到输入层到隐含层的参数瞬间降低到了100100100=10^6个!这使得我们能够用已有的训练数据得到良好的模型。CNN之所以适用于图像识别,正是由于CNN模型限制参数了个数并挖掘了局部结构的这个特点。顺着同样的思路,利用语音语谱结构中的局部信息,CNN照样能应用在语音识别中。

    全连接的DNN还存在着另一个问题——无法对时间序列上的变化进行建模。然而,样本出现的时间顺序对于自然语言处理、语音识别、手写体识别等应用非常重要。对了适应这种需求,就出现了另一种神经网络结构——循环神经网络RNN。

    在普通的全连接网络或CNN中,每层神经元的信号只能向上一层传播,样本的处理在各个时刻独立,因此又被成为前向神经网络(Feed-forward Neural Networks)。而在RNN中,神经元的输出可以在下一个时间戳直接作用到自身,即第i层神经元在m时刻的输入,除了(i-1)层神经元在该时刻的输出外,还包括其自身在(m-1)时刻的输出!表示成图就是这样的:

    图5 RNN网络结构

    我们可以看到在隐含层节点之间增加了互连。为了分析方便,我们常将RNN在时间上进行展开,得到如图6所示的结构:

    图6 RNN在时间上进行展开

    (t+1)时刻网络的最终结果O(t+1)是该时刻输入和所有历史共同作用的结果,这就达到了对时间序列建模的目的。

    可以发现,RNN可以看成一个在时间上传递的神经网络,它的深度是时间的长度!正如我们上面所说,“梯度消失”现象又要出现了,只不过这次发生在时间轴上。对于t时刻来说,它产生的梯度在时间轴上向历史传播几层之后就消失了,根本就无法影响太遥远的过去。因此,之前说“所有历史”共同作用只是理想的情况,在实际中,这种影响也就只能维持若干个时间戳。

    为了解决时间上的梯度消失,机器学习领域发展出了长短时记忆单元LSTM,通过门的开关实现时间上记忆功能,并防止梯度消失,一个LSTM单元长这个样子:

    图7 LSTM

    除了以上的三种网络,和之前提到的深度残差学习、LSTM外,深度学习还有许多其他的结构。举个例子,RNN既然能继承历史信息,是不是也能吸收点未来的信息呢?因为在序列信号分析中,如果我能预知未来,对识别一定也是有所帮助的。因此就有了双向RNN、双向LSTM,同时利用历史和未来的信息。

    图8 双向RNN

    事实上,不论是那种网络,他们在实际应用中常常都混合着使用,比如CNN和RNN在上层输出之前往往会接上全连接层,很难说某个网络到底属于哪个类别。不难想象随着深度学习热度的延续,更灵活的组合方式、更多的网络结构将被发展出来。尽管看起来千变万化,但研究者们的出发点肯定都是为了解决特定的问题。如果想进行这方面的研究,不妨仔细分析一下这些结构各自的特点以及它们达成目标的手段。入门的话可以参考:

    Ng的Ufldl以及

    Theano内自带的教程

    展开全文
  • 双向循环神经网络及TensorFlow实现

    千次阅读 2018-04-03 09:06:25
    前言 循环神经网络得益于其记忆功能使...所谓的单向循环神经网络其实就是常见的循环神经网络,可以看到t时刻、t-1时刻、t+1时刻,不同时刻输入对应不同的输出,而且上一时刻的隐含层会影响当前时刻的输出。这种结构...

    前言

    循环神经网络得益于其记忆功能使其擅长处理序列方面的问题,它能提取序列之间的特征,进而对序列输出进行预测。比如我说“我肚子饿了,准备去xx”,那么根据前面的序列输入来预测“xx”很可能就是“吃饭”。

    单向循环神经网络

    所谓的单向循环神经网络其实就是常见的循环神经网络,可以看到t时刻、t-1时刻、t+1时刻,不同时刻输入对应不同的输出,而且上一时刻的隐含层会影响当前时刻的输出。这种结构就是单向循环神经网络结构。

    这里写图片描述

    单向循环神经网络不足

    从单向的结构可以知道它的下一刻预测输出是根据前面多个时刻的输入来共同影响的,而有些时候预测可能需要由前面若干输入和后面若干输入共同决定,这样会更加准确。比如我说“我肚子xx,准备去吃饭”,那么如果没有后面的部分就不能很好地推断出是“饿了”,也可以是“好疼”或“胖了”之类的。

    双向循环神经网络

    鉴于单向循环神经网络某些情况下的不足,提出了双向循环神经网络。因为是需要能关联未来的数据,而单向循环神经网络属于关联历史数据,所以对于未来数据提出了反向循环神经网络,两个方向的网络结合到一起就能关联历史与未来了。

    双向循环神经网络按时刻展开的结构如下,可以看到向前和向后层共同连接着输出层,其中包含了6个共享权值,分别为输入到向前层和向后层两个权值、向前层和向后层各自隐含层到隐含层的权值、向前层和向后层各自隐含层到输出层的权值。

    这里写图片描述

    可以由下列式子表示,
    ht=f(w1xt+w2ht1)ht=f(w1xt+w2ht−1)

    ht=f(w3xt+w5ht+1)ht′=f(w3xt+w5ht+1′)

    ot=g(w4ht+w6ht)ot=g(w4ht+w6ht′)

    双向循环网络如何训练

    前向传播
    1. 沿着时刻1到时刻T正向计算一遍,得到并保存每个时刻向前隐含层的输出。
    2. 沿着时刻T到时刻1反向计算一遍,得到并保存每个时刻向后隐含层的输出。
    3. 正向和反向都计算完所有输入时刻后,每个时刻根据向前向后隐含层得到最终输出。

    反向传播
    1. 计算所有时刻输出层的δδ项。
    2. 根据所有输出层的δδ项,使用 BPTT 算法更新向前层。
    3. 根据所有输出层的δδ项,使用 BPTT 算法更新向后层。

    实现代码

    创建词汇

    处理字符首先就是需要创建包含语料中所有的词的词汇,需要一个从字符到词汇位置索引的词典,也需要一个从位置索引到字符的词典。

    def create_vocab(text):
        unique_chars = list(set(text))
        print(unique_chars)
        vocab_size = len(unique_chars)
        vocab_index_dict = {}
        index_vocab_dict = {}
        for i, char in enumerate(unique_chars):
            vocab_index_dict[char] = i
            index_vocab_dict[i] = char
        return vocab_index_dict, index_vocab_dict, vocab_size

    批量生成器

    创建一个批量生成器用于将文本生成批量的训练样本,其中text为整个语料,batch_size为批大小,vocab_size为词汇大小,seq_length为序列长度,vocab_index_dict为词汇索引词典。生成器的生成结构大致如下图,按文本顺序竖着填进矩阵,而矩阵的列大小为batch_size。

    class BatchGenerator(object):
        def __init__(self, text, batch_size, seq_length, vocab_size, vocab_index_dict):
            self._text = text
            self._text_size = len(text)
            self._batch_size = batch_size
            self.vocab_size = vocab_size
            self.seq_length = seq_length
            self.vocab_index_dict = vocab_index_dict
    
            segment = self._text_size // batch_size
            self._cursor = [offset * segment for offset in range(batch_size)]
            self._last_batch = self._next_batch()
    
        def _next_batch(self):
            batch = np.zeros(shape=(self._batch_size), dtype=np.float)
            for b in range(self._batch_size):
                batch[b] = self.vocab_index_dict[self._text[self._cursor[b]]]
                self._cursor[b] = (self._cursor[b] + 1) % self._text_size
            return batch
    
        def next(self):
            batches = [self._last_batch]
            for step in range(self.seq_length):
                batches.append(self._next_batch())
            self._last_batch = batches[-1]
            return batches

    这里写图片描述

    构建图

    分别定义向前和向后两个LSTM循环神经网络,需要指定隐含层的神经元数hidden_size,然后将创建的两个神经网络传入static_bidirectional_rnn完成双向循环神经网络的创建。

    lstm_fw_cell = rnn.BasicLSTMCell(hidden_size, forget_bias=1.0)
    lstm_bw_cell = rnn.BasicLSTMCell(hidden_size, forget_bias=1.0)
    outputs, _, _ = rnn.static_bidirectional_rnn(lstm_fw_cell, lstm_bw_cell, sliced_inputs, dtype=tf.float32)

    接着创建占位符,主要有输入占位符和target占位符,输入占位符,与批大小和序列长度相关的结构[batch_size, seq_length]。最后是target占位符,结构与输入占位符是一样的。为更好理解这里给输入和target画个图,如下:

    input_data = tf.placeholder(tf.int64, [batch_size, seq_length], name='inputs')
    input_targets = tf.placeholder(tf.int64, [batch_size, seq_length], name='targets')

    这里写图片描述

    这里写图片描述

    一般我们会需要一个嵌入层将词汇嵌入到指定的维度空间上,维度由embedding_size指定。同时vocab_size为词汇大小,这样就可以将所有单词都映射到指定的维数空间上。嵌入层结构如下图,通过tf.nn.embedding_lookup就能找到输入对应的词空间向量了,这里解释下embedding_lookup操作,它会从词汇中取到inputs每个元素对应的词向量,inputs为2维的话,通过该操作后变为3维,因为已经将词用embedding_size维向量表示了。

    embedding = tf.get_variable('embedding', [vocab_size, embedding_size])
    inputs = tf.nn.embedding_lookup(embedding, input_data)

    这里写图片描述

    上面得到的3维的嵌入层空间向量,我们无法直接传入循环神经网络,需要一些处理。需要根据序列长度切割,通过split后再经过squeeze操作后得到一个list,这个list就是最终要进入到循环神经网络的输入,list的长度为seq_length,这个很好理解,就是由这么多个时刻的输入。每个输入的结构为(batch_size,embedding_size),也即是(20,128)。注意这里的embedding_size,刚好也是128,与循环神经网络的隐含层神经元数量一样,这里不是巧合,而是他们必须要相同,这样嵌入层出来的矩阵输入到神经网络才能刚好与神经网络的各个权重完美相乘。最终得到循环神经网络的输出和最终状态。

    sliced_inputs = [tf.squeeze(input_, [1]) for input_ in
                             tf.split(axis=1, num_or_size_splits=seq_length, value=inputs)]

    经过2层循环神经网络得到了输出outputs,但该输出是一个list结构,我们要通过tf.reshape转成tf张量形式,该张量结构为(200,128)。同样target占位符也要连接起来,结构为(200,)。接着构建softmax层,权重结构为[hidden_size, vocab_size],偏置项结构为[vocab_size],输出矩阵与权重矩阵相乘并加上偏置项得到logits,然后使用sparse_softmax_cross_entropy_with_logits计算交叉熵损失,最后求损失平均值。

    flat_outputs = tf.reshape(tf.concat(axis=1, values=outputs), [-1, 2 * hidden_size])
    flat_targets = tf.reshape(tf.concat(axis=1, values=input_targets), [-1])
    logits = tf.matmul(flat_outputs, weights) + biases
    loss = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=flat_targets)
    mean_loss = tf.reduce_mean(loss)

    最后使用优化器对损失函数进行优化。为了防止梯度爆炸或梯度消失需要用clip_by_global_norm对梯度进行修正。

    tvars = tf.trainable_variables()
    grads, _ = tf.clip_by_global_norm(tf.gradients(mean_loss, tvars), max_grad_norm)
    optimizer = tf.train.AdamOptimizer(tf_learning_rate)
    train_op = optimizer.apply_gradients(zip(grads, tvars))

    计算训练准确率。

    prediction = tf.nn.softmax(logits)
    correct_pred = tf.equal(tf.argmax(prediction, 1), flat_targets)
    accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))

    创建会话

    创建会话开始训练,设置需要训练多少轮,由num_epochs指定。epoch_size为完整训练一遍语料库需要的轮数。通过批量生成器获取一批样本数据,因为当前时刻的输入对应的正确输出为下一时刻的值,所以用data[:-1]和data[1:]得到输入和target。组织ops并将输入、target和状态对应输入到占位符上,执行。

    with tf.Session(graph=graph) as session:
        tf.global_variables_initializer().run()
        for i in range(num_epochs):
            data = train_batches.next()
            inputs = np.array(data[:-1]).transpose()
            targets = np.array(data[1:]).transpose()
            ops = [mean_loss, train_op, tf_learning_rate, accuracy]
            feed_dict = {input_data: inputs, input_targets: targets}
            average_loss, __, lr, acc = session.run(ops, feed_dict)
            if i % 100 == 0:
                logging.info("average loss: %.5f,accuracy: %.3f", average_loss, acc)

    github

    https://github.com/sea-boat/DeepLearning-Lab/blob/master/BiLstm.py

    ————-推荐阅读————

    我的2017文章汇总——机器学习篇

    我的2017文章汇总——Java及中间件

    我的2017文章汇总——深度学习篇

    我的2017文章汇总——JDK源码篇

    我的2017文章汇总——自然语言处理篇

    我的2017文章汇总——Java并发篇

    ——————广告时间—————-

    跟我交流,向我提问:

    这里写图片描述

    公众号的菜单已分为“分布式”、“机器学习”、“深度学习”、“NLP”、“Java深度”、“Java并发核心”、“JDK源码”、“Tomcat内核”等,可能有一款适合你的胃口。

    为什么写《Tomcat内核设计剖析》

    欢迎关注:

    这里写图片描述

    展开全文
  • 单向循环神经网络所谓的单向循环神经网络其实就是常见的循环神经网络,可以看到t时刻、t-1时刻、t+1时刻,不同时刻输入对应不同的输出,而且上一时刻的隐含层会影响当前时刻的输出。这种结构就是单向循环神经...
  • 双向RNN,即可以从过去的时间点获取记忆,又可以从未来的时间点获取信息 至于网络单元到底是标准的RNN还是GRU或者是LSTM是...六个独特的权值在每一个时步被重复的利用,六个权值分别对应:输入到向前和向后隐含层...
  • 双向循环神经网络(BRNN)的基本思想是提出每一个训练序列向前...六个独特的权值在每一个时步被重复的利用,六个权值分别对应:输入到向前和向后隐含层(w1, w3),隐含层隐含层自己(w2, w5),向前和向后隐含层...
  • 双向长短时记忆循环神经网络

    千次阅读 2019-05-27 21:02:16
    这个问题就使得隐含层的输入对于网络输出的影响随着网络环路的不断递归而衰退。 为了解决这个问题,长短时记忆(LSTM)结构诞生了。与其说长短时记忆是一种循环神经网络,倒不如说是一个加强版的组件被放在了循环...
  • 环境:tensorflow1.1,python3双向循环神经网络(BRNN)的基本思想是提出每一个训练序列向前和向后分别是两个循环...六个独特的权值在每一个时步被重复的利用,六个权值分别对应:输入到向前和向后隐含层(w1, w3),隐
  • 该文件主要包含了两个利用Matlab做的BP算法,主要用来实现预测,该文件中包含两个网络,一个是普通BP神经网络,一个为双隐含层BP神经网络
  • MATLAB遗传神经网络算法学习

    千次阅读 2018-07-31 09:12:28
    中间层为双隐含层,节点数可选,一般不同层有不同的节点数;最后一层为输出层,节点数目N由输出向量维数确定. 不同层的神经元由权值连接,每个神经元带有一个阈值θ. 其中Im为输入层第m个神经元的输入值,θj为第...

空空如也

空空如也

1 2 3
收藏数 47
精华内容 18
关键字:

双隐含层神经网络