RNN(recurrent neural network,循环神经网络)

全连接神经网络和卷积神经网络模型中,网络结构都是从输入层到隐含层再到输出层,层与层之间是全连接或是部分连接的,但每层的节点之间都是无连接的。考虑这样的一个问题,如果要预测句子的下一个单词是什么,一般用到当前单词以及前面的单词,因为句子前后单词并不是孤立的。这个时候像卷积,全连接神经网络已经不满足我们的需要。我们需要刻画一个序列也就是当前的输出和当前输入以及上一时刻的输出的关系。循环神经网络就是为了解决这样的问题,从网络结构上看,循环神经网络会记忆之前的信息,并利用之前的信息影响后面节点的输出。也就是说循环神经网络隐藏层之间结点是有连接的,隐藏层的输入不仅包括输入层的输出也包括上一时刻隐藏层的输出。

主要解决的问题: 基于全连接的神经网络的方法存在参数太多,无法利用数据中时间序列信息的问题,主要用途是处理和预测序列数据。下图是RNN基本单元,及展开后的结构。


假设输入向量的维度为 x x x,隐藏状态为 n n n,那么下图全连接神经网络的输入大小为 n + x n+x n+x,可以浅显理解为将上一时刻的状态与当前时刻的输入拼接成一个大的向量作为循环体中神经网络的输入。因为该全连接层的输出为当前时刻的状态,于是输出层的结点个数也为 n n n,循环体的个数为 ( n + x ) n + n (n+x)*n+n (n+x)n+n个。

下图清晰的展示了一个循环神经网络前向传播的具体计算过程,需要注意的是下面采用的是向量拼接的方式将上一时刻状态对应的权重和当前时刻输入对应的权重合并,也有的会将上一时刻状态对应的权重和当前时刻输入对应的权重特意分开,但他们的实质是一样的。

LSTM(long short-term memory,长短时记忆网络结构)

在有些问题中,模型仅仅需要短期内的信息来执行当前的任务,比如’天空是(蓝色的)’,推断蓝色。模型不需要记忆这个短语之前的上下文信息,在这样的场景中相关的信息和待预测的词的位置之间间隔很小,循环神经网络可以比较容易的利用先前的信息。
但同样也会有复杂的情况需要结合上下文场景去分析,比如‘这里空气污染十分严重,天空的颜色是(灰色的)’,仅仅根据短期依赖无法解决这个问题。为了解决在复杂的场景中有用的信息间隔有大有小,长短不一,普通的循环神经网络收到限制的问题,LSTM就是为了解决这个问题。

LSTM它是一种特殊的循环体结构,与单一的tanh循环结构不同,LSTM是一种拥有三个门的特殊网络结构。LSTM靠门的结构让信息有选择性的影响神经网络中每个时刻的状态,所谓 门 就是一个使用sigmoid神经网络和一个按位做乘法的操作,这两个操作合在一起就是一个门的结构。当门打开即:(sigmoid神经网络输出位1时),全部信息通过;当门关闭(sigmoid神经网络输出为0时)任何信息都无法通过。

  • 遗忘门作用是为了让循环神经网络忘记之前没有用的信息(调节根据 W f W_f Wf矩阵参数)。 它会根据当前输入的 x t x_t xt和上一时刻输出 h t 1 h_{t-1} ht1决定那一部分记忆需要被遗忘。假设状态 c c c的维度为 n n n。遗忘门会根据当前的输入 x i x_i xi和上一时刻输出 h t 1 h_{t-1} ht1计算一个维度为 n n n的向量 f = s i g m o i d ( W 1 x + W 2 h ) f=sigmoid(W_1x+W_2h) f=sigmoid(W1x+W2h),他在每一维度上的值都在(0,1)范围内,再将上一时刻的状态 c t 1 c_{t-1} ct1 f f f向量相乘,那么f取值接近0的维度上的信息就会被忘记,而 f f f取值接近于1的维度上的信息就会被保留。
  • 输入门在循环神经网络忘记了部分之前的状态后,它还需要从当前的输入补充最新的记忆。 它会根据 x t x_t xt h t 1 h_{t-1} ht1决定哪些信息要被加入到状态 c t 1 c_{t-1} ct1中生成新的状态 c t c_t ct
  • 输出门:LSTM结构在计算到新的状态 c t c_t ct后需要产生当前时刻的输出,这个过程是通过输出门来完成的。输出门会根据最新的状态 c t c_t ct,上一时刻的输出 h t 1 h_{t-1} ht1和当前的输入 x t x_t xt来决定改时刻的输出 h t h_t ht


z = t a n h ( W z [ h t 1 , x t ] ) z=tanh(W_z[h_{t-1},x_t]) (输入值) z=tanh(Wz[ht1,xt]) i = s i g m o i d ( W i [ h t 1 , x t ] ) i=sigmoid(W_i[h_{t-1},x_t])(输入门) i=sigmoid(Wi[ht1,xt]) f = s i g m o i d ( W f [ h t 1 , x t ] ) f=sigmoid(W_f[h_{t-1},x_t])(遗忘门) f=sigmoid(Wf[ht1,xt]) o = s i g m o i d ( W o [ h t 1 , x t ] ) o=sigmoid(W_o[h_{t-1},x_t])(输出门) o=sigmoid(Wo[ht1,xt]) c t = f c t 1 + i z c_t=f\cdot c_{t-1} + i\cdot z(新状态) ct=fct1+iz h t = o t a n h ( c t ) h_t=o \cdot tanh(c_t)(输出) ht=otanh(ct)

解析LSTM工作原理:

  • 第一步是用来决定什么信息可以通过cell state。这个决定由“forget gate”层通过sigmoid来控制,它会根据上一时刻的输出和当前输入来产生一个0到1 的值,来决定是否让上一时刻学到的信息通过或部分通过。 f = s i g m o i d ( W f [ h t 1 , x t ] ) f=sigmoid(W_f[h_{t-1},x_t])(遗忘门) f=sigmoid(Wf[ht1,xt])

  • 第二步是产生我们需要更新的新信息。这一步包含两部分,第一个是一个“input gate”层通过sigmoid来决定哪些值用来更新,第二个是一个tanh层用来生成新的候选值即 i z i \cdot z iz z = t a n h ( W z [ h t 1 , x t ] ) z=tanh(W_z[h_{t-1},x_t]) (输入值) z=tanh(Wz[ht1,xt]) i = s i g m o i d ( W i [ h t 1 , x t ] ) i=sigmoid(W_i[h_{t-1},x_t])(输入门) i=sigmoid(Wi[ht1,xt])

  • 第三步结合第一第二步更新Cell也就是状态C。 c t = f c t 1 + i z c_t=f\cdot c_{t-1} + i\cdot z(新状态) ct=fct1+iz

  • 最后一步是决定模型的输出,首先是通过sigmoid层来得到一个初始输出,然后使用tanh将 值缩放到-1到1间,再与sigmoid得到的输出逐对相乘,从而得到模型的输出。 h t = o t a n h ( c t ) h_t=o \cdot tanh(c_t)(输出门) ht=otanh(ct)

小结

这里仅仅简单的讨论了下RNN,LSTM的结构和原理,具体的优化求解并没有提到,说到的LSTM只是最基本的,事实上LSTM在不同的论文中都有略微的变种。

参考:TensorFlow实战Google深度学习框架


这段时间在学习深度模型算***继续更新一些算法内容,更多的是自己对模型的理解,按自己的理解把其中一些的知识总结到博客上,一方面为了方便以后查阅,另一方面分享自己觉得有用的东西,希望能及时解决大家疑惑。如果有错误欢迎大家留言指正,一起学习进步。