pytorch-LSTM()
torch.nn包下實現了LSTM函數,實現LSTM層。多個LSTMcell組合起來是LSTM。
LSTM自動實現了前向傳播,不需要自己對序列進行迭代。
LSTM的用到的參數如下:創建LSTM指定如下參數,至少指定前三個參數
input_size:
輸入特征維數
hidden_size:
隱層狀態的維數
num_layers:
RNN層的個數,在圖中豎向的是層數,橫向的是seq_len
bias:
隱層狀態是否帶bias,默認為true
batch_first:
是否輸入輸出的第一維為batch_size,因為pytorch中batch_size維度默認是第二維度,故此選項可以將 batch_size放在第一維度。如input是(4,1,5),中間的1是batch_size,指定batch_first=True后就是(1,4,5)
dropout:
是否在除最后一個RNN層外的RNN層后面加dropout層
bidirectional:
是否是雙向RNN,默認為false,若為true,則num_directions=2,否則為1
為了統一,以后都batch_first=True
LSTM的輸入為:LSTM(input,(h0,co))
其中,指定batch_first=True
后,input就是(batch_size,seq_len,input_size)
(h0,c0)是初始的隱藏層,因為每個LSTM單元其實需要兩個隱藏層的。記hidden=(h0,c0)
其中,h0的維度是(num_layers*num_directions, batch_size, hidden_size)
c0維度同h0。注意,即使batch_first=True
,這里h0的維度依然是batch_size在第二維度
LSTM的輸出為:out,(hn,cn)
其中,out是每一個時間步的最后一個隱藏層h的輸出,假如有5個時間步(即seq_len=5),則有5個對應的輸出,out的維度是:(batch_size,seq_len,hidden_size)
而hidden=(hn,cn)
,他自己實現了時間步的迭代,每次迭代需要使用上一步的輸出和hidden層,最后一步hidden=(hn,cn)
記錄了最后一各時間步的隱藏層輸出,有幾層對應幾個輸出,如果這個是RNN-encoder,則hn,cn就是中間的編碼向量。hn的維度是(num_layers*num_directions,batch_size,hidden_size),cn同。
應用LSTM
創建一LSTM:
lstm = torch.nn.LSTM(input_size,hidden_size,num_layers,batch_first=True)
forward使用LSTM層:
out,hidden = lstm(input,hidden)
其中,hidden=(h0,c0)
是個tuple
最終得到out,hidden
舉例:
import torch
# 實現一個num_layers層的LSTM-RNN
class RNN(torch.nn.Module):
def __init__(self,input_size, hidden_size, num_layers):
super(RNN,self).__init__()
self.input_size = input_size
self.hidden_size=hidden_size
self.num_layers=num_layers
self.lstm = torch.nn.LSTM(input_size=input_size,hidden_size=hidden_size,num_layers=num_layers,batch_first=True)
def forward(self,input):
# input應該為(batch_size,seq_len,input_szie)
self.hidden = self.initHidden(input.size(0))
out,self.hidden = lstm(input,self.hidden)
return out,self.hidden
def initHidden(self,batch_size):
if self.lstm.bidirectional:
return (torch.rand(self.num_layers*2,batch_size,self.hidden_size),torch.rand(self.num_layers*2,batch_size,self.hidden_size))
else:
return (torch.rand(self.num_layers,batch_size,self.hidden_size),torch.rand(self.num_layers,batch_size,self.hidden_size))
input_size = 12
hidden_size = 10
num_layers = 3
batch_size = 2
model = RNN(input_size,hidden_size,num_layers)
# input (seq_len, batch, input_size) 包含特征的輸入序列,如果設置了batch_first,則batch為第一維
input = torch.rand(2,4,12)
model(input)