LSTM详解

LSTM详解

文章目录

LSTM是RNN的一种变种,可以有效地解决RNN的梯度爆炸或者消失问题。关于RNN可以参考作者的另一篇文章https://blog.csdn.net/qq_40922271/article/details/120965322

LSTM的改进在于增加了新的记忆单元与门控机制

改进

记忆单元

LSTM进入了一个新的 记忆单元c t c_t c t ​,用于进行线性的循环信息传递,同时输出信息给隐藏层的 外部状态h t h_t h t ​。在每个时刻t t t,c t c_t c t ​记录了到当前时刻为止的历史信息。

门控机制

LSTM引入门控机制来控制信息传递的路径,类似于数字电路中的门,0即关闭,1即开启。

LSTM中的三个门为 遗忘门f t f_t f t ​, 输入门i t i_t i t ​和 输出门o t o_t o t ​

  • f t f_t f t ​控制上一个时刻的记忆单元c t − 1 c_{t-1}c t −1 ​需要遗忘多少信息
  • i t i_t i t ​控制当前时刻的候选状态c ~ t \tilde{c}_t c ~t ​有多少信息需要存储
  • o t o_t o t ​控制当前时刻的记忆单元c t c_t c t ​有多少信息需要输出给外部状态h t h_t h t ​

下面我们就看看改进的新内容在LSTM的结构中是如何体现的。

LSTM结构

如图一所示为LSTM的结构,LSTM网络由一个个的LSTM单元连接而成。

LSTM详解

图一

图二描述了图一中各种元素的图标,从左到右分别为, 神经网络(σ 表 示 s i g m o i d \sigma表示sigmoid σ表示s i g m o i d)、 向量元素操作(× \times ×表示向量元素乘,+ ++表示向量加), 向量传输的方向向量连接向量复制

LSTM详解

图二

LSTM 的关键就是记忆单元,水平线在图上方贯穿运行。

记忆单元类似于传送带。直接在整个链上运行,只有一些少量的线性交互。信息在上面流传保持不变会很容易。

LSTM详解

; LSTM的计算过程

遗忘门

LSTM详解

在这一步中,遗忘门读取h t − 1 h_{t-1}h t −1 ​和x t x_t x t ​,经由sigmoid,输入一个在0到1之间数值给每个在记忆单元c t − 1 c_{t-1}c t −1 ​中的数字,1表示完全保留,0表示完全舍弃。

; 输入门

LSTM详解

输入门将确定什么样的信息内存放在记忆单元中,这里包含两个部分。

  1. sigmoid层同样输出[0,1]的数值,决定候选状态c ~ t \tilde{c}_t c ~t ​有多少信息需要存储
  2. tanh层会创建候选状态c ~ t \tilde{c}_t c ~t ​

更新记忆单元

随后更新旧的细胞状态,将c t − 1 c_{t-1}c t −1 ​更新为c t c_t c t ​

LSTM详解

首先将旧状态c t − 1 c_{t-1}c t −1 ​与f t f_t f t ​相乘,遗忘掉由f t f_t f t ​所确定的需要遗忘的信息,然后加上i t ∗ c ~ t i_t*\tilde{c}_t i t ​∗c ~t ​,由此得到了新的记忆单元c t c_t c t ​

; 输出门

结合输出门o t o_t o t ​将内部状态的信息传递给外部状态h t h_t h t ​。同样传递给外部状态的信息也是个过滤后的信息,首先sigmoid层确定记忆单元的那些信息被传递出去,然后,把细胞状态通过 tanh层 进行处理(得到[-1,1]的值)并将它和输出门的输出相乘,最终外部状态仅仅会得到输出门确定输出的那部分。

LSTM详解

通过LSTM循环单元,整个网络可以建立较长距离的时序依赖关系,以上公式可以简洁地描述为

[ c ~ t o t i t f t ] = [ t a n h σ σ σ ] ( W [ x t h t − 1 ] + b ) \begin{bmatrix} \tilde{c}t \ o_t \ i_t \ f_t \end{bmatrix} = \begin{bmatrix} tanh \ \sigma \ \sigma \ \sigma \end{bmatrix} \begin{pmatrix} W \begin{bmatrix} x_t \ h{t-1} \end{bmatrix} +b \end{pmatrix}⎣⎢⎢⎡​c ~t ​o t ​i t ​f t ​​⎦⎥⎥⎤​=⎣⎢⎢⎡​t a n h σσσ​⎦⎥⎥⎤​(W [x t ​h t −1 ​​]+b ​)

c t = f t ⊙ c t − 1 + i t ⊙ c ~ t c_t=f_t \odot c_{t-1}+i_t \odot \tilde{c}_t c t ​=f t ​⊙c t −1 ​+i t ​⊙c ~t ​

h t = o t ⊙ t a n h ( c t ) h_t=o_t \odot tanh(c_t)h t ​=o t ​⊙t a n h (c t ​)

LSTM单元的pytorch实现

下面通过手写LSTM单元加深对LSTM网络的理解

class LSTMCell(nn.Module):
    def __init__(self, input_size, hidden_size, cell_size, output_size):
        super().__init__()
        self.hidden_size = hidden_size
        self.cell_size = cell_size

        self.gate = nn.Linear(input_size+hidden_size, cell_size)
        self.output = nn.Linear(hidden_size, output_size)
        self.sigmoid = nn.Sigmoid()
        self.tanh = nn.Tanh()
        self.softmax = nn.LogSoftmax(dim=1)

    def forward(self, input, hidden, cell):

        combined = torch.cat((input, hidden), 1)

        f_gate = self.sigmoid(self.gate(combined))

        i_gate = self.sigmoid(self.gate(combined))
        z_state = self.tanh(self.gate(combined))

        o_gate = self.sigmoid(self.gate(combined))

        cell = torch.add(torch.mul(cell, f_gate), torch.mul(z_state, i_gate))

        hidden = torch.mul(self.tanh(cell), o_gate)
        output = self.output(hidden)
        output = self.softmax(output)
        return output, hidden, cell

    def initHidden(self):
        return torch.zeros(1, self.hidden_size)

    def initCell(self):
        return torch.zeros(1, self.cell_size)

Pytorch中的LSTM

CLASS torch.nn.LSTM(*args, **kwargs)

参数

  • input_size – 输入特征维数
  • hidden_size – 隐含状态h h h的维数
  • num_layers – RNN层的个数:(在竖直方向堆叠的多个相同个数单元的层数),默认为1
  • bias – 隐层状态是否带bias,默认为true
  • batch_first – 是否输入输出的第一维为batchsize
  • dropout – 是否在除最后一个RNN层外的RNN层后面加dropout层
  • bidirectional –是否是双向RNN,默认为false
  • proj_size – If > 0, will use LSTM with projections of corresponding size. Default: 0

其中比较重要的参数就是 hidden_sizenum_layers,hidden_size所代表的就是LSTM单元中神经元的个数。从知乎截来的一张图,通过下面这张图我们可以看出num_layers所代表的含义,就是depth的堆叠,也就是有几层的隐含层。可以看到output是最后一层layer的hidden输出的组合

LSTM详解

; 输入

 input, (h_0, c_0)
  • input: (seq_len, batch, input_size) 时间步数或序列长度,batch数,输入特征维度。如果设置了batch_first,则batch为第一维
  • h_0: shape(num_layers * num_directions, batch, hidden_size) containing the initial hidden state for each element in the batch. Defaults to zeros if (h_0, c_0) is not provided.

  • c_0: shape(num_layers * num_directions, batch, hidden_size)containing the initial cell state for each element in the batch. Defaults to zeros if (h_0, c_0) is not provided.

输出

output, (h_n, c_n)
  • output: (seq_len, batch, hidden_size * num_directions) 包含每一个时刻的输出特征,如果设置了batch_first,则batch为第一维
  • h_n: shape(num_layers * num_directions, batch, hidden_size) containing the final hidden state for each element in the batch.

  • c_n: shape (num_layers * num_directions, batch, hidden_size) containing the final cell state for each element in the batch.

h与c维度中的num_direction,如果是单向循环网络,则num_directions=1,双向则num_directions=2

参考与摘录

https://blog.csdn.net/qq_40728805/article/details/103959254

https://zhuanlan.zhihu.com/p/79064602

https://www.jianshu.com/p/9dc9f41f0b29

Original: https://blog.csdn.net/qq_40922271/article/details/120961760
Author: LOD1987
Title: LSTM详解

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/628856/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球