pytorch lstm训练例子,pytorch lstm实现

  pytorch lstm训练例子,pytorch lstm实现

  本文主要介绍PyTorch深度学习LSTM从输入输入到线性输出的深度理解。有需要的朋友可以借鉴一下,希望能有所帮助。祝大家进步很大,早日升职加薪。

  

目录
LSTM介绍LSTM参数InputsOutputsbatch _ first的情况

  

LSTM介绍

  关于LSTM的具体原理,请参考:

  https://www.jb51.net/article/178582.htm

  https://www.jb51.net/article/178423.htm

  系列文章:

  PyTorch构建双向LSTM实现时序负荷预测

  PyTorch构建LSTM实现多变量多步长时序负荷预测

  PyTorch建成LSTM实现多变量时序负荷预测

  PyTorch建设LSTM实现时序负荷预测

  

LSTM参数

  关于神经网络的参数。LSTM在官方文件中给出的解释是:

  总共有七个参数,其中只有前三个是必需的。由于PyTorch的DataLoader被广泛用于形成批量数据,batch_first也很重要。LSTM的两个常见应用场景是文本处理和时间序列预测,下面我将从这两个方面详细讲解每个参数。

  Input_size:在文本处理中,因为一个单词不能参与运算,所以我们要通过Word2Vec来嵌入这个单词,把每个单词表示成一个向量。这时input_size=embedding_size。比如每个句子有五个单词,每个单词用一个100维的向量表示,所以这里input _ size=100在时间序列预测中,比如负荷预测,每个负荷都是一个单独的值,可以直接参与计算,所以不需要把每个负荷都表示成一个向量。此时,input_size=1。但如果用多元预测,比如我们用前24小时每个时刻的【负荷、风速、温度、压力、湿度、天气、节假日信息】来预测下一时刻的负荷,那么此时input_size=7。Hidden_size:隐藏层节点的数量。你可以随意设置。Num_layers:层数。Nn。LSTMCell与nn比较。默认情况下,LSTM的层数为1。Batch_first:默认值为False,其含义稍后描述。

  

Inputs

  关于LSTM的投入,官方文件给出了如下定义:

  如你所见,输入由两部分组成:输入,(初始隐藏状态h_0,初始单元状态c_0)

  其中输入:

  输入(序列长度,批量大小,输入大小)

  Seq_len:在文本处理中,如果一个句子有7个单词,那么seq _ len=7;在时间序列预测中,假设我们用前24小时的负荷来预测下一时刻的负荷,那么seq_len=24。Batch_size:输入LSTM一次的样品数量。在文本处理中,可以一次输入很多句子;在时间序列预测中,还可以一次输入多条数据。Input_size:见上。(h_0,c_0):

  h_0(方向数*层数,批量大小,隐藏大小)

  c_0(方向数*层数,批量大小,隐藏大小)

  h0和c0的形状相同。

  Num_directions:如果是双向LSTM,那么num _ directions=2;否则,数量方向=1。Num_layers:见上一篇文章。Batch_size:见上一篇文章。Hidden_size:见上一篇文章。

  

Outputs

  关于LSTM的产量,官方文件给出的定义

  为:

  

  可以看到,输出也由两部分组成:otput、(隐状态h_n,单元状态c_n)

  其中output的shape为:

  

output(seq_len, batch_size, num_directions * hidden_size)

  h_n和c_n的shape保持不变,参数解释见前文。

  

  

batch_first

  如果在初始化LSTM时令batch_first=True,那么input和output的shape将由:

  

input(seq_len, batch_size, input_size)

  output(seq_len, batch_size, num_directions * hidden_size)

  

  变为:

  

input(batch_size, seq_len, input_size)

  output(batch_size, seq_len, num_directions * hidden_size)

  

  即batch_size提前。

  

  

案例

  简单搭建一个LSTM如下所示:

  

