【发布时间】:2018-08-11 16:15:35
【问题描述】:
我正在尝试将注意力机制添加到堆叠 LSTM 实现 https://github.com/salesforce/awd-lstm-lm
所有在线示例都使用编码器-解码器架构,我不想使用(注意力机制是否必须使用?)。
def __init__(self, rnn_type, ntoken, ninp, nhid, nlayers, dropout=0.5, dropouth=0.5, dropouti=0.5, dropoute=0.1, wdrop=0, tie_weights=False):
super(RNNModel, self).__init__()
self.encoder = nn.Embedding(ntoken, ninp)
self.rnns = [torch.nn.LSTM(ninp if l == 0 else nhid, nhid if l != nlayers - 1 else (ninp if tie_weights else nhid), 1, dropout=0) for l in range(nlayers)]
for rnn in self.rnns:
rnn.linear = WeightDrop(rnn.linear, ['weight'], dropout=wdrop)
self.rnns = torch.nn.ModuleList(self.rnns)
self.attn_fc = torch.nn.Linear(ninp, 1)
self.decoder = nn.Linear(nhid, ntoken)
self.init_weights()
def attention(self, rnn_out, state):
state = torch.transpose(state, 1,2)
weights = torch.bmm(rnn_out, state)# torch.bmm(rnn_out, state)
weights = torch.nn.functional.softmax(weights)#.squeeze(2)).unsqueeze(2)
rnn_out_t = torch.transpose(rnn_out, 1, 2)
bmmed = torch.bmm(rnn_out_t, weights)
bmmed = bmmed.squeeze(2)
return bmmed
def forward(self, input, hidden, return_h=False, decoder=False, encoder_outputs=None):
emb = embedded_dropout(self.encoder, input, dropout=self.dropoute if self.training else 0)
emb = self.lockdrop(emb, self.dropouti)
new_hidden = []
raw_outputs = []
outputs = []
for l, rnn in enumerate(self.rnns):
temp = []
for item in emb:
item = item.unsqueeze(0)
raw_output, new_h = rnn(item, hidden[l])
raw_output = self.attention(raw_output, new_h[0])
temp.append(raw_output)
raw_output = torch.stack(temp)
raw_output = raw_output.squeeze(1)
new_hidden.append(new_h)
raw_outputs.append(raw_output)
if l != self.nlayers - 1:
raw_output = self.lockdrop(raw_output, self.dropouth)
outputs.append(raw_output)
hidden = new_hidden
output = self.lockdrop(raw_output, self.dropout)
outputs.append(output)
outputs = torch.stack(outputs).squeeze(0)
outputs = torch.transpose(outputs, 2,1)
output = output.transpose(2,1)
output = output.contiguous()
decoded = self.decoder(output.view(output.size(0)*output.size(1), output.size(2)))
result = decoded.view(output.size(0), output.size(1), decoded.size(1))
if return_h:
return result, hidden, raw_outputs, outputs
return result, hidden
这个模型正在训练,但与没有注意力模型的模型相比,我的损失相当高。
【问题讨论】:
-
你能简单解释一下你的需求而不是显示你的代码吗?你的问题有点令人困惑。如果您能说出您在堆叠 RNN 之上添加注意力机制的想法,我将能够为您提供帮助。另外,这种注意力的实现缺少一个维度是什么意思?为什么你需要那个额外的维度?顺便说一句,您不需要使用编码器-解码器架构来使用注意力。如果您了解注意力的含义,您可以在任何地方使用它。
-
@WasiAhmad 我需要修改问题链接中的代码(我将其用于语言建模)以包含注意机制,以便我可以比较训练模型的质量。在原始代码中,forward 返回 5x5x831 张量(batchesXlengthXdictionary)。如果我使用我的问题中的注意力,我会得到 5x831 维度张量,它缺少一维。我想知道是否可以修改注意力函数以恢复第三维,但我认为 patapouf_ai 建议对“emb”张量中的每个单词应用注意力
-
@WasiAhmad 我已经更改了前向函数,将逐字输入注意力,但我的结果比没有注意力的模型差。我已经编辑了我的问题
标签: neural-network deep-learning pytorch tensor attention-model