Pytorch的LSTM(RNN)是如何處理Sequence的__關於input中seq_len以及輸入格式的總結


近幾天處理了幾天卷積LSTM,操作的數據格式太復雜,驀然回首,突然發現自己不明白LSTM中的輸入格式是什么了,於是寫一篇文章幫助自己回憶一下,也希望能幫助到一起正在機器學習的伙伴。補充一下,在LSTM之后,GRU和LSTM幾乎已經取代了傳統的RNN,因此在稱呼RNN的時候,大多數情況也是在稱呼LSTM,下文中可能會提到RNN,也是在說LSTM

按照Pytorch 給的文檔里格式寫一個LSTM

# author: https://www.cnblogs.com/danielkung/
lstm = torch.nn.LSTM(input_size,            # INT,輸入的維度
                     hidden_size,           # INT,隱藏層的維度
                     num_layers,            # INT,LSTM的層數
                     bias,                  # BOOL,是否需要wx+b中的b
                     batch_first,           # BOOL,輸入的數據第一維度為batch,與輸出無關
                     dropout,               # BOOL,是否需要dropout
                     bidirectional)         # BOOL,是否雙向RNN,是的話hidden,output都雙倍
intput = torch.randn(seq_len, batch, input_size)      # 三個參數需要定義
output, hidden = lstm(input)

Q:在處理了無數次以后,我終於有一次懵圈了,啥是seq_len來着?

A:seq_len就是輸入的sequence_length(序列長度),既然LSTM是處理序列數據的,那么序列就需要一個長度。雖然LSTM處理的序列長度通常是不固定的,但是Pytorch和TensorFlow的集成實現還是固定了input的序列長度,在處理不固定長度的數據(如機器翻譯),通常加入開始和結束符號 並采用序列的最大長度MAX_LEN作為seq_len

來看幾個實際的例子:

1. 輸入長度不固定,輸出長度固定

我想做一個語句的情感分析(positve,negtive),或者給一串數字,預測這串數字的下一個數字是什么(例如某串長度為N,預測第N+1數字是什么)。

在第一個問題中,假設我們拿到了N條數據,每條包含的字數不定,但是可以知道最長的字數為MAX_LEN。首先我們需要進行word embedding,即把每個詞轉變為長度固定的矩陣。假如每個word被轉化為 [1*128] 的矩陣,那我們得到的數據格式就為:

[N, MAX_LEN+2, 128]

此時你也許會問,那長度不夠MAX_LEN的呢?不夠的就被填充到MAX_LEN,並且多的2是開頭和結尾的'sos''eos'。

然后在LSTM中,我們每次取N條中的batch_size條進行訓練,並且input的seq_len就是MAX_LEN+2。代碼:

# author: https://www.cnblogs.com/danielkung/
import torch

input_size = 128      # 輸入的維度,就是我們word_embedding的長度
hidden_size = 64      # 這里我自己定義的,定義的是lstm的hidden也是輸出的維度
num_layers = 1        # 先定義一層的LSTM

lstm = torch.nn.LSTM(input_size, hidden_size, num_layers)
input = getFromDataSet()      # 函數沒定義,就是從data中取batch條數據,input的shape:[seq_len, batch_size, input_size]=[MAX_LEN+2, batch, 128]
output, hidden = lstm(input, hidden=None)      # Pytorch的LSTM會自己初始化hidden,因此hidden不寫一樣

output1 = output[-1]      # 取最后一層的輸出作為最終輸出,因為只有一層LSTM,output[-1]==output[0]
print(output.shape)
# RETURN: [seq_len, batch_size, hidden_size]

這里發現如果是做postive或者negtive分析的話,我們只需要一個數值,甚至只需要一個BOOL,因此還需要把輸出的output結果取最后一份output[-1],然后通過MLP即可,具體分析如圖。

代碼接上面繼續:

fc = nn.Linear(hidden_size, 1)
last_cell = outpu1t[-1]      # shape: [batch_size, hidden_size]
# 由圖可見, 此時的last_cell就是LSTM的最后一次的輸出結果。
res = fc(last_cell)      # shape: [batch_size, 1]
# 由此就得出了所有所有batch的預測結果。

Q:可能有人要問,輸出了那么多的output,只取最后一個用,這樣准確嗎?不浪費嗎?
A:不准,浪費。但是可以這么處理。在早期的sequence_to_sequence模型中,就是把encoder RNN的最后一個cell的輸出作為context傳給decoder,當然后來還有更好的辦法,如attention mechanism。在這里只展示最簡單的。

2. 輸入長度不固定,輸出長度不固定

如果輸出長度不固定,我們只需要把<1>中輸出中加入'sos''eos',並且去掉最后的全連接層就好了。

3. 特殊情況,seq_len的長度特別大

這類問題通常出現在文本翻譯或者文本處理,以及音頻、視頻處理中。我們需要把seq_len設置為一個適當的值,並且通過迭代,傳遞lstm的hidden_state的方式進行訓練。這對模型的設計,網絡的深度都有一定的要求,博客中就不在展示。

在相關領域已經有很多優秀的論文發表。

author:danielKKK


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM