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))
        

猜你喜欢

转载自blog.csdn.net/cyinfi/article/details/87309576