之前在學習RNN的時候,總是零零散散的搜一些東西。這次想要將關於RNN的知識總結起來,包括各種RNN網絡的結構、輸入輸出以及pytorch代碼實現。
單向RNN網絡簡介
我們首先介紹單向RNN網絡的結構,如下圖所示。時間步 的輸入爲:和,輸出是和。這裏我們統一使用 代表隱藏層狀態表示, 則表示模型輸出值。那麼,單個神經元的運算爲:。其中, 表示的該層的第 個神經元中的運算。
在上面介紹的基礎上,接下來,會介紹三種RNN網絡,分別是Vanilla RNN(即簡單RNN),GRU,LSTM。對於這三種網絡,我會從單個神經元、單層以及多層的方面展開介紹。因爲Vanilla RNN和GRU的結構上是一樣的,只是內部計算不同,所以這裏將這兩個放在一起介紹
Vanilla RNN / GRU 的結構
首先給出簡單RNN/ GRU的單層和多層的網絡結構,這裏從單個神經元進行分析。網絡結構圖如下:
簡介中我們用表示隱層狀態,表示 時刻輸出。那麼,單層Vanilla RNN / GRU的隱層狀態和輸出就是:,。可以看出,Vanilla RNN / GRU的隱層狀態和該時刻的輸出是一樣的。
對於多層Vanilla RNN / GRU來說,隱層狀態和輸出分別爲:,。中間層的輸出直接用於下一層的輸入,不會被直接輸出出來。
LSTM 的結構
首先給出單層和多層LSTM的結構圖,可以看出,相比Vanilla RNN和GRU,LSTM多了一個的輸入,這個表示cell的狀態。
在單層LSTM中,隱層狀態和輸出分別對應於:,。
在多層LSTM中,隱層狀態和輸出分別對應於:,。
雙向RNN網絡簡介
雙向RNN就相當於在上面所講單向RNN基礎之上,再增加一層方向的相同結構網絡。圖示如下:
雙向RNN就會出現兩個輸出,分別爲和,通常這兩個輸出會concat在一起,作爲整體輸出。
知道了單向和雙向RNN的結構之後,我們就來看看pytorch裏怎樣實現這樣的網絡,這裏以LSTM爲例,GRU類似,只是輸入和輸出的不同。
單向和雙向LSTM的pytorch代碼實現
單向LSTM
rnn = nn.LSTM(input_size=10, hidden_size=20, num_layers=2)#(input_size,hidden_size,num_layers)
input = torch.randn(5, 3, 10)#(seq_len, batch, input_size)
h0 = torch.randn(2, 3, 20) #(num_layers,batch,output_size)
c0 = torch.randn(2, 3, 20) #(num_layers,batch,output_size)
output, (hn, cn) = rnn(input, (h0, c0))
那麼,output和hn,cn的維度是多少呢?
output.shape #(seq_len, batch, output_size)
torch.Size([5, 3, 20])
hn.shape #(num_layers, batch, output_size)
torch.Size([2, 3, 20])
cn.shape #(num_layers, batch, output_size)
torch.Size([2, 3, 20])
雙向LSTM
rnn = nn.LSTM(input_size=10, hidden_size=20, num_layers=2,bidirectional=True)#(input_size,hidden_size,num_layers)
input = torch.randn(5, 3, 10)#(seq_len, batch, input_size)
h0 = torch.randn(4, 3, 20) #(num_layers,batch,output_size)
c0 = torch.randn(4, 3, 20) #(num_layers,batch,output_size)
output, (hn, cn) = rnn(input, (h0, c0))
output和hn,cn的維度是多少呢?
output.shape #(seq_len, batch, output_size*2)
torch.Size([5, 3, 40])
hn.shape #(num_layers*2, batch, output_size)
torch.Size([4, 3, 20])
cn.shape #(num_layers*2, batch, output_size)
torch.Size([4, 3, 20])