class LSTM(nn.Module):

   def __init__(self, input_size, hidden_size, num_layers, output_size, batch_size):

   super().__init__()

   self.input_size = input_size

   self.hidden_size = hidden_size

   self.num_layers = num_layers

   self.output_size = output_size

   self.num_directions = 1 # 单向LSTM

   self.batch_size = batch_size

   self.lstm = nn.LSTM(self.input_size, self.hidden_size, self.num_layers, batch_first=True)

   self.linear = nn.Linear(self.hidden_size, self.output_size)

   def forward(self, input_seq):

   h_0 = torch.randn(self.num_directions * self.num_layers, self.batch_size, self.hidden_size).to(device)

   c_0 = torch.randn(self.num_directions * self.num_layers, self.batch_size, self.hidden_size).to(device)

   seq_len = input_seq.shape[1] # (5, 30)

   # input(batch_size, seq_len, input_size)

   input_seq = input_seq.view(self.batch_size, seq_len, 1) # (5, 30, 1)

   # output(batch_size, seq_len, num_directions * hidden_size)

   output, _ = self.lstm(input_seq, (h_0, c_0)) # output(5, 30, 64)

   output = output.contiguous().view(self.batch_size * seq_len, self.hidden_size) # (5 * 30, 64)

   pred = self.linear(output) # pred(150, 1)

   pred = pred.view(self.batch_size, seq_len, -1) # (5, 30, 1)

   pred = pred[:, -1, :] # (5, 1)

   return pred

  

  其中定义模型的代码为:

  

self.lstm = nn.LSTM(self.input_size, self.hidden_size, self.num_layers, batch_first=True)

  self.linear = nn.Linear(self.hidden_size, self.output_size)

  

  我们加上具体的数字:

  

self.lstm = nn.LSTM(self.input_size=1, self.hidden_size=64, self.num_layers=5, batch_first=True)

  self.linear = nn.Linear(self.hidden_size=64, self.output_size=1)

  

  再看前向传播:

  

def forward(self, input_seq):

   h_0 = torch.randn(self.num_directions * self.num_layers, self.batch_size, self.hidden_size).to(device)

   c_0 = torch.randn(self.num_directions * self.num_layers, self.batch_size, self.hidden_size).to(device)

   seq_len = input_seq.shape[1] # (5, 30)

   # input(batch_size, seq_len, input_size)

   input_seq = input_seq.view(self.batch_size, seq_len, 1) # (5, 30, 1)

   # output(batch_size, seq_len, num_directions * hidden_size)

   output, _ = self.lstm(input_seq, (h_0, c_0)) # output(5, 30, 64)

   output = output.contiguous().view(self.batch_size * seq_len, self.hidden_size) # (5 * 30, 64)

   pred = self.linear(output) # (150, 1)

   pred = pred.view(self.batch_size, seq_len, -1) # (5, 30, 1)

   pred = pred[:, -1, :] # (5, 1)

   return pred

  

  假设用前30个预测下一个,则seq_len=30,batch_size=5,由于设置了batch_first=True,因此,输入到LSTM中的input的shape应该为:

  

input(batch_size, seq_len, input_size) = input(5, 30, 1)

  

  但实际上,经过DataLoader处理后的input_seq为:

  

input_seq(batch_size, seq_len) = input_seq(5, 30)

  

  (5, 30)表示一共5条数据,每条数据的维度都为30。为了匹配LSTM的输入,我们需要对input_seq的shape进行变换:

  

input_seq = input_seq.view(self.batch_size, seq_len, 1) # (5, 30, 1)

  

  然后将input_seq送入LSTM:

  

output, _ = self.lstm(input_seq, (h_0, c_0)) # output(5, 30, 64)

  根据前文,output的shape为:

  

output(batch_size, seq_len, num_directions * hidden_size) = output(5, 30, 64)

  全连接层的定义为:

  

self.linear = nn.Linear(self.hidden_size=64, self.output_size=1)

  因此,我们需要将output的第二维度变换为64(150, 64):

  

output = output.contiguous().view(self.batch_size * seq_len, self.hidden_size) # (5 * 30, 64)

  然后将output送入全连接层:

  

pred = self.linear(output) # pred(150, 1)

  得到的预测值shape为(150, 1)。我们需要将其进行还原,变成(5, 30, 1):

  

pred = pred.view(self.batch_size, seq_len, -1) # (5, 30, 1)

  在用DataLoader处理了数据后,得到的input_seq和label的shape分别为:

  

input_seq(batch_size, seq_len) = input_seq(5, 30)label(batch_size, output_size) = label(5, 1)

  由于输出是输入右移,我们只需要取pred第二维度(time)中的最后一个数据:

  

pred = pred[:, -1, :] # (5, 1)

  这样,我们就得到了预测值,然后与label求loss,然后再反向更新参数即可。

  时间序列预测的一个真实案例请见:PyTorch搭建LSTM实现时间序列预测(负荷预测)

  以上就是PyTorch深度学习LSTM从input输入到Linear输出的详细内容,更多关于LSTM input输入Linear输出的资料请关注盛行IT软件开发工作室其它相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: