在深度學習的背景下,重采樣主要涉及兩個方面:
- 數據層面的重采樣:處理不平衡數據集。
- 模型層面的重采樣:在神經網絡內部進行上采樣(UpSampling)或下采樣(DownSampling),常見于架構如編碼器-解碼器(Encoder-Decoder)或生成對抗網絡(GAN)。
1. 數據層面的重采樣:處理類別不平衡
在許多現實世界的數據集中(如醫療診斷、欺詐檢測),不同類別的樣本數量可能差異巨大。例如,99%的樣本是正常交易,只有1%是欺詐交易。如果直接用這樣的數據訓練模型,模型會傾向于預測多數類,導致對少數類的識別率極差。
解決方法就是通過重采樣來調整訓練集的分布。
A. 過采樣(Oversampling)
增加少數類的樣本數量,使其與多數類相當。
-
隨機過采樣:隨機復制少數類樣本。
- 優點:簡單。
- 缺點:容易導致過擬合,因為模型會多次看到完全相同的樣本。
-
SMOTE(Synthetic Minority Over-sampling Technique):創建新的合成樣本,而不是簡單復制。
- 原理:對每一個少數類樣本,從其K個最近鄰中隨機選擇一個樣本,然后在這兩個樣本的連線上隨機插值一點,作為新樣本。
- 優點:有效增加了樣本多樣性,緩解了過擬合問題。
- 缺點:可能會在多數類樣本密集的區域創造一些“模糊”的樣本,增加類別間的重疊。
B. 欠采樣(Undersampling)
減少多數類的樣本數量,使其與少數類相當。
- 隨機欠采樣:隨機地從多數類中刪除一些樣本。
- 優點:簡單,減少訓練時間。
- 缺點:可能會丟失多數類中包含的重要信息,導致模型欠擬合。
通常,SMOTE(或其變體,如ADASYN)與隨機欠采樣結合使用被認為是效果更好的策略。
在代碼中的實現(以imbalanced-learn
庫為例)
from imblearn.over_sampling import SMOTE
from imblearn.under_sampling import RandomUnderSampler
from imblearn.pipeline import Pipeline
from collections import Counter# 假設 X_train, y_train 是你的訓練數據和標簽
print(f'Original dataset shape {Counter(y_train)}')# 定義一個采樣管道:先SMOTE過采樣,再隨機欠采樣
over = SMOTE(sampling_strategy=0.5) # 使少數類達到多數類的一半數量
under = RandomUnderSampler(sampling_strategy=0.5) # 使多數類降到少數類的兩倍數量
steps = [('o', over), ('u', under)]
pipeline = Pipeline(steps=steps)# 應用重采樣
X_resampled, y_resampled = pipeline.fit_resample(X_train, y_train)print(f'Resampled dataset shape {Counter(y_resampled)}')
現代替代方案:除了重采樣,還可以使用加權損失函數(如class_weight
in PyTorch’s CrossEntropyLoss
or TensorFlow/Keras)。這種方法在計算損失時,給少數類的錯誤預測賦予更高的權重,從而讓模型更關注少數類。這通常是更受歡迎的方法,因為它不改變數據分布,計算高效。
2. 模型層面的重采樣:特征圖的空間變換
在卷積神經網絡(CNN)架構中,特別是用于分割(如U-Net)、檢測(如SSD)或生成(如GAN)的模型中,網絡需要在不同分辨率的特征圖之間進行轉換。這就用到了上采樣和下采樣操作。
A. 下采樣(DownSampling)
目的:增大感受野,提取更抽象、更全局的特征,同時減少計算量。
-
池化層(Pooling Layers):
- 最大池化(Max Pooling):取窗口內的最大值。能更好地保留紋理特征。
- 平均池化(Average Pooling):取窗口內的平均值。能更好地保留整體數據的特征。
- 目前,最大池化更為常用。
-
帶步長的卷積(Strided Convolution):
- 使用
stride > 1
的卷積層,在計算卷積的同時直接實現下采樣。 - 例如,一個
3x3
卷積核,stride=2
,輸出特征圖的高和寬會減半。 - 這是現代架構(如ResNet)的首選,因為卷積層可以學習到最優的下采樣方式,而池化層是確定性的、不可學習的。
- 使用
B. 上采樣(UpSampling)
目的:恢復空間分辨率,將壓縮的、抽象的特征圖映射回高分辨率的空間,用于像素級預測(如圖像分割)或生成圖像。
-
轉置卷積(Transposed Convolution / Deconvolution):
- 雖然不是真正的反卷積,但它是可學習的上采樣方法。
- 它通過插入零值或進行插值來擴展輸入特征圖的大小,然后進行常規卷積操作。
- 缺點:如果核大小和步長參數設置不當,容易產生“棋盤效應”(checkerboard artifacts)。
-
上采樣 + 卷積(Upsampling + Convolution):
- 先使用最近鄰插值(Nearest Neighbor) 或雙線性插值(Bilinear) 等不可學習的插值方法將特征圖尺寸放大。
- 然后跟一個普通的
1x1
或3x3
卷積來平滑和細化特征。 - 這種方法可以有效避免棋盤效應,是許多現代架構(如SRGAN)的選擇。
-
Unpooling:
- 通常與Max Pooling配對使用。記錄下Max Pooling時最大值的位置,在Unpooling時,將值放回原位置,其他位置填0。
- 在U-Net等網絡中有所應用,但不如前兩種方法普遍。
在代碼中的實現(以PyTorch為例)
import torch
import torch.nn as nn# 下采樣
downsample_by_pool = nn.MaxPool2d(kernel_size=2, stride=2) # 使用池化
downsample_by_conv = nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3, stride=2, padding=1) # 使用步長卷積# 上采樣
upsample_by_transpose = nn.ConvTranspose2d(in_channels=64, out_channels=32, kernel_size=2, stride=2) # 轉置卷積
upsample_by_interpolation = nn.Sequential(nn.Upsample(scale_factor=2, mode='nearest'), # 或 'bilinear'nn.Conv2d(in_channels=64, out_channels=32, kernel_size=3, padding=1)
)
總結
方面 | 類型 | 方法 | 目的 | 關鍵點 |
---|---|---|---|---|
數據重采樣 | 過采樣 | 隨機過采樣、SMOTE | 平衡類別分布,解決不平衡問題 | SMOTE創建合成樣本,優于隨機復制 |
欠采樣 | 隨機欠采樣 | 平衡類別分布,解決不平衡問題 | 可能丟失信息,常與過采樣結合使用 | |
模型重采樣 | 下采樣 | 池化層、步長卷積 | 擴大感受野,減少計算量 | 步長卷積是現代首選 |
上采樣 | 轉置卷積、插值+卷積 | 恢復空間分辨率,用于密集預測 | 插值+卷積可避免棋盤效應 |
選擇哪種重采樣技術完全取決于你的具體任務:
- 如果你的數據標簽不平衡,優先考慮加權損失函數,如果效果不佳再嘗試SMOTE結合欠采樣。
- 如果你在設計網絡結構(如圖像分割),步長卷積用于下采樣,最近鄰/雙線性上采樣 + 卷積是穩健且高效的上采樣選擇。