微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 Pytorch 实现 BiLSTM-Attention-CRF 模型

如何解决使用 Pytorch 实现 BiLSTM-Attention-CRF 模型

我正在尝试为 NER 任务实现 BiLSTM-Attention-CRF 模型。我能够基于 BILSTM-CRF 模型(来自 here代码)执行 NER 任务,但我需要注意提高模型的性能

现在我的模型是:

BiLSTM -> 线性层(隐藏到标签)-> CRf 层

线性层的输出是(seq.length x tagset size),然后它被输入到 CRF 层。

我正在尝试使用以下代码将线性层替换为注意层:

class SelfAttention(nn.Module):
    def __init__(self,hidden_dim):
            super().__init__()
            self.hidden_dim = hidden_dim
            self.projection = nn.Sequential(
                    nn.Linear(hidden_dim,64),nn.ReLU(True),nn.Linear(64,1)
            )

    def forward(self,encoder_outputs):
            batch_size = encoder_outputs.size(0)
            # (B,L,H) -> (B,1)
            energy = self.projection(encoder_outputs)
            weights = F.softmax(energy.squeeze(-1),dim=1)
            # (B,H) * (B,1) -> (B,H)
            outputs = (encoder_outputs * weights.unsqueeze(-1)).sum(dim=1)
            return outputs,weights

这样做时我有两个问题:

  • 我不能让它工作,所以输出应该是(seq.length x tagset size)的形状,这样它就可以被输入到 CRF 层中。
  • 根据这个paper,我们需要初始化和学习词级上下文向量,这在注意力模型的这个实现中是看不到的。

请帮助我。

TIA

解决方法

你实现的是一种非常不寻常的自我注意类型。它类似于 the original self-attention for sequence classification,这可能是 Attention is all you need 论文的部分灵感来源。

一般来说,注意力可以理解为一种概率隐藏状态检索。给定一些键,您可以检索一些值。在标准 Bahdanau's attention 中,键是解码器状态,值是编码器状态。在 Transformer self-attention 中,用作从其他状态检索某些信息的键,即每个状态同时是一个键和一个值。在特殊情况下,您已经实现了,您只有一个在 projection 中加密的密钥。您使用这个单一的常量键从隐藏状态中检索一个向量,结果,每个序列只能获得一个向量。

您可能想要的是使用 Transformer 风格的自注意力机制,其中每个状态都被用作一个键来获取值的摘要。为此,您可以使用 PyTorch 中的 nn.MultiheadAttention class。除了我所描述的,它还在多个头中进行注意力,因此它可以进行更细粒度的检索。请注意,在您的情况下,查询、键和值是相同的张量,即 Bi-LSTM 的输出。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。