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