LSTM 计算过程推导
(1) LSTM简介
LSTM是常用的循环神经网络(即带有LSTMcell的循环网络),使用的时候也非常方便,在这里想结合论文和代码对LSTM的计算过程做一下介绍。
(2)LSTM笔记
先放一张图(摘自大牛的笔记)
(1)Ct-1 -> Ct (最上面横线,该细胞状态state)只经历了小的线性变换,所以方便信息的向后传递,也就是可以记忆长期序列的原因。
(2)状态的改变是通过门信息控制的,由图上可以看到一个乘法(遗忘门-表示原有状态有的去留)和一个加法(输入门-表示新信息有多少可以加入到状态中)。
(3)遗忘向量的计算(Ht–1为上一个时间戳的隐层,sigmod输出0-1)
(4)新state信息的计算(It是输入门向量,表示新信息的去留)
(5)输出信息的计算(Ot是输出门向量信息)
we put the cell state through tanh (to push the values to be between −1 and 1)
(3)LSTM变体
(1)可以窥视state的LSTM
(2)讲输入门和遗忘门进行关联
(3)Gated Recurrent Unit, or GRU没有了state,只有hidden。
(4)LSTM代码
由上面的原理可以看到三个控制门需要三个需要学习的变量,再加上存储的状态一共四个需要学习的变量。
上面的公式[ht-1, xt]用到了两部分数据,所以定义了两个kernel,kernal用来映射xt, recurrent_kernel用来处理ht-1。
最后得到了门信息 i , f, o分别是输入门,遗忘门,输出们。并且由门信息和[ht-1, xt]得到了细胞的状态c,即记忆状态。
最后用输出门得到该细胞的输出 h = o * self.activation©。
h_tm1 = states[0]
c_tm1 = states[1]
if self.implementation == 1:
if 0 < self.dropout < 1.:
inputs_i = inputs * dp_mask[0]
inputs_f = inputs * dp_mask[1]
inputs_c = inputs * dp_mask[2]
inputs_o = inputs * dp_mask[3]
else:
inputs_i = inputs
inputs_f = inputs
inputs_c = inputs
inputs_o = inputs
x_i = K.dot(inputs_i, self.kernel_i)
x_f = K.dot(inputs_f, self.kernel_f)
x_c = K.dot(inputs_c, self.kernel_c)
x_o = K.dot(inputs_o, self.kernel_o)
if self.use_bias:
x_i = K.bias_add(x_i, self.bias_i)
x_f = K.bias_add(x_f, self.bias_f)
x_c = K.bias_add(x_c, self.bias_c)
x_o = K.bias_add(x_o, self.bias_o)
if 0 < self.recurrent_dropout < 1.:
h_tm1_i = h_tm1 * rec_dp_mask[0]
h_tm1_f = h_tm1 * rec_dp_mask[1]
h_tm1_c = h_tm1 * rec_dp_mask[2]
h_tm1_o = h_tm1 * rec_dp_mask[3]
else:
h_tm1_i = h_tm1
h_tm1_f = h_tm1
h_tm1_c = h_tm1
h_tm1_o = h_tm1
i = self.recurrent_activation(x_i + K.dot(h_tm1_i,
self.recurrent_kernel_i))
f = self.recurrent_activation(x_f + K.dot(h_tm1_f,
self.recurrent_kernel_f))
c = f * c_tm1 + i * self.activation(x_c + K.dot(h_tm1_c,
self.recurrent_kernel_c))
o = self.recurrent_activation(x_o + K.dot(h_tm1_o,self.recurrent_kernel_o))