下面简单介绍一下RNN的结构,如果简略地去看,RNN结构很简单,根本没有CNN那么复杂,但是要具体实现,还是需要仔细思考一下,希望本篇博客能把RNN结构说的明白。
循环神经网络(Recurrent Neural Network,RNN)DNN以及CNN在对样本提取特征的时候,样本与样本之间是独立的,而有些情况是无法把每个输入的样本都看作是独立的,比如NLP中的此行标注问题,ASR中每个音素都和前一个音素是相关的,这类问题可以看做一种带有时序序列的问题,无法将样本看做是相互独立的,因此单纯的DNN和CNN解决这类问题就比较棘手。此时RNN就是一种解决这类问题很好的模型。
由上图可以看出,RNN的结构是一个重复的过程,且权重是共享的,这也是借鉴了CNN的思想,可以减少参数量,从而减少计算的复杂度。第时刻隐藏层的输出需要时刻的隐藏层的输出,RNN以此来实现信息的传递。如果上图计算不清晰,就请看下面的两幅图片。
看到这两幅图已经很清晰地展示了RNN的整体结构,但是在具体实现的时候,或者你需要了解每一个细节,我们知道在图像处理的时候,我们的每一个图像被拉成一个向量,每一个像素其实就是输入层的一个神经元。并且对于隐藏层每个神经元同样相当于一个特征图所构成向量的一个像素值。所以,上述的隐藏层并不是一个单一的神经元,它是一个包含多个神经元的隐藏层,如下图所示。这才是RNN的真正的结构。
好了,上面只是RNN的图形描述,现在用公式的形式来对RNN的前向传播进行描述,以下图的符号进行描述,很容易就可以写出前向传播的公式。
符号 | 含义 |
输入向量的大小(one-hot长度,也是词典大小) | |
输入的每一个序列的长度 | |
隐藏层神经元的个数 | |
样本集合 | |
第时刻的输入 | |
第时刻经过Softmax层的输出。 | |
第时刻输入样本的真实标签 | |
第时刻的损失函数,使用交叉熵函数, | |
序列对应的损失函数: RNN的反向传播是每处理完一个样本就需要对参数进行更新,因此当执行完一个序列之后,总的损失函数就是各个时刻所得的损失之和。 | |
第个时刻RNN隐藏层的输入。 | |
第t个时刻RNN隐藏层的输出。 | |
输出层的输入,即Softmax函数的输入 | |
输入层与隐藏层之间的权重。 | |
上一个时刻的隐藏层 与 当前时刻隐藏层之间的权值。 | |
隐藏层与输出层之间的权重。 |
RNN的前向传播过程:
但是RNN,与CNN或者DNN相比,其参数更新是如何实现的呢?这是训练RNN的一个核心问题。请看下篇BPTT。
参考:
李宏毅老师课件