僅僅使用pytorch來手撕transformer架構(2):編碼器模塊和編碼器類的實現和向前傳播
往期文章:
僅僅使用pytorch來手撕transformer架構(1):位置編碼的類的實現和向前傳播
最適合小白入門的Transformer介紹
僅僅使用pytorch來手撕transformer架構(2):多頭注意力MultiHeadAttention類的實現和向前傳播
# Transformer 編碼器模塊
class TransformerBlock(nn.Module):def __init__(self, embed_size, heads, dropout, forward_expansion):super(TransformerBlock, self).__init__()self.attention = MultiHeadAttention(embed_size, heads)self.norm1 = nn.LayerNorm(embed_size)self.norm2 = nn.LayerNorm(embed_size)self.feed_forward = nn.Sequential(nn.Linear(embed_size, forward_expansion * embed_size),nn.ReLU(),nn.Linear(forward_expansion * embed_size, embed_size),)self.dropout = nn.Dropout(dropout)def forward(self, value, key, query, mask):attention = self.attention(value, key, query, mask)x = self.dropout(self.norm1(attention + query))forward = self.feed_forward(x)out = self.dropout(self.norm2(forward + x))return out# 編碼器
class Encoder(nn.Module):def __init__(self, src_vocab_size, embed_size, num_layers, heads, device, forward_expansion, dropout, max_length):super(Encoder, self).__init__()self.embed_size = embed_sizeself.device = deviceself.word_embedding = nn.Embedding(src_vocab_size, embed_size)self.position_embedding = PositionalEncoding(embed_size, dropout, max_length)self.layers = nn.ModuleList([TransformerBlock(embed_size,heads,dropout=dropout,forward_expansion=forward_expansion,)for _ in range(num_layers)])self.dropout = nn.Dropout(dropout)def forward(self, x, mask):N, seq_length = x.shapex = self.dropout(self.position_embedding(self.word_embedding(x)))for layer in self.layers:x = layer(x, x, x, mask)return x
1.編碼器模塊的實現
這段代碼實現了一個Transformer編碼器模塊(Transformer Block),它是Transformer架構的核心組件之一。Transformer架構是一種基于自注意力機制(Self-Attention)的深度學習模型,廣泛應用于自然語言處理(NLP)任務,如機器翻譯、文本生成等。以下是對代碼的詳細解釋:
1.1 類定義
class TransformerBlock(nn.Module):
TransformerBlock
是一個繼承自 PyTorch 的 nn.Module
的類,表示一個Transformer編碼器模塊。nn.Module
是 PyTorch 中所有神經網絡模塊的基類,用于定義和管理神經網絡的結構。
2.2 初始化方法
def __init__(self, embed_size, heads, dropout, forward_expansion):super(TransformerBlock, self).__init__()self.attention = MultiHeadAttention(embed_size, heads)self.norm1 = nn.LayerNorm(embed_size)self.norm2 = nn.LayerNorm(embed_size)self.feed_forward = nn.Sequential(nn.Linear(embed_size, forward_expansion * embed_size),nn.ReLU(),nn.Linear(forward_expansion * embed_size, embed_size),)self.dropout = nn.Dropout(dropout)
參數解釋
embed_size
: 嵌入向量的維度,表示每個詞或標記(token)的特征維度。heads
: 多頭注意力機制中的頭數(Multi-Head Attention
)。dropout
: Dropout比率,用于防止過擬合。forward_expansion
: 前饋網絡(Feed-Forward Network, FFN)中隱藏層的擴展因子。
組件解釋
-
多頭注意力機制(
MultiHeadAttention
)self.attention = MultiHeadAttention(embed_size, heads)
這是Transformer的核心部分,實現了多頭注意力機制。它允許模型在不同的表示子空間中學習信息。
MultiHeadAttention
的具體實現沒有在這段代碼中給出,但通常它會將輸入分為多個“頭”,分別計算注意力權重,然后將結果拼接起來。 -
層歸一化(
LayerNorm
)self.norm1 = nn.LayerNorm(embed_size) self.norm2 = nn.LayerNorm(embed_size)
層歸一化(Layer Normalization)是一種歸一化方法,用于穩定訓練過程并加速收斂。它對每個樣本的特征進行歸一化,而不是像批量歸一化(Batch Normalization)那樣對整個批次進行歸一化。
-
前饋網絡(
Feed-Forward Network
)self.feed_forward = nn.Sequential(nn.Linear(embed_size, forward_expansion * embed_size),nn.ReLU(),nn.Linear(forward_expansion * embed_size, embed_size), )
前饋網絡是一個簡單的兩層全連接網絡。它的作用是進一步處理多頭注意力機制的輸出。
forward_expansion
參數控制隱藏層的大小,通常設置為一個較大的值(如4),表示隱藏層的維度是輸入維度的4倍。 -
Dropout
self.dropout = nn.Dropout(dropout)
Dropout 是一種正則化技術,通過隨機丟棄一部分神經元的輸出來防止過擬合。
dropout
參數表示丟棄的概率。
3. 前向傳播方法
def forward(self, value, key, query, mask):attention = self.attention(value, key, query, mask)x = self.dropout(self.norm1(attention + query))forward = self.feed_forward(x)out = self.dropout(self.norm2(forward + x))return out
參數解釋
value
: 值向量,用于計算注意力權重后的加權求和。key
: 鍵向量,用于計算注意力權重。query
: 查詢向量,用于計算注意力權重。mask
: 掩碼,用于防止某些位置的信息泄露(如在自注意力中屏蔽未來信息)。
流程解釋
-
多頭注意力
attention = self.attention(value, key, query, mask)
首先,使用多頭注意力機制計算注意力輸出。
value
、key
和query
是輸入的三個部分,mask
用于控制哪些位置的信息可以被關注。 -
殘差連接與層歸一化
x = self.dropout(self.norm1(attention + query))
將注意力輸出與輸入的
query
進行殘差連接(attention + query
),然后通過層歸一化(LayerNorm
)。最后,應用 Dropout 防止過擬合。 -
前饋網絡
forward = self.feed_forward(x)
將經過歸一化的輸出傳遞到前饋網絡中進行進一步處理。
-
第二次殘差連接與層歸一化
out = self.dropout(self.norm2(forward + x))
將前饋網絡的輸出與之前的輸出
x
進行殘差連接,再次通過層歸一化和 Dropout。 -
返回結果
return out
最終返回處理后的輸出。
4. 總結
Transformer編碼器模塊,其核心包括:
- 多頭注意力機制(
MultiHeadAttention
)。 - 殘差連接(Residual Connection)。
- 層歸一化(
LayerNorm
)。 - 前饋網絡(
Feed-Forward Network
)。 - Dropout 正則化。
這些組件共同作用,使得Transformer能夠高效地處理序列數據,并在許多NLP任務中取得了優異的性能。
2.編碼器的實現
這段代碼定義了一個完整的 Transformer 編碼器(Encoder),它是 Transformer 架構中的一個重要組成部分。編碼器的作用是將輸入序列(如源語言文本)轉換為上下文表示,這些表示可以被解碼器(Decoder)用于生成目標序列(如目標語言文本)。以下是對代碼的詳細解釋:
1. 類定義
class Encoder(nn.Module):
Encoder
是一個繼承自 PyTorch 的 nn.Module
的類,用于定義 Transformer 編碼器的結構。nn.Module
是 PyTorch 中所有神經網絡模塊的基類,用于定義和管理神經網絡的結構。
2. 初始化方法
def __init__(self, src_vocab_size, embed_size, num_layers, heads, device, forward_expansion, dropout, max_length):super(Encoder, self).__init__()self.embed_size = embed_sizeself.device = deviceself.word_embedding = nn.Embedding(src_vocab_size, embed_size)self.position_embedding = PositionalEncoding(embed_size, dropout, max_length)self.layers = nn.ModuleList([TransformerBlock(embed_size,heads,dropout=dropout,forward_expansion=forward_expansion,)for _ in range(num_layers)])self.dropout = nn.Dropout(dropout)
參數解釋
src_vocab_size
: 源語言詞匯表的大小,即輸入序列中可能的標記(token)數量。embed_size
: 嵌入向量的維度,表示每個詞或標記的特征維度。num_layers
: 編碼器中 Transformer 塊(TransformerBlock
)的數量。heads
: 多頭注意力機制中的頭數。device
: 運行設備(如 CPU 或 GPU)。forward_expansion
: 前饋網絡(FFN)中隱藏層的擴展因子。dropout
: Dropout 比率,用于防止過擬合。max_length
: 輸入序列的最大長度,用于位置編碼。
組件解釋
-
詞嵌入(
word_embedding
)self.word_embedding = nn.Embedding(src_vocab_size, embed_size)
詞嵌入層將輸入的標記(token)索引映射為固定維度的嵌入向量。
src_vocab_size
是詞匯表的大小,embed_size
是嵌入向量的維度。 -
位置編碼(
position_embedding
)self.position_embedding = PositionalEncoding(embed_size, dropout, max_length)
位置編碼層用于為每個標記添加位置信息,使得模型能夠捕捉序列中的順序關系。
PositionalEncoding
的具體實現沒有在這段代碼中給出,但通常它會根據標記的位置生成一個固定維度的向量,并將其與詞嵌入相加。 -
Transformer 塊(
TransformerBlock
)self.layers = nn.ModuleList([TransformerBlock(embed_size,heads,dropout=dropout,forward_expansion=forward_expansion,)for _ in range(num_layers)] )
編碼器由多個 Transformer 塊組成。每個 Transformer 塊包含多頭注意力機制和前饋網絡。
num_layers
表示 Transformer 塊的數量。 -
Dropout
self.dropout = nn.Dropout(dropout)
Dropout 是一種正則化技術,通過隨機丟棄一部分神經元的輸出來防止過擬合。
dropout
參數表示丟棄的概率。
3. 前向傳播方法
def forward(self, x, mask):N, seq_length = x.shapex = self.dropout(self.position_embedding(self.word_embedding(x)))for layer in self.layers:x = layer(x, x, x, mask)return x
參數解釋
x
: 輸入序列,形狀為(N, seq_length)
,其中N
是批次大小,seq_length
是序列長度。mask
: 掩碼,用于防止某些位置的信息泄露(如在自注意力中屏蔽未來信息)。
流程解釋
-
詞嵌入與位置編碼
x = self.dropout(self.position_embedding(self.word_embedding(x)))
- 首先,將輸入序列
x
通過詞嵌入層(word_embedding
)得到嵌入向量。 - 然后,將嵌入向量與位置編碼(
position_embedding
)相加,為每個標記添加位置信息。 - 最后,應用 Dropout 防止過擬合。
- 首先,將輸入序列
-
逐層傳遞
for layer in self.layers:x = layer(x, x, x, mask)
- 輸入序列
x
逐層傳遞到每個 Transformer 塊中。在每個塊中:value
、key
和query
都是x
,因為這是自注意力機制(Self-Attention)。mask
用于控制哪些位置的信息可以被關注。
- 每個 Transformer 塊的輸出會作為下一層的輸入。
- 輸入序列
-
返回結果
return x
- 最終返回編碼器的輸出,形狀為
(N, seq_length, embed_size)
,表示每個位置的上下文表示。
- 最終返回編碼器的輸出,形狀為
4. 總結
Transformer 編碼器,其主要功能包括:
- 詞嵌入與位置編碼:將輸入標記轉換為嵌入向量,并添加位置信息。
- 多層 Transformer 塊:通過多頭注意力機制和前饋網絡逐層處理輸入序列。
- 掩碼機制:通過掩碼控制注意力的范圍,避免信息泄露。
- Dropout 正則化:防止過擬合。
編碼器的輸出是一個上下文表示,可以被解碼器用于生成目標序列。這種架構在機器翻譯、文本生成等任務中表現出色。
作者碼字不易,覺得有用的話不妨點個贊吧,關注我,持續為您更新AI的優質內容。