赞
踩
第四个assignment 搭建了一个NMT,与之前在课程中学到的是一样的,架构如下
完整代码见我的GitHub
环境搭建:
e_t.data.masked_fill_(enc_masks.bool(), -float('inf'))
注:若检验程序未通过,可以看看输入的报错,然后打印计算过程中矩阵的维度,判断是否出错,大部分bug根据维度就能找到
(a) 识别出batch中最长的句子,并将其他句子pad成相同长度。
只需要遍历求出最长句子的长度,然后使用pad_token将其他句子padding成一样长即可
max_len = max(len(sen) for sen in sents)
for sen in sents:
sents_padded.append(sen + [pad_token] * (max_len-len(sen)))
(b) 实现 model embeddings.py 中的 __init__
使用 nn.Embedding(vocab_len, embedding_size, pad_idx) 即可
self.source = nn.Embedding(len(vocab.src), self.embed_size,src_pad_token_idx)
self.target = nn.Embedding(len(vocab.tgt), self.embed_size,src_pad_token_idx)
下面就正式开始搭建NMT神经网络了
(c) 实现 nmt model.py 中的 __init__
self.encoder = nn.LSTM(embed_size, self.hidden_size,dropout = self.dropout_rate,bidirectional=True)
self.decoder = nn.LSTMCell(embed_size + self.hidden_size, self.hidden_size) #每个时间步的输入为上一时间步得到的o_(t-1)和本时间步的词嵌入输入
self.h_projection = nn.Linear(self.hidden_size * 2, self.hidden_size,bias = False) #将encoder两个hidden拼接转化为decoder的初始hidden (2h,1)->(h,1)
self.c_projection = nn.Linear(self.hidden_size*2, self.hidden_size,bias = False) #同h_projection
self.att_projection = nn.Linear(self.hidden_size*2, self.hidden_size,bias = False) #multiplicative attention,将encoder每个时间步的输出(2h,1),转化为(h,1)
self.combined_output_projection = nn.Linear(self.hidden_size*3, self.hidden_size,bias = False) #将u_t (batch_size,3h) 转化为 v_t(batch_size,h)
self.target_vocab_projection = nn.Linear(self.hidden_size,len(vocab.tgt),bias = False)#将hidden(h,1)转化为(vocab,1)
self.dropout = nn.Dropout(self.dropout_rate)
(d) 实现nmt_model.py 中的 encode
X = self.model_embeddings.source(source_padded) #获取源句子词嵌入
X = pack_padded_sequence(X,source_lengths) #相当于压缩
enc_hiddens,(last_hidden,last_cell) = self.encoder(X) #encoder
enc_hiddens = pad_packed_sequence(enc_hiddens,batch_first = True) #(b, src_len, h*2) #相当于解压,注意返回值为一个元组,我们需要第一个元素
init_decoder_hidden = self.h_projection(torch.cat((last_hidden[0],last_hidden[1]),dim = 1)) #拼接后转化
init_decoder_cell = self.c_projection(torch.cat((last_cell[0],last_cell[1]),dim = 1)) #拼接后转化
dec_init_state = (init_decoder_hidden,init_decoder_cell)
### END YOUR CODE
return enc_hiddens[0], dec_init_state
(e) 实现nmt_model.py 的 decode
enc_hiddens_proj = self.att_projection(enc_hiddens) #计算W_att * h_encoder,在step函数中用于计算注意力
Y = self.model_embeddings.target(target_padded) #target sentence
for Y_t in torch.split(Y,1):
Y_t = torch.squeeze(Y_t, 0)
Ybar_t = torch.cat((Y_t,o_prev),dim = 1)
dec_state,o_t,_ = self.step(Ybar_t, dec_state, enc_hiddens, enc_hiddens_proj, enc_masks)# see function step
combined_outputs.append(o_t) #保存每个时间步的最终输出(hidden与encoder每个时间步加权 拼接)用于最后预测单词
o_prev = o_t #
combined_outputs = torch.stack(combined_outputs,dim = 0)
dec_state = self.decoder(Ybar_t,dec_state) #nn.LSTMcell的用法
e_t = torch.bmm(enc_hiddens_proj,torch.unsqueeze(dec_state[0],dim = 2)) #batch矩阵乘法,计算注意力分数
e_t = torch.squeeze(e_t,dim = 2)
alpha_t = F.softmax(e_t,dim =1) #计算注意力权值
alpha_t = torch.unsqueeze(alpha_t,dim=1)
a_t = torch.bmm(alpha_t, enc_hiddens) #encoder hidden的注意力加权
a_t = torch.squeeze(a_t, dim=1)
U_t = torch.cat((a_t,dec_state[0]),dim = 1)
V_t = self.combined_output_projection(U_t)
O_t = self.dropout(torch.tanh(V_t)) #每个时间步最终的输出
(g) step 函数中使用了 generate_sent masks() ,解释其构造的masks对注意力计算有什么影响,解释为什么这是必要的。
if enc_masks is not None:
e_t.data.masked_fill_(enc_masks.bool(), -float('inf'))
(h) 因为笔者使用的是windows,无法直接运行.sh,所以我这里直接查看run.sh文件,运行相关的命令。
python vocab.py --train-src=./en_es_data/train.es --train-tgt=./en_es_data/train.en vocab.json
产生vocab文件python run.py train --train-src=./en_es_data/train.es --train-tgt=./en_es_data/train.en --dev-src=./en_es_data/dev.es --dev-tgt=./en_es_data/dev.en --vocab=vocab.json
进行本地训练(i) 由于笔者无在线的虚拟机来进行训练,因此这部分先放着。
(j) 三种计算注意力方式的优缺点
(a) 确定错误类型,提供理由,如何改进
i
.
\mathrm{i.}
i.specific linguistic construct
i
i
.
\mathrm{ii.}
ii. specific linguistic construct
i
i
i
.
\mathrm{iii.}
iii. specific model limitations(We can’t know the unkonw word)
改进:未知词可能是专有名词,我们可以使用复制机制,直接复制过来
i
v
.
\mathrm{iv.}
iv. specific model limitations
v
.
\mathrm{v.}
v. specific model limitations(the model may pay more attetion to the word ‘she’, so the result is “the women’s”)
v
i
.
\mathrm{vi.}
vi. specific model limitations(the model can’t distinguish the difference between French unit and American unit)
转载自:ZacBi’ github
(b)
(c) BLEU计算
i
.
\mathrm{i.}
i.
i i . \mathrm{ii.} ii.只基于r1计算,
i
i
i
.
\mathrm{iii.}
iii.
我觉得只使用一个参考翻译会有很大的不确定性,就比如上面的例子,去掉r2使得c2的分数变低,如果去掉的是r1,那么c1的分数将会降低。因此较少的参考翻译会增加偶然性,我们知道,虽然一个句子有多种不同的说法,但其中有一些词或短语是相同的,一个好的翻译应该尽可能与这些词或短语overlap,因此较多的参考翻译对评价结果更有利。
i v . \mathrm{iv.} iv.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。