序列到序列模型(Seq2Seq)介紹

序列到序列模型(Seq2Seq)是一種用於處理序列數據的深度學習架構,廣泛應用於自然語言處理(NLP)任務,如機器翻譯、文本摘要、對話生成等。Seq2Seq 模型通常由兩個主要部分組成:編碼器(Encoder)和解碼器(Decoder)。

關鍵特點

  1. 編碼器:編碼器接收輸入序列,將其轉換為一個固定長度的上下文向量(context vector),該向量捕捉了輸入序列的語義信息。
  2. 解碼器:解碼器根據上下文向量生成輸出序列。解碼器通常使用循環神經網絡(RNN)、長短期記憶網絡(LSTM)或門控循環單元(GRU)等結構。
  3. 注意力機制:在許多現代 Seq2Seq 模型中,採用了注意力機制(Attention),使解碼器在生成每個輸出時能夠關注輸入序列的不同部分。這增強了模型的表現,尤其是在處理長序列時。
  4. 多任務學習:Seq2Seq 模型可以同時處理多種任務,如翻譯和摘要生成。

代碼示例

以下是使用 PyTorch 構建一個簡單的 Seq2Seq 模型的示例。這個示例實現了一個基本的編碼器-解碼器架構。

安裝依賴

確保安裝了 torch 和 torchtext 庫:

pip install torch torchtext

示例代碼

import torch
import torch.nn as nn
import torch.optim as optim

# 定義編碼器
class Encoder(nn.Module):
    def __init__(self, input_dim, emb_dim, hidden_dim):
        super(Encoder, self).__init__()
        self.embedding = nn.Embedding(input_dim, emb_dim)
        self.rnn = nn.GRU(emb_dim, hidden_dim)

    def forward(self, src):
        embedded = self.embedding(src)
        outputs, hidden = self.rnn(embedded)
        return hidden

# 定義解碼器
class Decoder(nn.Module):
    def __init__(self, output_dim, emb_dim, hidden_dim):
        super(Decoder, self).__init__()
        self.embedding = nn.Embedding(output_dim, emb_dim)
        self.rnn = nn.GRU(emb_dim, hidden_dim)
        self.fc_out = nn.Linear(hidden_dim, output_dim)

    def forward(self, input, hidden):
        input = input.unsqueeze(0)  # 增加時間維度
        embedded = self.embedding(input)
        output, hidden = self.rnn(embedded, hidden)
        prediction = self.fc_out(output.squeeze(0))
        return prediction, hidden

# 定義 Seq2Seq 模型
class Seq2Seq(nn.Module):
    def __init__(self, encoder, decoder):
        super(Seq2Seq, self).__init__()
        self.encoder = encoder
        self.decoder = decoder

    def forward(self, src, trg, teacher_forcing_ratio=0.5):
        trg_len = trg.shape[0]
        batch_size = trg.shape[1]
        output_dim = self.decoder.fc_out.out_features
        
        outputs = torch.zeros(trg_len, batch_size, output_dim).to(trg.device)

        hidden = self.encoder(src)

        # 初始輸入為解碼器的開始標記
        input = trg[0, :]

        for t in range(1, trg_len):
            output, hidden = self.decoder(input, hidden)
            outputs[t] = output

            # 決定是否使用教師強制
            teacher_force = torch.rand(1) < teacher_forcing_ratio
            input = trg[t] if teacher_force else output.argmax(1)

        return outputs

# 示例參數
INPUT_DIM = 1000  # 輸入詞彙表大小
OUTPUT_DIM = 1000  # 輸出詞彙表大小
EMB_DIM = 256  # 嵌入維度
HIDDEN_DIM = 512  # 隱藏層維度

# 創建模型實例
encoder = Encoder(INPUT_DIM, EMB_DIM, HIDDEN_DIM)
decoder = Decoder(OUTPUT_DIM, EMB_DIM, HIDDEN_DIM)
model = Seq2Seq(encoder, decoder)

# 打印模型結構
print(model)

Find More

代碼解釋

  1. 編碼器Encoder 類定義了輸入的嵌入層和 GRU 層,負責將輸入序列編碼為隱藏狀態。
  2. 解碼器Decoder 類定義瞭解碼器的嵌入層、GRU 層和輸出層,負責根據編碼器的隱藏狀態生成輸出序列。
  3. Seq2Seq 模型Seq2Seq 類將編碼器和解碼器結合在一起,執行前向傳播,並支持教師強制(teacher forcing)策略。
  4. 示例參數:定義了輸入和輸出的詞彙表大小、嵌入維度和隱藏層維度,並創建了模型實例。

總結

序列到序列模型是處理序列數據的重要工具,廣泛應用於各種 NLP 任務。通過簡單的編碼器-解碼器架構,可以構建出強大的 Seq2Seq 模型,適用於機器翻譯、文本生成等場景。