Loss 學習筆記


在機器學習中,我們使用 loss/cost 表示當前模型與理想模型的差距。訓練的目的,就是不斷縮小 loss/cost。
簡單直接的classification error 很難精確描述模型與理想模型之間的距離。需要建立別的更有效的loss函數。

pytorch中常用的方法如下:

每個損失函數的構造函數都會有自己的參數
criterion = LossCriterion()
loss = criterion(x, y)

訓練過程中的Loss

煉丹師的自我修養:如何分析訓練過程loss異常 (qq.com)

在面對模型不收斂的時候,首先要保證訓練的次數夠多。在訓練過程中,loss並不是一直在下降,准確率一直在提升的,會有一些震盪存在。只要總體趨勢是在收斂就行。若訓練次數夠多(一般上千次,上萬次,或者幾十個epoch)沒收斂,再考慮采取措施解決。

  • train loss 不斷下降,test loss不斷下降,說明網絡仍在學習;
  • train loss 不斷下降,test loss趨於不變,說明網絡過擬合;
  • train loss 趨於不變,test loss不斷下降,說明數據集100%有問題;
  • train loss 趨於不變,test loss趨於不變,說明學習遇到瓶頸,需要減小學習率或批量數目;
  • train loss 不斷上升,test loss不斷上升,說明網絡結構設計不當,訓練超參數設置不當,數據集經過清洗等問題。

Cross-Entropy-Loss

交叉熵損失函數的目的就是使目標端輸出的分布與真實分布盡可能一致。

交叉熵,部分參考:

博客 - 神經網絡的分類模型 LOSS 函數為什么要用 CROSS ENTROPY
知乎 - 損失函數 - 交叉熵損失函數
PyTorch(七)——損失函數

如果用 MSE 計算 loss,輸出的曲線是波動的,有很多局部的極值點。 即,非凸優化問題 (non-convex)。cross entropy 計算 loss,則依舊是一個凸優化問題,用梯度下降求解時,凸優化問題有很好的收斂特性。
cross-entropy 更清晰的描述了模型與理想模型的距離。交叉熵主要是用來判定實際的輸出與期望的輸出的接近程度。注意:交叉熵不是對稱的。
交叉熵的計算公式為:

\[CE = - \sum\limits_{k = 1}^N {{p_k}\log {q_k}} \]

其中p表示真實值,在這個公式中是one-hot形式;log底數為2,q是預測值,在這里假設已經是經過softmax后的結果了。

分類問題,都用 one hot + cross entropy
training 過程中,分類問題用 cross entropy,回歸問題用 mean squared error。
training 之后,validation/testing 時,使用 classification error,更直觀,而且是我們最關注的指標。

模型預測學習過程中:

  1. 神經網絡最后一層得到每個類別的得分scores;
  2. 該得分經過sigmoid(或softmax)函數獲得概率輸出;
  3. 模型預測的類別概率輸出與真實類別的one hot形式進行交叉熵損失函數的計算。

使用邏輯函數得到概率,並結合交叉熵當損失函數時,在模型效果差的時候學習速度比較快,在模型效果好的時候學習速度變慢。
sigmoid(softmax) + cross-entropy loss 擅長於學習類間的信息,因為它采用了類間競爭機制,它只關心對於正確標簽預測概率的准確性,忽略了其他非正確標簽的差異,導致學習到的特征比較散。基於這個問題的優化有很多,比如對softmax進行改進,如L-Softmax、SM-Softmax、AM-Softmax等。(由於交叉熵涉及到計算每個類別的概率,所以交叉熵幾乎每次都和sigmoid(或softmax)函數一起出現。)
使用交叉熵損失函數,不僅可以很好的衡量模型的效果,又可以很容易的的進行求導計算。
另,sigmoid計算公式為:

\[sigmoid(z) = \frac{{{e^z}}}{{1 + {e^z}}} \]

softmax的計算公式為:

\[{softmax}({z_i}) = \frac{{{e^{{z_i}}}}}{{\sum\nolimits_{i = 1}^K {{e^{{z_i}}}} }} \]

交叉熵作為損失函數還有一個好處是使用sigmoid函數在梯度下降時能避免均方誤差損失函數學習速率降低的問題,因為學習速率可以被輸出的誤差所控制。

torch.nn.CrossEntropyLoss()

多分類,訓練過程中使用。首先,import torch.nn as nn 部分參考:

博客 - pytorch損失函數之nn.CrossEntropyLoss()、nn.NLLLoss()

CrossEntropyLoss帶權重的計算公式為(默認weight=None)(不帶權重的話,公式中不包含外層括號外的weight[class]):

\[loss(x,class) = weight[class]\left( { - x[class] + \log (\sum\limits_i {\exp \left( {x[i]} \right)} )} \right) \]

\[loss(x,class) = - \log \frac{{\exp \left( {x\left[ {class} \right]} \right)}}{{\sum\nolimits_i {\exp \left( {x[i]} \right)} }} \]

用於多分類問題,nn.CrossEntropyLoss()是nn.logSoftmax()和nn.NLLLoss()的整合,可以直接使用它來替換網絡中的這兩個操作。
直接使用pytorch中的loss_func=nn.CrossEntropyLoss()計算得到的結果與softmax-log-NLLLoss計算得到的結果是一致的。

class torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction='mean')   

