nn.LSTM输入、输出、参数及pad


1.LSTM的三个输出output, hidden, cell,分别表示什么意思?

https://blog.csdn.net/wangwangstone/article/details/90296461 这里最后的代码中能搞明白。

import torch
import torch.nn as nn             # 神经网络模块
rnn = nn.LSTM(10, 20, 2)  # 输入数据x的向量维数10, 设定lstm隐藏层的特征维度20, 此model用2个lstm层。如果是1,可以省略,默认为1) input = torch.randn(5, 3, 10) # 输入的input为,序列长度seq_len=5, 每次取的minibatch大小,batch_size=3, 
# 数据向量维数=10(仍然为x的维度)。每次运行时取3个含有5个字的句子(且句子中每个字的维度为10进行运行)  # 初始化的隐藏元和记忆元,通常它们的维度是一样的 # 2个LSTM层,batch_size=3, 隐藏层的特征维度20 h0 = torch.randn(2, 3, 20) c0 = torch.randn(2, 3, 20) # 这里有2层lstm,output是最后一层lstm的每个词向量对应隐藏层的输出,其与层数无关,只与序列长度相关 # hn,cn是所有层最后一个隐藏元和记忆元的输出,和层数、隐层大小有关。 output, (hn, cn) = rnn(input, (h0, c0)) ##模型的三个输入与三个输出。三个输入与输出的理解见上三输入,三输出 print(output.size(),hn.size(),cn.size()) #输出:torch.Size([5, 3, 20]) torch.Size([2, 3, 20]) torch.Size([2, 3, 20])

 输入数据格式: (三个输入)

input(seq_len, batch, input_size)

h_0(num_layers * num_directions, batch, hidden_size)

c_0(num_layers * num_directions, batch, hidden_size)

输出数据格式:

output(seq_len, batch, hidden_size * num_directions)

h_n(num_layers * num_directions, batch, hidden_size)

c_n(num_layers * num_directions, batch, hidden_size)

设置batch_first=True:

import torch
import torch.nn as nn 
rnn = nn.LSTM(10, 20, 2,batch_first=True)
input = torch.randn(5, 3, 10)
h0 = torch.randn(2, 5, 20)
c0 = torch.randn(2, 5, 20)
output, (hn, cn) = rnn(input, (h0, c0))
print(output.size(),hn.size(),cn.size())

torch.Size([5, 3, 20]) torch.Size([2, 5, 20]) torch.Size([2, 5, 20])
#可以看到是shape和输入保持一致的
#如果开始设置了批次在前,那么输出时也会批次在前。

 

2.pack_padded_sequence /pad_packed_sequence

https://zhuanlan.zhihu.com/p/34418001?edition=yidianzixun&utm_source=yidianzixun&yidian_docid=0IVwLf60

https://www.cnblogs.com/lindaxin/p/8052043.html

这个还蛮有意思的,通过这个代码我明白了:

import torch
import torch.nn as nn from torch.autograd import Variable from torch.nn import utils as nn_utils batch_size = 2 max_length = 3 hidden_size = 2 n_layers =1 tensor_in = torch.FloatTensor([[1, 2, 3], [1, 0, 0]]).resize_(2,3,1) tensor_in = Variable( tensor_in ) #[batch, seq, feature], [2, 3, 1] seq_lengths = [3,1] # list of integers holding information about the batch size at each sequence step # pack it pack = nn_utils.rnn.pack_padded_sequence(tensor_in, seq_lengths, batch_first=True) # initialize rnn = nn.RNN(1, hidden_size, n_layers, batch_first=True) h0 = Variable(torch.randn(n_layers, batch_size, hidden_size)) #forward out, _ = rnn(pack, h0) # unpack unpacked = nn_utils.rnn.pad_packed_sequence(out) print('111',unpacked)

 输出:

111 (tensor([[[ 0.0217, -0.4686],
         [-0.0132, -0.4441]], [[-0.2905, -0.7984], [ 0.0000, 0.0000]], [[-0.6398, -0.9216], [ 0.0000, 0.0000]]], grad_fn=<CopySlices>), tensor([3, 1])) #中间结果: >>> tensor_in tensor([[[1.], [2.], [3.]], [[1.], [0.], [0.]]]) #输入的是已经添加了batchsize的,是一个三维的 >>> pack PackedSequence(data=tensor([[1.], [1.], [2.], [3.]]), batch_sizes=tensor([2, 1, 1])) #经过压缩之后就可以发现很有意思,它是按照batch压缩的,压缩成一个长序列,然后还有一个batch_size的参数来控制读取。 >>> h0 tensor([[[ 0.2472, 0.2233], [-0.0616, 0.2127]]]) #初始化的隐状态 >>> out PackedSequence(data=tensor([[ 0.0217, -0.4686], [-0.0132, -0.4441], [-0.2905, -0.7984], [-0.6398, -0.9216]], grad_fn=<CatBackward>), batch_sizes=tensor([2, 1, 1])) #这个是未经过pad之前的,可以发现是和pack的结构类似, #为什么变成了二维的呢,是因为hidden_size是二维的

总之是为了lstm的特殊输入,需要先pack,pack之后lstm的output再pad输出。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM