循环神经网络个人笔记

       循环神经网络(RNN)是另一种比较流行的神经网络,它对文本方面的应用表现非常敏感。一开始看的是吴恩达老师的视频课,但是发现看了一段时间后还是非常的模糊。偶然看到台湾大学李宏毅教授的上课视频,感觉讲的通俗易懂,豁然开朗。依据老师的上课资料与视频写下自己的笔记,加深一下印象。

1Example Application

        老师先用一个Slot Filling 的例子,即输入一个句子,预设有几个槽位,将句子的信息插入到对于的槽位。比如 下面所示

                                       

输入 I would like to arrive TaiPei on November 2th。那么Taipei对应的就是 Destination目的地,November 2th对应的就是到达的时间。我们假设可以使用神经网络来解决这个问题,神经网络的输入是每个单词,该单词使用向量表示,可以使用1-of N encoding将一个单词转化为向量的方式,当然还有其他表示。那么该神经网络的输出就是该单词属于某个槽位的概率。由于我们只考虑的单词本身,而没有依靠上下文语义去判断该单词是否属于槽位,所以会出现问题。如下所示,输入两个句子

                                                    

Taipei前面根据不同的词,一个arrive,另一个leave。我们知道前一句taipei是Destination,第二句是place of departure。但是上述的我们训练的神经网络不知道,它仅仅会考虑taipei,然后认定它为一个特定的槽位。如果我们假设神经网络有记忆,那么就可很清晰的分辨出两个taipei是属于不同的槽位的,这就引伸出了RNN,也就是循环神经网络。

2 Recurrent Neural Network

      依我自己通俗的,简单的理解RNN的本质就是在一个神经网络中,当前神经元需要考虑上一个或者上一层神经元的输出。如老师所讲述的一个简单结构

                                                 

     将隐藏层的输出存储在记忆中,然后下次输入新的数据时,要考虑记忆中的值。李宏毅老师还举了一个非常简单例子,也就是输入三个向量 \begin{bmatrix} 1\\ 1\end{bmatrix} \begin{bmatrix} 1\\ 1\end{bmatrix} \begin{bmatrix} 2\\ 2\end{bmatrix},隐藏的激活函数就是线性函数y=x这种,bias偏差为0,输出为\begin{bmatrix} 4\\ 4\end{bmatrix} \begin{bmatrix} 12\\ 12\end{bmatrix} \begin{bmatrix} 32\\ 32\end{bmatrix}.如下图所示

                                                         

 输入\begin{bmatrix} 1\\ 1\end{bmatrix} 时,绿色的隐藏层为2,将值存入蓝色的memory中,输出值为\begin{bmatrix} 4\\ 4\end{bmatrix},再次输入 \begin{bmatrix} 1\\ 1\end{bmatrix}时,由于需要考虑memory中的值,我们只是把他们相加,所以值为 \begin{bmatrix} 6\\ 6\end{bmatrix}.存入蓝色的memory中,输出值为 \begin{bmatrix} 12\\ 12\end{bmatrix},再输入  \begin{bmatrix} 2\\ 2\end{bmatrix}时,加上两个6,值为16,最后输出为 \begin{bmatrix} 32\\ 32\end{bmatrix}

    上述就是简单的RNN例子及运算,如果将RNN使用在之前的slot clipping中,过程会如下所示

                                                       

     我们将单词一个个输入,再第一个单词arrive 和leave 分别输入后,将他们计算的隐藏层的数值存储起来,再输入taipei时,由于之前存储的值不同,所以会得到不同的结果,当然要使用肯定时需要更深层次的RNN网络。此外还有不存储隐藏层值而存储输出值的,这种叫做Jardan Network. 此外还有双向的RNN。

3 Long Short-term Memory(LSTM)

       现在LSTM非常的流行,在NLP上更甚,通常所讲使用的RNN其实就是LSTM。LSTM的神经元架构如下所示,它有4个输入,一个输出。4个输入分别时一个输入数据,一个输入控制门和一个输出控制门,一个遗忘门。其实这些控制门也是相应的函数。如下所示

                                                    

      这是结构图,我们可以之间使用数学公式计算来解释这些门,输入门就是控制输入,如果为sigmoid函数,为1就时允许输入,为0就是输入的值为0 等等。使用数学公式描述LSTM的神经元为如下所示                     

                                        

       我们上述所讲的激活函数都是sigmoid函数,如果输入一个z值,通过神经元激活函数计算为g(z),输入控制门输入的值为z_{i},门内的函数为计算为f(z_{i}),再两者相乘为g(z)f(z_{i})。到遗忘控制门这,输入值为z_{f},memory原先存储的值为c,那么新的值为

c^{'}=g(z)f(z_{i})+cf(z_{f}),然后再通过一个函数计算得出为h(c^{'}),经由控制们后,最后的输出为a=f(z_{o})h(c^{'}).虽然过程非常的复杂,但是理解起来还是很清晰的,最后李宏毅老师手动举了一个例子用来计算LSTM,真的非常的容易懂。

最后关于这些控制们的输入值,是由一个数据转化为向量得出来的,由于上诉只是一个LSTM的最基本的结构,一层往往有很多个这样的单元,所以我们需要将输入的值变成一个向量,再根据这个向量里面的值,选择作为各种控制门的输入,如下所示

                                          

C^{t-1}就是上一个输入值训练后存储在momery中的值。LSTM就是很多层这样的结构进行叠加起来。更详细的结构如下所示

                                                

 说实话一个就看到很头痛,还好这些我们都不需要自己去具体实现,keras可以帮我们具体去实现,我们只需要调用参数就可以了。至于这些参数的具体值,都是由LSTM自己去学习的,也就是向后传播算法,但是是进阶的算法叫做Backpropagation through time(BPTT)。但是RNN有时候训练会不尽人意,在训练时我们希望随着epoch 的增加,RNN的loss函数也会随之下降,但是也可能会出现这样的情况

                                       

那是因为RNN的total loss是会剧烈抖动的,因为会剧烈抖动,没法保证平滑下降,如下图所示

                                         

 表面要么非常平坦,要么非常陡峭(当你的参数值在较为平坦的区域做更新时,因此该区域梯度值比较小,此时的学习率一般会变得的较大,如果突然到达了陡峭的区域,梯度值陡增,再与此时较大的学习率相乘,参数就有很大幅度更新(实线表示的轨迹),因此学习过程非常不稳定。Razvan Pascanu使用了叫做“Clipping”的训练技巧:为梯度设置阈值,超过该阈值的梯度值都会被cut,这样参数更新的幅度就不会过大。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值