一點(diǎn)點(diǎn)總結(jié)
回過頭看看這三天的模型谚鄙,從一般LSTM Seq2Seq -> GRU Seq2Seq -> 基于注意力機(jī)制的 Seq2Seq
在構(gòu)建模型的時(shí)候帆调,對(duì)Encoder和Decoder進(jìn)行拆分,最后通過Seq2Seq整合恨闪,如果含有Attention機(jī)制优质,還需要增加attention模塊。
1. 先看三個(gè)模型的Encoder部分
Encoder就是處理輸入Seq的模塊研叫,LSTM 和 GRU Seq2Seq比較類似,區(qū)別在于使用的cell類型(LSTM還是GRU)和輸出結(jié)果(hidden璧针,cell還是只有hidden)嚷炉,attention機(jī)制Seq2Seq復(fù)雜一些,因?yàn)槭请p向的探橱。
1.1 LSTM Seq2Seq Encoder
2層LSTM申屹,數(shù)據(jù)順序從下往上。
Encoder輸入?yún)?shù):
- input_dim輸入encoder的one-hot向量維度隧膏,這個(gè)和輸入詞匯大小一致哗讥,就是輸入字典長度
- emb_dim嵌入層的維度,這一層將one-hot向量轉(zhuǎn)為密度向量,256
詞嵌入在 pytorch 中只需要調(diào)用 torch.nn.Embedding(m, n) 就可以了私植,m 表示單詞的總數(shù)目忌栅,n 表示詞嵌入的維度,是一種降維曲稼,相當(dāng)于是一個(gè)大矩陣索绪,矩陣的每一行表示一個(gè)單詞。 - hid_dim隱藏和cell的狀態(tài)維度,512
- n_layers RNN層數(shù)贫悄,這里就是2
- dropout是要使用的丟失量瑞驱。這是一個(gè)防止過度擬合的正則化參數(shù),0.5
Encoder返回參數(shù):
- hidden窄坦,隱藏狀態(tài)
- cell唤反,單元狀態(tài)
看一下實(shí)現(xiàn)
class Encoder(nn.Module):
def __init__(self, input_dim, emb_dim, hid_dim, n_layers, dropout):
super(Encoder,self).__init__()
self.input_dim=input_dim
self.emb_dim=emb_dim
self.hid_dim=hid_dim
self.n_layers=n_layers
self.dropout=dropout
self.embedding=nn.Embedding(input_dim,emb_dim)
self.rnn=nn.LSTM(emb_dim,hid_dim,n_layers,dropout=dropout)
self.dropout=nn.Dropout(dropout)
def forward(self, src):
embedded=self.dropout(self.embedding(src))
outputs, (hidden,cell)=self.rnn(embedded)
return hidden ,cell
1.2 GRU Seq2Seq Encoder
和LSTM比較類似,做了單層GRU鸭津,dropout不再作為參數(shù)傳入GRU彤侍,返回結(jié)果只有hidden狀態(tài)
Encoder輸入?yún)?shù):
- input_dim輸入encoder的one-hot向量維度,這個(gè)和輸入詞匯大小一致逆趋,就是輸入字典長度
- emb_dim嵌入層的維度盏阶,這一層將one-hot向量轉(zhuǎn)為密度向量,256
詞嵌入在 pytorch 中只需要調(diào)用 torch.nn.Embedding(m, n) 就可以了,m 表示單詞的總數(shù)目闻书,n 表示詞嵌入的維度名斟,是一種降維,相當(dāng)于是一個(gè)大矩陣魄眉,矩陣的每一行表示一個(gè)單詞砰盐。 - hid_dim隱藏和cell的狀態(tài)維度,512
- dropout是要使用的丟失量。這是一個(gè)防止過度擬合的正則化參數(shù)坑律,0.5
Encoder返回參數(shù):
- hidden岩梳,隱藏狀態(tài)
看一下實(shí)現(xiàn)
class Encoder(nn.Module):
def __init__(self, input_dim, emb_dim, hid_dim, dropout):
super(Encoder,self).__init__()
self.input_dim=input_dim
self.emb_dim=emb_dim
self.hid_dim=hid_dim
self.dropout=dropout
self.embedding=nn.Embedding(input_dim,emb_dim)
self.rnn=nn.GRU(emb_dim,hid_dim)
self.dropout=nn.Dropout(dropout)
def forward(self, src):
embedded=self.dropout(self.embedding(src))
outputs, hidden=self.rnn(embedded)
return hidden
1.3 attention Seq2Seq Encoder
因?yàn)閍ttention機(jī)制這個(gè)差別就比較大,使用單層GRU,通過bidirectional RNN蒋腮,每層可以有兩個(gè)RNN網(wǎng)絡(luò)淘捡,這樣就可以從左到右,從右到左對(duì)輸入seq進(jìn)行觀察池摧,得到上下文向量焦除,從某種意義上說,是一種對(duì)文本的理解作彤。
Encoder輸入?yún)?shù):
- input_dim輸入encoder的one-hot向量維度膘魄,這個(gè)和輸入詞匯大小一致,就是輸入字典長度
- emb_dim嵌入層的維度竭讳,這一層將one-hot向量轉(zhuǎn)為密度向量,256
詞嵌入在 pytorch 中只需要調(diào)用 torch.nn.Embedding(m, n) 就可以了创葡,m 表示單詞的總數(shù)目,n 表示詞嵌入的維度绢慢,是一種降維灿渴,相當(dāng)于是一個(gè)大矩陣,矩陣的每一行表示一個(gè)單詞胰舆。 - enc_hid_dim encoder隱藏和cell的狀態(tài)維度,512
- dec_hid_dim decoder隱藏和cell的狀態(tài)維度,512
- dropout是要使用的丟失量骚露。這是一個(gè)防止過度擬合的正則化參數(shù),0.5
Encoder返回參數(shù):
- outputs的大小為[src長度, batch_size, hid_dim num_directions]缚窿,其中hid_dim是來自前向RNN的隱藏狀態(tài)棘幸。這里可以將(hid_dim num_directions)看成是前向、后向隱藏狀態(tài)的堆疊倦零。
,
误续,我們也可以將所有堆疊的編碼器隱藏狀態(tài)表示為
。
- hidden的大小為[n_layers num_directions, batch_size, hid_dim]葫隙,其中[-2,:,:]是在結(jié)束最后時(shí)間步(即在看到最后一個(gè)單詞之后)給出頂層前向RNN隱藏狀態(tài)栽烂。[-1,:停蕉,:]是在結(jié)束最后時(shí)間步之后(即在看到句子中的第一個(gè)單詞之后)給出頂層后向RNN隱藏狀態(tài)。
看一下實(shí)現(xiàn)
class Encoder(nn.Module):
def __init__(self, input_dim, emb_dim, enc_hid_dim, dec_hid_dim, dropout):
super(Encoder,self).__init__()
self.input_dim=input_dim
self.emb_dim=emb_dim
self.enc_hid_dim=enc_hid_dim
self.dec_hid_dim=dec_hid_dim
self.dropout=dropout
self.embedding=nn.Embedding(input_dim,emb_dim)
self.rnn=nn.GRU(emb_dim,enc_hid_dim,bidirectional=True)
self.fc=nn.Linear(enc_hid_dim*2,dec_hid_dim)
self.dropout=nn.Dropout(dropout)
def forward(self, src):
embedded=self.dropout(self.embedding(src))
outputs, hidden=self.rnn(embedded)
hidden = torch.tanh(self.fc(torch.cat((hidden[-2,:,:], hidden[-1,:,:]), dim = 1)))
return outputs, hidden