Recurrent Neural Network
参考文献:
https://blog.csdn.net/qq_32241189/article/details/80461635?
https://zhuanlan.zhihu.com/p/30844905
RNN(Recurrent Neural Network)是一类用于处理序列数据的神经网络。首先我们要明确什么是序列数据,摘取百度百科词条:时间序列数据是指在不同时间点上收集到的数据,这类数据反映了某一事物、现象等随时间的变化状态或程度。这是时间序列数据的定义,当然这里也可以不是时间,比如文字序列,但总归序列数据有一个特点——后面的数据跟前面的数据有关系。
上图是一幅全连接神经网络图,我们可以看到输入层-隐藏层-输出层,他们每一层之间是相互独立地,(框框里面代表同一层),每一次输入生成一个节点,同一层中每个节点之间又相互独立的话,那么我们每一次的输入其实跟前面的输入是没有关系地。这样在某一些任务中便不能很好的处理序列信息。
什么是序列信息呢?
通俗理解就是一段连续的信息,前后信息之间是有关系地,必须将不同时刻的信息放在一起理解。
比如一句话,虽然可以拆分成多个词语,但是需要将这些词语连起来理解才能得到一句话的意思。
RNN就是用来处理这些序列信息的任务,比如NLP中的语句生成问题,一句话中的每个词并不是单独存在地,而是根据上下文信息,与他的前后词有关。
如:我吃XXX,吃是一个动词,按照语法规则,那么它后面接名词的概率就比较大,在预测XXX是什么的时候就要考虑前面的动词吃的信息,如果没考虑上下文信息而预测XXX是一个动词的话,动词+动词,很大概率是不符合语言逻辑地。
为了解决这一问题,循环神经网络 RNN也就应运而生了。
关于RNN作用能理解多少理解多少,我们继续往下面看,最后再来熟悉RNN。
RNN 结构
首先看一个简单的循环神经网络如,它由输入层、一个隐藏层和一个输出层组成:
我们发现把上面有W的那个带箭头的圈去掉,它就变成了最普通的全连接神经网络。x是一个向量,它表示输入层的值(这里面没有画出来表示神经元节点的圆圈);s是一个向量,它表示隐藏层的值(这里隐藏层面画了一个节点,你也可以想象这一层其实是多个节点,节点数与向量s的维度相同);
U是输入层到隐藏层的权重矩阵,o也是一个向量,它表示输出层的值;V是隐藏层到输出层的权重矩阵
那么,现在我们来看看W是什么。循环神经网络的隐藏层的值s不仅仅取决于当前这次的输入x,还取决于上一次隐藏层的值s。权重矩阵 W就是隐藏层上一次的值作为这一次的输入的权重。
我们从上图就能够很清楚的看到,上一时刻的隐藏层是如何影响当前时刻的隐藏层的。
如果我们把上面的图展开,循环神经网络也可以画成下面这个样子:
现在看上去就比较清楚了,这个网络在t时刻接收到输入
x
t
x_t
xt之后,隐藏层的值是
s
t
s_t
st,输出值是
o
t
o_t
ot 。关键一点是,
s
t
s_t
st的值不仅仅取决于
x
t
x_t
xt ,还取决于
s
t
−
1
s_{t-1}
st−1 。我们可以用下面的公式来表示循环神经网络的计算方法:
用公式表示如下:
上面文字繁琐一些,不知道能不能了解RNN 的基本结构。
标准RNN的还有以下特点:
1、权值共享,图中的W全是相同的,U和V也一样。
2、每一个输入值
x
t
x_t
xt都只与它本身的那条路线建立权连接,不会和别的神经元连接。
RNN的反向传播BPTT
将RNN展开之后,前向传播就是依次按照时间的顺序计算一次就好了,反向传播就是从最后一个时间将累积的损失传递回来即可,这与普通的神经网络训练本质上是相似的。
即通过梯度下降法一轮轮的迭代,得到合适的RNN模型参数 U , W , V , b , c U,W,V,b,c U,W,V,b,c。由于我们是基于时间反向传播,所以RNN的反向传播有时也叫做BPTT(back-propagation through time)。当然这里的BPTT和普通神经网络也有很大的不同点,即这里所有的 U , W , V , b , c U,W,V,b,c U,W,V,b,c在序列的各个位置是共享的,反向传播时我们更新的是相同的参数。
每一次的输出值
O
t
O_t
Ot都会产生一个误差值
E
t
E_t
Et, 则总的误差可以表示为:
E
=
∑
i
e
i
E=\sum_ie_i
E=i∑ei
则损失函数可以使用交叉熵损失函数也可以使用平方误差损失函数.
由于每一步的输出不仅仅依赖当前步的网络并且还需要前若干步网络的状态,那么这种BP改版的算法叫做Backpropagation Through Time(BPTT) , 也就是将输出端的误差值反向传递,运用梯度下降法进行更新.
我们从序列的末尾开始,反向进行计算。在最后的时间步T, s t s_t st只有 o t o_t ot 作为后续节点,因此这个梯度很简单.
在这里我们以 t = 3时刻为例, 根据链式求导法则可以得到t = 3时刻的偏导数为:
其次我们求解W的更新方法, 由前面的W的更新可以看出它是每个时刻的偏差的偏导数之和.
此时, 根据公式
s
t
=
f
(
U
x
t
+
W
s
t
−
1
)
s_t=f(Ux_t+Ws_{t-1})
st=f(Uxt+Wst−1)我们会发现, S3除了和W有关之外, 还和前一时刻S2有关.
对于S2直接展开得到下面的式子:
对于S1直接展开得到下面的式子:
将上述三个式子合并得到:
这样就得到了公式:
这里要说明的是: ∂ S k + / ∂ w \partial S_k^+/\partial w ∂Sk+/∂w表示的是S3对W直接求导, 不考虑S2的影响.(也就是例如y = f(x)*g(x)对x求导一样)
其次是对U的更新方法. 由于参数U求解和W求解类似,这里就不在赘述了,最终得到的具体的公式如下: