簡單transformer運用

通俗易懂解讀:hw04.py 文件內容與 Transformer 的應用

這個文件是一個 Python 腳本(hw04.py),用于完成 NTU 2021 Spring 機器學習課程的 HW4 作業任務:揚聲器分類(Speaker Classification)。它主要通過 Transformer 模型(尤其是自注意力機制,Self-Attention)來實現分類,并提供了訓練和推理代碼。以下我會詳細講解文件的結構,重點教你如何使用 Transformer 和 Self-Attention,并讓你明白如何訓練模型、調整參數。


1. 文件概述
  • 任務:從語音特征(梅爾頻譜圖,mel-spectrogram)中分類揚聲器(600 個類別)。
  • 數據集:Voxceleb2 數據集的子集,包含 600 個揚聲器的音頻特征。
  • 目標
    • 學習使用 Transformer 模型(Simple 級別)。
    • 調整 Transformer 參數(Medium 級別)。
    • 構建 Conformer(Hard 級別,代碼中未實現)。
    • 進一步實現 Self-Attention Pooling 和 Additive Margin Softmax(Boss 級別,代碼中未實現)。
  • 代碼結構
    • 數據準備:解壓數據、加載數據集、定義 DataLoader。
    • 模型定義:使用 TransformerEncoderLayer 實現分類器。
    • 訓練:實現訓練循環、學習率調度和驗證。
    • 推理:加載模型,預測測試集揚聲器并生成提交文件。

2. Transformer 和 Self-Attention 的原理與應用

先簡單講解 Transformer 和 Self-Attention 的原理,然后結合代碼看它們如何被使用。

(1) Transformer 和 Self-Attention 原理
  • Transformer
    • 由 Google 在 2017 年論文《Attention is All You Need》提出,是一種基于注意力機制的模型,取代了傳統的 RNN。
    • 核心組件:自注意力(Self-Attention)前饋神經網絡(Feedforward Network)
    • 優點:能并行處理序列(不像 RNN 逐個處理),捕捉長距離依賴。
  • Self-Attention
    • 是一種注意力機制,讓模型在處理序列中的每個元素時,關注整個序列的其他元素。
    • 比如處理“[蘋果, 香蕉, 橙子]”時,Self-Attention 會計算:
      • “蘋果”和其他元素(香蕉、橙子)的相關性。
      • “香蕉”和其他元素的相關性,依此類推。
    • 計算步驟
      1. 將輸入序列(每個元素是一個向量)映射為 Query(Q)、Key(K)、Value(V)三個向量。
      2. 計算注意力分數:Attention(Q,K,V)=softmax(QKTdk)V \text{Attention}(Q, K, V) = \text{softmax}(\frac{QK^T}{\sqrt{d_k}})V Attention(Q,K,V)=softmax(dk??QKT?)V。
      3. 輸出一個加權后的向量,表示當前元素對整個序列的關注結果。
(2) 代碼中的 Transformer 和 Self-Attention
  • 模型定義(Classifier 類):

    python

    收起自動換行運行

    復制

    class Classifier(nn.Module): def __init__(self, d_model=80, n_spks=600, dropout=0.1): super().__init__() self.prenet = nn.Linear(40, d_model) self.encoder_layer = nn.TransformerEncoderLayer( d_model=d_model, dim_feedforward=256, nhead=2 ) self.pred_layer = nn.Sequential( nn.Linear(d_model, d_model), nn.ReLU(), nn.Linear(d_model, n_spks), )

    • self.prenet:將輸入特征(梅爾頻譜圖,維度為 40)投影到 d_model=80 的維度,為 Transformer 處理做準備。
    • self.encoder_layer:使用 PyTorch 的 nn.TransformerEncoderLayer,這是一個標準的 Transformer 編碼層,包含:
      • Self-Attention:通過 nhead=2 設置多頭注意力(Multi-Head Attention),將 d_model 均分為 2 頭,每頭處理 d_model/nhead=40 維度。
      • Feedforward Network:通過 dim_feedforward=256 設置前饋網絡的隱藏層維度。
      • 默認使用 dropout(0.1)和 ReLU 激活函數。
    • 代碼中注釋掉了一個 nn.TransformerEncoder,原本應該是堆疊多個 TransformerEncoderLayer(比如 num_layers=2),但當前只用了一層。
  • 前向傳播(forward 方法):

    python

    收起自動換行運行

    復制

    def forward(self, mels): out = self.prenet(mels) # (batch size, length, 40) -> (batch size, length, d_model) out = out.permute(1, 0, 2) # (batch size, length, d_model) -> (length, batch size, d_model) out = self.encoder_layer(out) # Transformer 編碼 out = out.transpose(0, 1) # (length, batch size, d_model) -> (batch size, length, d_model) stats = out.mean(dim=1) # 平均池化:(batch size, d_model) out = self.pred_layer(stats) # (batch size, n_spks) return out

    • Self-Attention 的作用
      • 輸入 mels 是梅爾頻譜圖,形狀為 (batch size, length, 40),表示一個 batch 的音頻特征。
      • 經過 self.prenet,維度變成 (batch size, length, d_model)。
      • out = out.permute(1, 0, 2) 調整維度為 (length, batch size, d_model),因為 TransformerEncoderLayer 期望輸入是 (sequence length, batch size, d_model)。
      • self.encoder_layer(out) 執行 Self-Attention 和 Feedforward 操作:
        • Self-Attention 計算每個時間步(幀)對其他所有幀的關注權重。
        • Feedforward 對每個幀獨立應用前饋網絡。
      • 最后通過平均池化(out.mean(dim=1))將序列維度壓縮,得到每個樣本的特征向量 (batch size, d_model),再通過 self.pred_layer 輸出分類結果 (batch size, n_spks)。

