
中文命名實體識別(Named Entity Recognition, NER)初探
自注意力機制(Self-attention),有時被稱為內部注意力,是一種關聯(lián)單個序列不同位置以計算該序列表示的注意力機制。它已被成功應用于多種任務,如閱讀理解、抽象總結、文本蘊涵和學習任務無關的句子表示。Transformer 是第一個完全依賴自注意力來計算輸入和輸出表示的轉導模型,而不使用序列對齊的 RNN 或卷積。
大多數(shù)競爭激烈的神經序列轉導模型都具有編碼器-解碼器結構。這里的編碼器將符號表示的輸入序列映射到一系列連續(xù)表示。給定這些表示,解碼器逐個生成輸出序列的符號元素。
class EncoderDecoder(nn.Module):
"""
標準的編碼器-解碼器架構。這也是許多其他模型的基礎。
"""
def __init__(self, encoder, decoder, src_embed, tgt_embed, generator):
super(EncoderDecoder, self).__init__()
self.encoder = encoder
self.decoder = decoder
self.src_embed = src_embed
self.tgt_embed = tgt_embed
self.generator = generator
def forward(self, src, tgt, src_mask, tgt_mask):
"處理源和目標序列的掩碼。"
return self.decode(self.encode(src, src_mask), src_mask,
tgt, tgt_mask)
def encode(self, src, src_mask):
return self.encoder(self.src_embed(src), src_mask)
def decode(self, memory, src_mask, tgt, tgt_mask):
return self.decoder(self.tgt_embed(tgt), memory, src_mask, tgt_mask)
該模型在編碼器和解碼器中使用堆疊的自注意力和逐點的全連接層。
編碼器由 N=6 個相同的層組成。
def clones(module, N):
"生產 N 個相同的層。"
return nn.ModuleList([copy.deepcopy(module) for _ in range(N)])
class Encoder(nn.Module):
"核心編碼器是一個 N 層的堆棧。"
def __init__(self, layer, N):
super(Encoder, self).__init__()
self.layers = clones(layer, N)
self.norm = LayerNorm(layer.size)
def forward(self, x, mask):
"依次通過每層處理輸入(和掩碼)。"
for layer in self.layers:
x = layer(x, mask)
return self.norm(x)
每個子層的輸出是 LayerNorm(x + Sublayer(x))
,其中 Sublayer(x)
是子層本身實現(xiàn)的函數(shù)。
解碼器也由 N=6 個相同的層組成。
class Decoder(nn.Module):
"具有掩碼的通用 N 層解碼器。"
def __init__(self, layer, N):
super(Decoder, self).__init__()
self.layers = clones(layer, N)
self.norm = LayerNorm(layer.size)
def forward(self, x, memory, src_mask, tgt_mask):
for layer in self.layers:
x = layer(x, memory, src_mask, tgt_mask)
return self.norm(x)
解碼器在每個編碼器層的兩個子層之外插入第三個子層,該子層對編碼器堆棧的輸出執(zhí)行多頭注意力。
注意力函數(shù)可以描述為將查詢和一組鍵-值對映射到輸出,查詢、鍵、值和輸出都是向量。輸出是值的加權和,其中每個值的權重由查詢與相應鍵的兼容性函數(shù)計算。
我們稱之為“縮放點積注意力”。
def attention(query, key, value, mask=None, dropout=None):
"計算縮放點積注意力"
d_k = query.size(-1)
scores = torch.matmul(query, key.transpose(-2, -1))
/ math.sqrt(d_k)
if mask is not None:
scores = scores.masked_fill(mask == 0, -1e9)
p_attn = F.softmax(scores, dim = -1)
if dropout is not None:
p_attn = dropout(p_attn)
return torch.matmul(p_attn, value), p_attn
通過以上詳細的解析和示例,您應該對 Transformer 模型及其實現(xiàn)有更深入的了解。如果有進一步的問題,歡迎在評論區(qū)討論。