transformer中解码器中的masked multi-head attention不加会怎样
时间: 2023-09-18 14:09:12 浏览: 162
如果在解码器中的masked multi-head attention中不进行mask操作,那么在当前时间步之前的所有位置都可以被当前时间步的注意力所获取,这就意味着当前时间步可以看到所有之前的信息,包括后续的信息。这会导致模型泄露未来信息,从而使模型在实际应用中表现不佳。
因此,在解码器中的masked multi-head attention中进行mask操作是必要的,它可以确保模型只能在当前时间步之前的位置进行注意力计算,避免了模型泄露未来信息的问题。
相关问题
transformer 解码器
### Transformer 解码器的工作原理
在Transformer模型中,解码器由多个相同的层堆叠而成。每一层主要包含两个子层:多头自注意力机制(Multi-head Self-Attention)和前馈神经网络(Feed Forward Neural Network)。此外,在这两个子层之间还存在一个编码器-解码器注意力机制(Encoder-Decoder Attention),用于捕捉输入序列与目标序列之间的依赖关系[^1]。
#### 多头自注意力机制
该部分允许解码器关注到目前为止已生成的目标序列中的不同位置,从而预测下一个词。为了防止解码器看到未来的信息,在计算自注意力时会应用掩码操作,即Masked Multi-head Self-Attention。通过这种方式,可以确保当前时刻只能够访问之前的位置信息[^2]。
```python
import torch.nn as nn
class MaskedSelfAttention(nn.Module):
def __init__(self, d_model, num_heads):
super().__init__()
self.multihead_attn = nn.MultiheadAttention(d_model, num_heads)
def forward(self, query, key, value, mask=None):
attn_output, _ = self.multihead_attn(query, key, value, attn_mask=mask)
return attn_output
```
#### 编码器-解码器注意力机制
此模块接收来自最后一个编码器层的输出作为键(key)和值(value),并将解码器自身的隐藏状态作为查询(query)来获取上下文向量。这有助于解码器理解源语言句子的内容并据此生成翻译后的单词[^3]。
```python
class EncoderDecoderAttention(nn.Module):
def __init__(self, d_model, num_heads):
super().__init__()
self.multihead_attn = nn.MultiheadAttention(d_model, num_heads)
def forward(self, query, encoder_outputs, src_mask=None):
context_vector, _ = self.multihead_attn(query=query,
key=encoder_outputs,
value=encoder_outputs,
key_padding_mask=src_mask)
return context_vector
```
#### 前馈神经网络
最后是一个简单的线性变换加上ReLU激活函数组成的两层全连接网络。这个结构在整个解码过程中保持不变,并应用于每一个时间步上产生的特征表示之上[^4]。
```python
class PositionwiseFeedForward(nn.Module):
def __init__(self, d_model, d_ff):
super().__init__()
self.fc1 = nn.Linear(d_model, d_ff)
self.relu = nn.ReLU()
self.fc2 = nn.Linear(d_ff, d_model)
def forward(self, x):
return self.fc2(self.relu(self.fc1(x)))
```
transformer解码器输入
### Transformer 解码器输入格式与要求
Transformer架构中的解码器接收特定格式的数据作为输入,这些数据对于实现有效的序列到序列学习至关重要[^1]。
#### 输入嵌入(Input Embeddings)
解码器的第一个输入是目标序列的词嵌入。每个时间步的目标单词被映射成固定维度的向量表示。这种转换通常由预训练好的词表完成,其中包含了词汇表中所有可能单词对应的密集向量。
```python
import torch.nn as nn
embedding_layer = nn.Embedding(vocab_size, d_model)
target_sequence_ids = ... # 目标语言句子token ID列表
embedded_inputs = embedding_layer(target_sequence_ids)
```
#### 位置编码(Positional Encoding)
为了引入顺序信息,解码器还需要添加位置编码至上述得到的词嵌入上。这允许模型区分相同词语的不同排列组合所带来的语义差异。
```python
def get_positional_encoding(max_len, embed_dim):
pe = torch.zeros(max_len, embed_dim)
position = torch.arange(0., max_len).unsqueeze(1)
div_term = torch.exp(torch.arange(0., embed_dim, 2) * -(math.log(10000.0) / embed_dim))
pe[:, 0::2] = torch.sin(position * div_term)
pe[:, 1::2] = torch.cos(position * div_term)
return pe.unsqueeze(0)
positional_encodings = get_positional_encoding(seq_length, d_model)
decoder_input_with_pos = embedded_inputs + positional_encodings[:,:seq_length,:]
```
#### 自注意力掩蔽(Masked Self-Attention)
由于解码过程中不允许当前时刻看到未来的信息,在计算自注意分数时会对未来的 token 施加掩膜处理。这意味着当预测第 t 步的结果时,只考虑前 t−1 步的内容;而对于后续部分,则设置为无穷小值使得softmax后的概率接近于零。
```python
def create_look_ahead_mask(size):
mask = (torch.triu(torch.ones((size, size))) == 0).transpose(0, 1)
return mask.float().masked_fill(mask == 0, float('-inf')).masked_fill(mask == 1, float(0.0))
lookahead_mask = create_look_ahead_mask(decoder_seq_len)
attention_output = multi_head_attention(query=decoder_input_with_pos,
key=encoder_outputs,
value=encoder_outputs,
attention_mask=lookahead_mask)
```
#### 编码器-解码器注意力机制(Encoder-Decoder Attention)
除了自身的自注意力层外,解码器还会利用来自编码器的最后一层输出来构建跨模态连接。此过程涉及查询(encoder outputs)-键(key)/值(value)匹配操作,从而让解码侧能够聚焦源端的关键特征并据此生成更合理的翻译或合成图像等下游任务所需的输出。
```python
cross_attn_output = cross_multi_head_attention(query=attention_output,
key=encoder_final_state,
value=encoder_final_state)
```
阅读全文