3. 如何使用 Transformer

通過這個代碼,我教你如何在 PyTorch 中使用 Transformer 來完成一個分類任務。

(1) 定義 Transformer 模型
  • 使用 nn.TransformerEncoderLayer 構建基本層:

    python

    收起自動換行運行

    復制

    self.encoder_layer = nn.TransformerEncoderLayer( d_model=d_model, # 輸入和輸出的特征維度 nhead=2, # 多頭注意力的頭數,d_model 必須能被 nhead 整除 dim_feedforward=256, # 前饋網絡的隱藏層維度 dropout=0.1 # dropout 比例 )

  • 如果需要堆疊多層,可以用 nn.TransformerEncoder:

    python

    收起自動換行運行

    復制

    self.encoder = nn.TransformerEncoder(self.encoder_layer, num_layers=2)

    (代碼中注釋掉了這部分,當前只用了一層。)
(2) 輸入數據準備
  • Transformer 需要輸入形狀為 (sequence length, batch size, d_model):
    • 代碼中通過 out.permute(1, 0, 2) 調整維度。
    • 輸入的 mels 是 (batch size, length, 40),先通過 self.prenet 投影到 d_model=80,再調整維度。
(3) 前向傳播
  • 直接調用 self.encoder_layer(out),PyTorch 會自動處理 Self-Attention 和 Feedforward。
  • 輸出需要根據任務調整:
    • 這里是分類任務,所以用平均池化(out.mean(dim=1))壓縮序列維度,然后通過全連接層輸出分類結果。
(4) 應用場景
  • Transformer 適合處理序列數據(如語音、文本)。
  • Self-Attention 讓模型能捕捉序列中任意兩個位置之間的關系,比如語音中不同幀之間的關聯。

4. 如何訓練模型

訓練一個模型需要準備數據、定義模型、設置優化器和學習率調度器,然后進入訓練循環。以下是代碼中的訓練過程解析。

(1) 數據準備
  • 數據集(myDataset 類):
    • 加載梅爾頻譜圖(torch.load),隨機截取 segment_len=128 幀。
    • 標簽是揚聲器 ID(從 mapping.json 中獲取)。
  • DataLoader(get_dataloader 函數):
    • 按 90%(訓練)/10%(驗證)劃分數據集。
    • 使用 collate_batch 函數填充批次數據,確保長度一致(填充值為 -20,表示極小的對數值)。
(2) 模型和優化器
  • 模型:model = Classifier(n_spks=speaker_num).to(device),初始化 Classifier。
  • 損失函數:criterion = nn.CrossEntropyLoss(),用于多分類任務。
  • 優化器:optimizer = AdamW(model.parameters(), lr=1e-3),使用 AdamW 優化器,初始學習率 1e-3。
  • 學習率調度器(get_cosine_schedule_with_warmup):
    • 包含 Warmup 階段(前 1000 步,學習率從 0 線性增加到 1e-3)。
    • 之后按余弦衰減(Cosine Decay)降低學習率。
(3) 訓練循環(main 函數)
  • 訓練步驟

    python

    收起自動換行運行

    復制

    for step in range(total_steps): batch = next(train_iterator) loss, accuracy = model_fn(batch, model, criterion, device) loss.backward() optimizer.step() scheduler.step() optimizer.zero_grad()

    • 每步從 train_loader 獲取一個批次。
    • 計算損失和準確率(model_fn)。
    • 反向傳播、優化器更新參數、調度器調整學習率、清空梯度。
  • 驗證
    • 每 2000 步(valid_steps)驗證一次,計算驗證集準確率。
    • 保存最佳模型(best_accuracy)。
  • 保存模型:每 10,000 步(save_steps)保存最佳模型到 model.ckpt。
(4) 推理(main 函數,推理部分)
  • 加載訓練好的模型,預測測試集揚聲器,生成 output.csv(格式:Id, Category)。

5. 如何調整 Transformer 參數

調整 Transformer 參數是 HW4 的 Medium 級別任務。以下是代碼中可以調整的部分,以及調整的意義。

(1) 調整參數的地方
  • 在 Classifier 的 __init__ 中:

    python

    收起自動換行運行

    復制

    self.encoder_layer = nn.TransformerEncoderLayer( d_model=d_model, dim_feedforward=256, nhead=2 )

    • d_model=80:特征維度,增加會提升模型容量,但計算量更大。
    • nhead=2:多頭注意力頭數,d_model 必須能被整除(當前 80/2=40)。
    • dim_feedforward=256:前饋網絡隱藏層維度,增加會增強模型表達能力。
  • 堆疊多層(當前注釋掉了):

    python

    收起自動換行運行

    復制

    self.encoder = nn.TransformerEncoder(self.encoder_layer, num_layers=2)

    • num_layers=2:增加層數會讓模型更深,能捕捉更復雜的模式,但可能過擬合。
(2) 調整建議
  • 增大 d_model:比如從 80 增加到 128,增強模型容量,但需要確保 nhead 能整除(比如 nhead=4)。
  • 增加 nhead:比如從 2 增加到 4,允許多頭注意力捕捉更多不同類型的依賴關系。
  • 調整 dim_feedforward:比如從 256 增加到 512,增強前饋網絡的能力。
  • 增加層數:取消注釋 self.encoder,設置 num_layers=3,讓模型更深。
  • 調整 dropout:默認 0.1,可以嘗試 0.2 或 0.05,防止過擬合。
  • 效果:文檔中提到(HW04.pdf 第13頁),調整參數后公共基準從 0.82523(Simple)提升到 0.90547(Medium)。
(3) 注意事項
  • 增加參數會增加計算量,可能需要更大的 batch size 或更長的訓練時間。
  • 過大的模型可能過擬合,需要調整學習率或增加 dropout。

6. 總結:如何使用 Transformer 訓練模型
  • 步驟
    1. 準備數據:加載梅爾頻譜圖,劃分訓練/驗證集,用 DataLoader 批次加載。
    2. 定義模型:使用 nn.TransformerEncoderLayer,設置 d_model、nhead 等參數。
    3. 前向傳播:通過 Self-Attention 處理序列,池化后輸出分類結果。
    4. 訓練:設置優化器、學習率調度器,循環計算損失、更新參數。
    5. 調整參數:修改 d_model、nhead、num_layers 等,優化性能。
  • Self-Attention 的作用:捕捉序列中幀與幀之間的關系,比如語音中不同時間點的關聯。
  • 訓練技巧
    • 使用 Warmup 學習率調度(代碼中已實現)。
    • 定期驗證,保存最佳模型。
    • 調整參數時,觀察驗證集準確率,避免過擬合。

7. 動手實踐

如果你想自己訓練一個類似模型,可以用以下步驟:

  1. 環境準備
    • 安裝 PyTorch:pip install torch
    • 下載數據集(代碼中的鏈接已失效,可用其他語音數據集如 LibriSpeech 替代)。
  2. 修改代碼
    • 調整 d_model=128、nhead=4、num_layers=3,觀察效果。
    • 實現 Conformer(參考 https://arxiv.org/abs/2005.08100)。
  3. 訓練
    • 運行 main 函數,設置 total_steps=70000,觀察驗證準確率。
  4. 推理
    • 用訓練好的模型預測測試集,生成提交文件

逐行講解 Conformer 代碼實現

由于你之前沒有接觸過 Conformer,我會從零開始詳細講解之前提供的 ConformerBlock 和 ConformerConvModule 的代碼實現,逐行分析其功能、原理和實現細節。Conformer 是 Transformer 的變種,專為語音任務設計,結合了全局建模(Self-Attention)和局部建模(卷積)的優勢。以下代碼來自之前修改的 hw04.py,我們會重點聚焦 Conformer 的實現部分。


1. Conformer 代碼實現

以下是 ConformerConvModule 和 ConformerBlock 的完整代碼,我會逐行解釋其作用。

import torch
import torch.nn as nn
import torch.nn.functional as F# 卷積模塊,用于捕捉局部特征
class ConformerConvModule(nn.Module):def __init__(self, d_model=80, kernel_size=31, dropout=0.1):super().__init__()# Pointwise Convolution 1self.pointwise_conv1 = nn.Conv1d(d_model, d_model * 2, kernel_size=1, stride=1, padding=0, bias=True)self.glu = nn.GLU(dim=1)  # Gated Linear Unit# Depthwise Convolutionself.depthwise_conv = nn.Conv1d(d_model,d_model,kernel_size=kernel_size,stride=1,padding=(kernel_size - 1) // 2,groups=d_model,  # Depthwisebias=True)self.bn = nn.BatchNorm1d(d_model)self.swish = nn.Swish()# Pointwise Convolution 2self.pointwise_conv2 = nn.Conv1d(d_model, d_model, kernel_size=1, stride=1, padding=0, bias=True)self.dropout = nn.Dropout(dropout)def forward(self, x):# x: (batch, length, d_model) -> (batch, d_model, length) for convx = x.transpose(1, 2)# Pointwise Conv 1 + GLUx = self.pointwise_conv1(x)x = self.glu(x)# Depthwise Conv + BN + Swishx = self.depthwise_conv(x)x = self.bn(x)x = self.swish(x)# Pointwise Conv 2x = self.pointwise_conv2(x)x = self.dropout(x)# Back to (batch, length, d_model)x = x.transpose(1, 2)return x# Conformer 塊,包含 FFN、Self-Attention 和卷積模塊
class ConformerBlock(nn.Module):def __init__(self, d_model=80, nhead=2, dim_feedforward=256, dropout=0.1, kernel_size=31):super().__init__()# Feed-Forward Module (half-step)self.ffn1 = nn.Sequential(nn.LayerNorm(d_model),nn.Linear(d_model, dim_feedforward),nn.Swish(),nn.Dropout(dropout),nn.Linear(dim_feedforward, d_model))# Multi-Head Self-Attentionself.self_attention = nn.MultiheadAttention(d_model, nhead, dropout=dropout)self.norm1 = nn.LayerNorm(d_model)self.dropout1 = nn.Dropout(dropout)# Convolution Moduleself.conv_module = ConformerConvModule(d_model, kernel_size, dropout)self.norm2 = nn.LayerNorm(d_model)self.dropout2 = nn.Dropout(dropout)# Feed-Forward Module (half-step)self.ffn2 = nn.Sequential(nn.LayerNorm(d_model),nn.Linear(d_model, dim_feedforward),nn.Swish(),nn.Dropout(dropout),nn.Linear(dim_feedforward, d_model))self.norm3 = nn.LayerNorm(d_model)self.dropout3 = nn.Dropout(dropout)def forward(self, x):# x: (length, batch, d_model)# FFN 1 (half-step)x = x + 0.5 * self.dropout1(self.ffn1(x))# Multi-Head Self-Attentionattn_output, _ = self.self_attention(x, x, x)x = self.norm1(x + self.dropout1(attn_output))# Convolution Modulex = self.norm2(x + self.dropout2(self.conv_module(x)))# FFN 2 (half-step)x = self.norm3(x + self.dropout3(self.ffn2(x)))return x

2. 逐行講解 ConformerConvModule
(1) 初始化方法 __init__

python

收起自動換行運行

復制

class ConformerConvModule(nn.Module): def __init__(self, d_model=80, kernel_size=31, dropout=0.1):

  • class ConformerConvModule(nn.Module):定義一個卷積模塊,繼承 PyTorch 的 nn.Module 類,所有神經網絡模塊都需要繼承這個類。
  • d_model=80:輸入和輸出的特征維度(類似 Transformer 的隱藏維度)。
  • kernel_size=31:卷積核大小,決定了捕捉局部特征的范圍(越大,感受野越大)。
  • dropout=0.1:Dropout 比例,防止過擬合。

python

收起自動換行運行

復制

super().__init__()

  • 調用父類 nn.Module 的初始化方法,確保正確初始化模塊。

python

收起自動換行運行

復制

self.pointwise_conv1 = nn.Conv1d(d_model, d_model * 2, kernel_size=1, stride=1, padding=0, bias=True)

  • nn.Conv1d:一維卷積,適用于序列數據(如語音的梅爾頻譜圖)。
  • d_model:輸入通道數(特征維度)。
  • d_model * 2:輸出通道數,升維到兩倍,用于后續 GLU(Gated Linear Unit)操作。
  • kernel_size=1:點卷積(Pointwise Convolution),只對每個時間步獨立操作,不涉及鄰域。
  • stride=1:步幅為 1,不改變序列長度。
  • padding=0:無填充,因為 kernel_size=1 不需要填充。
  • bias=True:包含偏置參數。

python

收起自動換行運行

復制

self.glu = nn.GLU(dim=1) # Gated Linear Unit

  • nn.GLU:Gated Linear Unit,一種門控機制。
  • dim=1:在通道維度上操作(因為輸入是 (batch, channel, length))。
  • GLU 的作用:將 d_model * 2 的通道分成兩部分,一部分作為值,另一部分通過 sigmoid 激活作為門控,輸出 d_model 個通道。公式為: GLU(x)=x1?σ(x2)\text{GLU}(x) = x_1 \cdot \sigma(x_2)GLU(x)=x1??σ(x2?) 其中 x1 x_1 x1? 和 x2 x_2 x2? 是通道拆分的兩部分。

python

收起自動換行運行

復制

self.depthwise_conv = nn.Conv1d( d_model, d_model, kernel_size=kernel_size, stride=1, padding=(kernel_size - 1) // 2, groups=d_model, # Depthwise bias=True )

  • nn.Conv1d:定義深度可分離卷積(Depthwise Convolution)。
  • d_model:輸入和輸出通道數保持一致。
  • kernel_size=31:卷積核大小,捕捉局部特征。
  • stride=1:步幅為 1。
  • padding=(kernel_size - 1) // 2:自動計算填充,確保輸出長度不變(例如 kernel_size=31 時,padding=15)。
  • groups=d_model:深度卷積,每個輸入通道獨立卷積,減少參數量。
  • bias=True:包含偏置。

python

收起自動換行運行

復制

self.bn = nn.BatchNorm1d(d_model)

  • nn.BatchNorm1d:一維批歸一化,作用于通道維度。
  • 歸一化每個通道的特征,加速訓練,穩定梯度。

python

收起自動換行運行

復制

self.swish = nn.Swish()

  • nn.Swish:激活函數,公式為 Swish(x)=x?σ(x) \text{Swish}(x) = x \cdot \sigma(x) Swish(x)=x?σ(x),比 ReLU 更平滑。

python

收起自動換行運行

復制

self.pointwise_conv2 = nn.Conv1d(d_model, d_model, kernel_size=1, stride=1, padding=0, bias=True)

  • 第二個點卷積,將特征降維回 d_model。

python

收起自動換行運行

復制

self.dropout = nn.Dropout(dropout)

  • Dropout 層,隨機丟棄部分神經元,防止過擬合。
(2) 前向傳播方法 forward

python

收起自動換行運行

復制

def forward(self, x):

  • 定義前向傳播,輸入 x 是 (batch, length, d_model) 的張量。

python

收起自動換行運行

復制

x = x.transpose(1, 2)

  • transpose(1, 2):將 (batch, length, d_model) 轉換為 (batch, d_model, length),因為 nn.Conv1d 期望輸入是 (batch, channel, length)。

python

收起自動換行運行

復制

x = self.pointwise_conv1(x)

  • 應用第一個點卷積,將通道數從 d_model 升到 d_model * 2。

python

收起自動換行運行

復制

x = self.glu(x)

  • 應用 GLU,將通道數降回 d_model,并通過門控機制選擇性保留信息。

python

收起自動換行運行

復制

x = self.depthwise_conv(x)

  • 應用深度卷積,捕捉局部特征(kernel_size=31 覆蓋 31 個時間步)。

python

收起自動換行運行

復制

x = self.bn(x)

  • 應用批歸一化,穩定特征分布。

python

收起自動換行運行

復制

x = self.swish(x)

  • 應用 Swish 激活,增加非線性。

python

收起自動換行運行

復制

x = self.pointwise_conv2(x)

  • 應用第二個點卷積,進一步處理特征,保持維度為 (batch, d_model, length)。

python

收起自動換行運行

復制

x = self.dropout(x)

  • 應用 Dropout,防止過擬合。

python

收起自動換行運行

復制

x = x.transpose(1, 2)

  • 將維度轉回 (batch, length, d_model),與輸入一致。

python

收起自動換行運行

復制

return x

  • 返回處理后的張量。

3. 逐行講解 ConformerBlock
(1) 初始化方法 __init__

python

收起自動換行運行

復制

class ConformerBlock(nn.Module): def __init__(self, d_model=80, nhead=2, dim_feedforward=256, dropout=0.1, kernel_size=31):

  • 定義 Conformer 塊,參數與 ConformerConvModule 類似。
  • nhead=2:多頭注意力的頭數。
  • dim_feedforward=256:前饋網絡的隱藏層維度。

python

收起自動換行運行

復制

super().__init__()

python

收起自動換行運行

復制

self.ffn1 = nn.Sequential( nn.LayerNorm(d_model), nn.Linear(d_model, dim_feedforward), nn.Swish(), nn.Dropout(dropout), nn.Linear(dim_feedforward, d_model) )

  • 定義第一個前饋模塊(FFN1)。
  • nn.LayerNorm(d_model):層歸一化,歸一化每個時間步的特征。
  • nn.Linear(d_model, dim_feedforward):將維度從 d_model 擴展到 dim_feedforward。
  • nn.Swish():Swish 激活。
  • nn.Dropout(dropout):Dropout。
  • nn.Linear(dim_feedforward, d_model):降維回 d_model。

python

收起自動換行運行

復制

self.self_attention = nn.MultiheadAttention(d_model, nhead, dropout=dropout)

  • nn.MultiheadAttention:多頭自注意力。
  • d_model:輸入維度。
  • nhead=2:頭數,每頭處理 d_model/nhead=40 維度。
  • dropout=dropout:注意力中的 Dropout。

python

收起自動換行運行

復制

self.norm1 = nn.LayerNorm(d_model) self.dropout1 = nn.Dropout(dropout)

  • norm1 和 dropout1:用于自注意力后的歸一化和 Dropout。

python

收起自動換行運行

復制

self.conv_module = ConformerConvModule(d_model, kernel_size, dropout)

  • 調用 ConformerConvModule,處理局部特征。

python

收起自動換行運行

復制

self.norm2 = nn.LayerNorm(d_model) self.dropout2 = nn.Dropout(dropout)

  • norm2 和 dropout2:卷積模塊后的歸一化和 Dropout。

python

收起自動換行運行

復制

self.ffn2 = nn.Sequential( nn.LayerNorm(d_model), nn.Linear(d_model, dim_feedforward), nn.Swish(), nn.Dropout(dropout), nn.Linear(dim_feedforward, d_model) )

  • 定義第二個前饋模塊(FFN2),結構與 FFN1 相同。

python

收起自動換行運行

復制

self.norm3 = nn.LayerNorm(d_model) self.dropout3 = nn.Dropout(dropout)

  • norm3 和 dropout3:FFN2 后的歸一化和 Dropout。
(2) 前向傳播方法 forward

python

收起自動換行運行

復制

def forward(self, x):

  • 輸入 x 是 (length, batch, d_model),符合 Transformer 的輸入格式。

python

收起自動換行運行

復制

x = x + 0.5 * self.dropout1(self.ffn1(x))

  • 應用 FFN1,半步前饋(系數 0.5 是 Conformer 的設計)。
  • self.ffn1(x):通過 FFN1 處理。
  • self.dropout1(...):應用 Dropout。
  • x + 0.5 * ...:殘差連接,穩定訓練。

python

收起自動換行運行

復制

attn_output, _ = self.self_attention(x, x, x)

  • 應用多頭自注意力。
  • self.self_attention(x, x, x):輸入 Query、Key、Value 均為 x,計算自注意力。
  • attn_output:注意力輸出,形狀仍為 (length, batch, d_model)。
  • _:忽略注意力權重。

python

收起自動換行運行

復制

x = self.norm1(x + self.dropout1(attn_output))

  • x + self.dropout1(attn_output):殘差連接。
  • self.norm1(...):層歸一化。

python

收起自動換行運行

復制

x = self.norm2(x + self.dropout2(self.conv_module(x)))

  • 應用卷積模塊。
  • self.conv_module(x):通過 ConformerConvModule 處理。
  • self.dropout2(...):Dropout。
  • x + ...:殘差連接。
  • self.norm2(...):層歸一化。

python

收起自動換行運行

復制

x = self.norm3(x + self.dropout3(self.ffn2(x)))

  • 應用 FFN2,與 FFN1 類似。

python

收起自動換行運行

復制

return x

  • 返回處理后的張量,形狀不變。

4. 總結與使用
  • ConformerConvModule:通過卷積捕捉局部特征,適合語音任務中的短時相關性。
  • ConformerBlock:結合 FFN、Self-Attention 和卷積,平衡全局和局部建模。
  • 如何使用
    • 在 Classifier 中替換 TransformerEncoderLayer 為 ConformerBlock。
    • 堆疊多層:self.encoder = nn.Sequential(*[ConformerBlock(...) for _ in range(2)])。
    • 調整參數(如 d_model、kernel_size)優化性能。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/83388.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/83388.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/83388.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

redis的哨兵模式和Redis cluster

目錄 一. redis的主從復制 二. 哨兵模式 2.1 定義 2.2 作用 2.3 配置實例 三. Redis cluster 3.1 定義 3.2 作用 3.3 配置實例 1. 新建集群文件目錄 2. 準備可執行文件到每個文件夾 3. 開啟群集功能 4. 啟動redis節點 5. 查看是否啟動成功 6. 啟動集群 7. 測試…

簡述八大排序(Sort)

1.插入排序 1.1直接插入排序 給定一組數據,若數據只有一個肯定是有序的,我們將無序數據一個個插入到已有序的數據中。用i遍歷無序數據,j遍歷有序數據,找到合適插入位置,用tmp存放目標插入數據,將其與j對應…

xcode 編譯運行錯誤 Sandbox: rsync(29343) deny(1) file-write-create

解決方法 方法一:修改Targets -> Build Settings 中 ENABLE_USER_SCRIPT_SANDBOXING 設置 NO 方法二:項目使用cocoaPods進行三方管理 且 使用了 use_frameworks,把 use_frameworks 注釋掉,然后重新自行pod install

linux系統中防火墻的操作

防火墻 開放ssh端口 sudo ufw allow 22/tcp # 允許 SSH 連接 sudo ufw enable開放防火墻端口 sudo ufw allow 80/tcp # HTTP sudo ufw allow 443/tcp # HTTPS(如果需要) sudo ufw enable查看擋墻防火墻設置 sudo ufw status刪除其中一條防火墻規…

[特殊字符] 超強 Web React版 PDF 閱讀器!支持分頁、縮放、旋轉、全屏、懶加載、縮略圖!

在現代 Web 項目中,PDF 瀏覽是一個常見需求:從政務公文到合同協議,PDF 文件無處不在。但很多方案要么體驗不佳,要么集成復雜。今天,我給大家帶來一個開箱即用、功能全面的 PDF 預覽組件 —— [PDFView](https://www.np…

設計模式——策略設計模式(行為型)

摘要 策略設計模式是一種行為型設計模式,它定義了一系列算法并將每個算法封裝起來,使它們可以相互替換。該模式讓算法的變化獨立于使用算法的客戶,從而使得算法可以靈活地切換和擴展。其主要角色包括策略接口、具體策略類和環境類。策略模式…

DeepSeek-R1-0528,官方的端午節特別獻禮

DeepSeek:端午安康!刻在國人骨子里的浪漫 2025 年 05 月 28 日 | DeepSeek 端午特別獻禮 當粽葉飄香時,DeepSeek 悄然帶來一份節日驚喜 版本號 DeepSeek-R1-0528 正式上線 官方賦予它的靈魂是: 思考更深 推理更強 用戶通過官網…

mac安裝brew時macos無法信任ruby的解決方法

背景 在使用如下腳本安裝brew時,遇到安裝ruby,macos不信任外部軟件,在安全性點擊信任仍然無法安裝。 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"如何解決 本地安裝好符…

2025音頻傳輸模塊全球選購指南:高品質音頻體驗的品牌之選

隨著無線技術的迅猛發展,音頻傳輸模塊(Audio Transmission Module)已成為高品質音頻體驗的關鍵技術之一。它們廣泛應用于智能家居、無線耳機、會議系統、廣播設備以及專業音頻領域。面對市場上多樣化的產品,如何選擇適合自己需求的…

解析樓宇自控系統:分布式結構的核心特點與優勢展現

在建筑智能化發展的進程中,樓宇自控系統作為實現建筑高效運行與管理的關鍵,其系統結構的選擇至關重要。傳統的集中式樓宇自控系統在面對日益復雜的建筑環境和多樣化的管理需求時,逐漸暴露出諸多弊端,如可靠性低、擴展性差、響應速…

Spring Boot對一些技術框架進行了統一版本號管理

這個說法是 正確的。 Spring Boot 對許多常用依賴進行了版本管理,因此在項目中引入這些依賴時,通常不需要指定版本號。 Spring Boot 依賴版本管理 🛠? spring-boot-starter-parent:當你的項目在 pom.xml (Maven 項目) 中繼承自…

關于MySQL的索引

一、索引 1、索引概述 1.1、介紹 索引( index )是幫助 MySQL 高效獲取數據的數據結構 ( 有序 ) 。在數據之外,數據庫系統還維護著滿足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據&…

微服務常用日志追蹤方案:Sleuth + Zipkin + ELK

在微服務架構中,一個用戶請求往往需要經過多個服務的協同處理。為了有效追蹤請求的完整調用鏈路,需要一套完整的日志追蹤方案。Sleuth Zipkin ELK 組合提供了完整的解決方案 Sleuth:生成和傳播追蹤IDZipkin:收集、存儲和可視化…

R語言基礎| 創建數據集

在R語言中,有多種數據類型,用以存儲和處理數據。每種數據類型都有其特定的用途和操作函數,使得R語言在處理各種數據分析任務時非常靈活和強大: 向量(Vector): 向量是R語言中最基本的數據類型,它…

nssctf第二題[SWPUCTF 2021 新生賽]簡簡單單的邏輯

這是題目&#xff0c;下載后得到一個python文件,打開 解讀代碼&#xff1a; for i in range(len(list)):key (list[i]>>4)((list[i] & 0xf)<<4)result str(hex(ord(flag[i])^key))[2:].zfill(2)list[i]>>4&#xff1a;從列表中取數字同時高4位向右位…

mysql(十五)

目錄 子查詢 1.準備工作 2--創建表格 3--插入數據 2.where 子查詢單列單個數據 格式 查詢 3.where 子查詢單列多個數據(in) 格式 查詢 使用子查詢 4.from 多行多數據 格式 查詢 子查詢 將select的查詢的返回結果 當成另外一個selet語句的內容去使用。 子查詢放在()里面 注意…

【HarmonyOS 5】鴻蒙Taro跨端框架

?Taro跨端框架? 支持React語法開發鴻蒙應用&#xff0c;架構分為三層&#xff1a; ArkVM層運行業務代碼和React核心TaroElement樹處理節點創建和屬性綁定TaroRenderNode虛擬節點樹與上屏節點一一對應 import { Component } from tarojs/taro export default class MyCompon…

華為OD機試真題——會議接待 /代表團坐車(2025A卷:200分)Java/python/JavaScript/C++/C語言/GO六種最佳實現

2025 A卷 200分 題型 本文涵蓋詳細的問題分析、解題思路、代碼實現、代碼詳解、測試用例以及綜合分析; 并提供Java、python、JavaScript、C++、C語言、GO六種語言的最佳實現方式! 本文收錄于專欄:《2025華為OD真題目錄+全流程解析/備考攻略/經驗分享》 華為OD機試真題《會議…

C語言---動態內存管理、柔性數組

一、malloc和free 1、變長數組 變長數組是指數組的大小可以通過變量來指定。 在c99以及之后的標準中&#xff1a; #include<stdio.h> int main() { int n0; scanf("%d",&n); } 2、malloc和free 這個函數向內存申請一塊連續可用的空間&#xff0c;并返…

WEBSTORM前端 —— 第3章:移動 Web —— 第4節:移動適配-VM

目錄 一、適配方案 二、VM布局 ?編輯 三、vh布局 四、案例—酷我音樂 一、適配方案 二、VM布局 三、vh布局 四、案例—酷我音樂