當序列具有不平衡類時如何訓練 LSTM
我在每個時間步都標記序列,但是數據集中的一些標籤只在兩個更常見的標籤之間非常短暫地出現。因此,NN 偏向於這些常見的標籤。我不能只向它展示更多稀有標籤的示例,因為狀態在序列中非常重要,因此將序列分解會對其預測能力產生負面影響。
以下是數據和標籤的一個非常簡單的示例:
數據:
1 0 0 0 0 2 0 3 0 0 0 0 0 0 0 0 0 0 4 0 3 0 0 0 0 0 0 2 0 1 0 0 0 0 2 0 0 3 0 0
標籤:
1 1 1 1 1 2 2 3 3 3 3 3 3 3 3 3 3 3 4 4 3 3 3 3 3 3 3 2 2 1 1 1 1 1 2 2 2 3 3 3
基本上一個指標出現在序列中,然後這是序列的標籤,直到出現新指標(因此狀態的重要性)
與成本函數成反比的貢獻
處理不平衡數據的另一種方法是加權每個標籤對成本函數的貢獻,與標籤的頻率成反比。在您上面的示例中,我計算了以下類的頻率:
1: 10 2: 7 3: 20 4: 2
因此,您可以將逐個樣本的成本乘以 $ \frac{1}{10} $ 當真正的標籤
1
是 $ \frac{1}{7} $ 對於標籤2
, $ \frac{1}{20} $ 對於標籤3
,和 $ \frac{1}{2} $ 為標籤4
。所以你會看到1
標籤數量是4
標籤的 5 倍,但它們都會做出貢獻 $ \frac{1}{5}^{th} $ 與您的整體成本函數一樣多。換句話說,您可以預期每個標籤對您的成本函數的平均影響大致相同。在實踐中,我會在整個訓練集中使用標籤的頻率,並設置分子,使乘數之和為 1。例如,在上面的示例中,我將使用分數 $ \frac{1.26}{10} $ , $ \frac{1.26}{7} $ , $ \frac{1.26}{20} $ , $ \frac{1.26}{2} $ 加起來〜1。你不需要以這種方式擴展,但如果你不這樣做,你實際上是在修改你的學習率。
使用這種方法(如重採樣)的一個危險是增加了過度擬合稀有標籤的機會。如果您使用這種方法,您可能希望以某種方式規範您的模型。
實際上,我相信大多數深度學習庫都提供此功能。例如,在python庫
keras
中,該keras.models.Model.fit()
方法有一個sample_weight
參數:sample_weight:訓練樣本的可選 Numpy 權重數組,用於加權損失函數(僅在訓練期間)。您可以傳遞與輸入樣本長度相同的平面 (1D) Numpy 數組(權重和样本之間的 1:1 映射),或者在時間數據的情況下,您可以傳遞具有 shape 的 2D 數組
(samples, sequence_length)
,以應用每個樣本的每個時間步長都有不同的權重。在這種情況下,您應該確保sample_weight_mode="temporal"
在compile()
.最後,我會鼓勵你確保你有一個你信任的良好性能指標。使用這樣的方法可能會導致您的模型比實際期望的更頻繁地估計您的稀有標籤。正如蒂姆在評論中所說:
如果某事更常見,那麼它被更普遍地預測是合理的。