• torch.nn中LSTM使用


    一、pytorch中LSTM实现原理:

    对于输入序列中的每个元素,每层计算以下函数:
    i t = σ ( W i i x t + b i i + W h i h t − 1 + b h i ) i_t = \sigma(W_{ii}x_t + b_{ii} + W_{hi}h_{t-1}+b_{hi}) it=σ(Wiixt+bii+Whiht1+bhi)
    f t = σ ( W i f x t + b i f + W h f h t − 1 + b h f ) f_t = \sigma(W_{if}x_t + b_{if} + W_{hf}h_{t-1}+b_{hf}) ft=σ(Wifxt+bif+Whfht1+bhf)
    o t = σ ( W i o x t + b i o + W h o h t − 1 + b h o ) o_t = \sigma(W_{io}x_t + b_{io} + W_{ho}h_{t-1}+b_{ho}) ot=σ(Wioxt+bio+Whoht1+bho)
    g t = t a n h ( W i g x t + b i g + W h g h t − 1 + b h g ) g_t=tanh(W_{ig}x_t + b_{ig} + W_{hg}h_{t-1} + b_{hg}) gt=tanh(Wigxt+big+Whght1+bhg)
    c t = f t ⊙ c t − 1 + i t ⊙ g t c_t=f_t \odot c_{t-1} + i_t \odot g_t ct=ftct1+itgt
    h t = o t ⊙ t a n h ( c t ) h_t = o_t \odot tanh(c_t) ht=ottanh(ct)
    其中各个变量的含义如下:

    • h t h_t ht:表示在t时间步的hidden state
    • c t c_t ct:表示在t时间步的cell state
    • x t x_t xt:表示在t时间步的输入
    • h t − 1 h_{t-1} ht1:表示在上个时间步的hidden state 或者在初始时间步的hidden state
    • i t i_t it, f t f_t ft, o t o_t ot表示输入门,遗忘门,输出门
    • σ \sigma σ:表示sigmoid函数
    • ⊙ \odot :表示点积
      在多层LSTM中, 第 l l l层的输入 x t ( l ) x_t^{(l)} xt(l)( l l l>=2)来自于前一层对应时间步的hidden state做dorpout的结果。
    二、参数
    1. 初始化参数
    • input_size:输入x的 维度
    • hidden_size:hidden state 的维度
    • num_layers:LSTM堆叠层数,设置num_layers=2 的话,表示堆叠两层LSTM到一起,第二个 LSTM 接收第一个 LSTM 的输出并计算最终结果;默认为1
    • bias:如果是False,将不再加入 b_h和b_hh,默认为True
    • batch_first:如果为True,则输入和输出的tensors的维度为(batch,seq,feature)而不是(seq,batch,feature)。注意:此标识只对output有效,对hidden state 和 cell state无效,默认为False
    • dorpout:如果为非0,在每个 LSTM 层(最后一层除外)的输出上引入一个dropout层,dropout概率等于此参数值。默认值:0,只对多层LSTM有效。
    • bidirectional:如果为True,则是双向LSTM,默认为False
    • proj_size:如果>0,将使用具有相应大小的投影的 LSTM。
    2. forward入参
    • Input:单个样本(unbatched)输入,则形状为 ( L , H i n ) (L, H_{in}) (L,Hin);batch_first=False,则形状为 ( L , N , H i n ) (L,N,H_{in}) (L,N,Hin);batch_first=True,则形状为 ( N , L , H i n ) (N,L,H_{in}) (N,L,Hin)。输入也可以是打包的可变长度序列。参考packedtorch.nn.utils.rnn.pack_padded_sequence() h或者torch.nn.utils.rnn.pack_sequence() 方法。
    • h_0:单个样本(unbatched)输入,形状为 ( D ∗ n u m l a y e r s , H o u t ) (D*num_layers, H_out) (Dnumlayers,Hout);batch样本输入,则形状为 ( D ∗ n u m l a y e r s , N , H o u t ) (D*num_layers, N, H_out) (Dnumlayers,N,Hout)也就是初始化的hidden state, 默认为0(h_0, c_0)。
    • c_0:单个样本(unbatched)输入,形状为 ( D ∗ n u m l a y e r s , H c e l l ) (D*num_layers, H_cell) (Dnumlayers,Hcell);batch样本输入,则形状为 ( D ∗ n u m l a y e r s , N , H c e l l ) (D*num_layers, N, H_cell) (Dnumlayers,N,Hcell)也就是初始化的hidden state, 默认为0(h_0, c_0)。
      其中:
    • N=batch size
    • L=sequence length
    • D=2 if bidirectional=True otherwise 1
    • H i n H_{in} Hin=input_size
    • H c e l l H_{cell} Hcell=hidden_size
    • H o u t H_{out} Hout=hidden_size
    3. 输出
    • output:单个样本(unbatched)输入,则形状为 ( L , D ∗ H o u t ) (L, D*H_{out}) (L,DHout);batch_first=False,则形状为 ( L , N , D ∗ H o u t ) (L,N,D*H_{out}) (L,N,DHout);batch_first=True,则形状为 ( N , L , D ∗ H o u t ) (N,L,D*H_{out}) (N,L,DHout)。输入也可以是打包的可变长度序列。参考packedtorch.nn.utils.rnn.pack_padded_sequence() h或者torch.nn.utils.rnn.pack_sequence() 方法。
    • h_0:单个样本(unbatched)输入,形状为 ( D ∗ n u m l a y e r s , H o u t ) (D*num_layers, H_out) (Dnumlayers,Hout);batch样本输入,则形状为 ( D ∗ n u m l a y e r s , N , H o u t ) (D*num_layers, N, H_out) (Dnumlayers,N,Hout),包含序列中每个元素的最终隐藏状态。当双向 = True 时,h_n将分别包含最终正向和反向隐藏状态的串联。
    • c_0:单个样本(unbatched)输入,形状为 ( D ∗ n u m l a y e r s , H c e l l ) (D*num_layers, H_cell) (Dnumlayers,Hcell);batch样本输入,则形状为 ( D ∗ n u m l a y e r s , N , H c e l l ) (D*num_layers, N, H_cell) (Dnumlayers,N,Hcell),包含序列中每个元素的最终cell状态。
    三、实例
    1)
    import torch.nn as nn
    import torch
    rnn = nn.LSTM(10, 20, 2)# embedding_size, hidden_size, num_layer
    input = torch.randn(5, 3, 10)# sequence length, batch size, embedding_size
    h0 = torch.randn(2, 3, 20)# num_layer*dirc, batch size, hidden_size
    c0 = torch.randn(2, 3, 20)# num_layer*dirc, batch size, hidden_size
    output, (hn, cn) = rnn(input, (h0, c0))
    output.shape
    Out[8]: torch.Size([5, 3, 20])# # sequence length, batch size, hidden_size
    hn.shape
    Out[9]: torch.Size([2, 3, 20])# num_layer*dirc, batch size, hidden_size
    c0.shape
    Out[10]: torch.Size([2, 3, 20])# num_layer*dirc, batch size, hidden_size
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    2)
    rnn = nn.LSTM(input_size=1, hidden_size=20, num_layers=2)
    input = torch.tensor([[1,2,0], [3,0,0], [4,5,6]], dtype=torch.float)
    lens = [2, 1, 3]
    # 构建输入数据,维度为:torch.Size([3, 3, 1]), 即 bactch_size=3, sequence length=3, embedding size=1
    input = input.unsqueeze(2)
    input
    Out[68]: 
    tensor([[[1.],
             [2.],
             [0.]],
            [[3.],
             [0.],
             [0.]],
            [[4.],
             [5.],
             [6.]]])
    # 第一维是 batch,则batch_first=True,
    padded_seq = pack_padded_sequence(input, lens, batch_first=True, enforce_sorted=False)
    # 将 padded_seq输入,并且不对hidden和cell进行初始化
    output, (hn, cn) = rnn(padded_seq)
    # 进行逆操作拆箱
    output = pad_packed_sequence(output, batch_first=True)
    # output[0] LSTM输出,output[1]为batch中样本长度
    output[0].shape
    Out[72]: torch.Size([3, 3, 20])
    output[1]
    Out[73]: tensor([2, 1, 3])
    hn.shape
    Out[76]: torch.Size([2, 3, 20])
    cn.shape
    Out[77]: torch.Size([2, 3, 20])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    未完待续。。。

  • 相关阅读:
    Android框架mqtt库无法兼容高版本android13的问题
    RabbitMQ 死信队列详解
    在 Ubuntu 22 的基础上进行 Hadoop 伪分布式(HDFS)的搭建
    els 方块停在方块上。
    js_this是对象_和预期的结果不一致
    立体多层玫瑰绘图源码__玫瑰花python 绘图源码集锦
    正则匹配绕过总计之[极客大挑战 2019]RCE ME
    pdf怎么转换成jpg图片或png图片
    45部署LVS-DR群集
    HTML案例-1.标签练习
  • 原文地址:https://blog.csdn.net/weixin_36893273/article/details/127230121