pytorch源碼

  1. weight (Tensor, optional) – a manual rescaling weight given to each class. If given, has to be a Tensor of size C
  2. size_average (bool, optional) – Deprecated (see reduction). By default, the losses are averaged over each loss element in the batch. Note that for some losses, there are multiple elements per sample. If the field size_average is set to False, the losses are instead summed for each minibatch. Ignored when reduce is False. Default: True
  3. ignore_index (int, optional) – Specifies a target value that is ignored and does not contribute to the input gradient. When size_average is True, the loss is averaged over non-ignored targets.
  4. reduce (bool, optional) – Deprecated (see reduction). By default, the losses are averaged or summed over observations for each minibatch depending on size_average. When reduce is False, returns a loss per batch element instead and ignores size_average. Default: True
  5. reduction (string, optional) – Specifies the reduction to apply to the output: 'none' | 'mean' | 'sum'. 'none': no reduction will be applied, 'mean': the sum of the output will be divided by the number of elements in the output, 'sum': the output will be summed. Note: size_average and reduce are in the process of being deprecated, and in the meantime, specifying either of those two args will override reduction. Default: 'mean'

Focal-Loss

參考

本質上講,Focal Loss 就是一個解決分類問題中類別不平衡、分類難度差異的一個 loss。
這個loss是在交叉熵損失函數基礎上進行的修改。普通的交叉熵對於正樣本而言,輸出概率越大損失越小。對於負樣本而言,輸出概率越小則損失越小。此時的損失函數在大量簡單樣本的迭代過程中比較緩慢且可能無法優化至最優。
修改的方式就是“軟化”這個 CE loss,“軟化”就是把一些本來不可導的函數用一些可導函數來近似,數學角度應該叫“光滑化”。這樣處理之后本來不可導的東西就可導了,類似的算例還有梯度下降和EM算法。Focal loss的計算公示如下(演化自二分類交叉熵loss):

\[{L_{fl}} = \left\{ {\begin{array}{*{20}{c}} { - {{\left( {1 - y'} \right)}^\gamma }\log y',y = 1} \\ { - y{'^\gamma }\log \left( {1 - y'} \right),y = 0} \end{array}} \right.\]

\(y'\)是經過激活函數的輸出,所以在0-1之間。上式原有的基礎上加了一個因子,其中\(\gamma>0\)使得減少易分類樣本的損失。使得更關注於困難的、錯分的樣本。
\(\gamma\)調節簡單樣本權重降低的速率,當\(\gamma\)為0時即為交叉熵損失函數,當\(\gamma\)增加時,調整因子的影響也在增加。實驗發現\(\gamma=2\)時最優。
Focal Loss 在多分類中的形式如下:

\[{L_{fl}} = - {\left( {1 - y{'_t}} \right)^\gamma }\log y{'_t} \]

\(y{'_t}\)是目標的預測值,一般是經過 softmax 后的結果。

Large-Margin-Cosine-Loss

所有基於softmax loss改進的損失都有相同的想法:最大化類間方差和最小化類內方差。

參考

簡稱LMCL,原用在人臉識別任務中,出自Tencent AI Lab在CVPR 2018的論文:CosFace: Large Margin Cosine Loss for Deep Face Recognition

這個損失函數制定通過采用了特征L2歸一化以及權重向量的L2歸一化,去除了特征的徑向差異帶來的影響(這個創新點其實就來自之前的Normface)。引入一個余弦Margin可以在角度空間中增大決策Margin,因此可以實現最小化類內差異,最大化類間差異。
該算法以歸一化的特征為輸入,以最大化類間余弦Margin來學習判別性特征。
定義一個超參數m>0(兩個類別之間有一個明確的邊界空間(margin>0),有更好的魯棒性),定義了一個余弦空間的Margin,決策邊界為:

\[\begin{gathered} {C_1}:\cos \left( {{\theta _1}} \right) \geqslant \cos \left( {{\theta _2}} \right) + m \hfill \\ {C_2}:\cos \left( {{\theta _2}} \right) \geqslant \cos \left( {{\theta _1}} \right) + m \hfill \\ \end{gathered}\]

計算公式:

\[{L_{lmc}} = \frac{1}{N}\sum\limits_i { - \log \frac{{{e^{s\left( {\cos \left( {{\theta_{{y_i}}},i} \right) - m} \right)}}}}{{{e^{s\left( {\cos \left( {{\theta_{{y_i}}},i} \right) - m} \right)}} + \sum\nolimits_{j \ne {y_i}} {{e^{s\cos \left( {{\theta_j},i} \right)}}} }}} \]

subject to:

\[\begin{gathered} W = \frac{{{W^*}}}{{\left\| {{W^*}} \right\|}}, \hfill \\ x = \frac{{{x^*}}}{{\left\| {{x^*}} \right\|}}, \hfill \\ \cos \left( {{\theta _j},i} \right) = W_j^T{x_i} \hfill \\ \end{gathered}\]

其中N為訓練樣本的數目,x_i表示歸一化的第i個特征,W_i表示第i類別的權重向量。s為尺度超參數,一般取值較大;m為margin超參數,取小值。

Contrastive-Loss

對比損失函數,CTR loss.
對比學習最早被應用在圖像領域,通過縮小與正樣本間的相似度/距離,擴大與負樣本間的相似度/距離,使得正樣本與錨點之間的距離遠遠大於負樣本與錨點之間的距離。顯然,對於自然語言處理任務來說,對比損失是序列級別(sequence-level)的。

tips

在PyTorch中使用交叉熵損失函數的時候會自動把label轉化成onehot,所以不用手動轉化,而使用MSE需要手動轉化成onehot編碼。
幾種loss的對比:
avatar


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM