我正在尝试在我的网络中实现 nn.MultiheadAttention。根据docs ,
embed_dim – total dimension of the model.
但是,根据 source file ,
embed_dim must be divisible by num_heads
和
self.q_proj_weight = Parameter(torch.Tensor(embed_dim, embed_dim))
如果我理解正确,这意味着每个头仅采用每个查询的一部分特征,因为矩阵是二次的。是实现的bug还是我的理解有误?
最佳答案
每个头使用投影查询向量的不同部分。您可以将其想象为查询被拆分为 num_heads
向量,这些向量独立用于计算缩放后的点积注意力。因此,每个头对查询中的特征(以及键和值)的不同线性组合进行操作。此线性投影是使用 self.q_proj_weight 矩阵完成的,并将投影的查询传递给 F.multi_head_attention_forward 函数。
在 F.multi_head_attention_forward
,它是通过 reshape 和转置查询向量来实现的,以便可以计算各个头的独立注意力 efficiently by matrix multiplication .
注意力头的大小是 PyTorch 的设计决定。理论上,您可以有不同的头部尺寸,因此投影矩阵的形状为 embedding_dim
× num_heads * head_dims
。转换器的某些实现(例如用于机器翻译的基于 C++ 的 Marian 或 Huggingface's Transformers )允许这样做。
关于deep-learning - 为什么 torch.nn.MultiheadAttention 中的 W_q 矩阵是二次的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63657679/