【損失函數】損失函數專題


損失函數專題

范數

L0范數

L0范數是指向量中非0的元素的個數。如果用L0規則化一個參數矩陣W,就是希望W中大部分元素是零,實現稀疏

L0范數的應用:

  1. 特征選擇:實現特征的自動選擇,去除無用特征。稀疏化可以去掉這些無用特征,將特征對應的權重置為零

  2. 可解釋性(interpretability):例如判斷某種病的患病率時,最初有1000個特征,建模后參數經過稀疏化,最終只有5個特征的參數是非零的,那么就可以說影響患病率的主要就是這5個特征。

L1范數

L1范數是指向量中各個元素絕對值之和。L1范數也可以實現稀疏,通過將無用特征對應的參數W置為零實現。
L1范數:

既然L0可以實現稀疏,為什么不用L0,而要用L1呢?個人理解一是因為L0范數很難優化求解(NP難問題),二是L1范數是L0范數的最優凸近似,而且它比L0范數要容易優化求解。

L2范數

L2范數是指向量各元素的平方和然后求平方根。,用在回歸模型中也稱為嶺回歸(Ridge regression)。

L2范數:

[公式]

L2避免過擬合的原理是:讓L2范數的規則項

[公式]

盡可能小,可以使得W每個元素都很小,接近於零,但是與L1不同的是,不會等於0;這樣得到的模型抗干擾能力強,參數很小時,即使樣本數據x發生很大的變化,模型預測值y的變化也會很有限。

L2范數的作用:

  1. 學習理論的角度:從學習理論的角度來說,L2范數可以防止過擬合,提升模型的泛化能力
  2. 優化計算的角度:從優化或者數值計算的角度來說,L2范數有助於處理 condition number不好的情況下矩陣求逆很困難的問題。

損失函數

(一) L1損失

使用L1損失函數也被叫做最小化絕對誤差(Least Abosulote Error)。這 個名稱非常的形象。 LAE 就是最小化真實值yi和預測值 f(xi) 之間差值 DL1的絕對值的和。

[公式]

這里的 DL1其實就是平均絕對誤差(MAE),使用L1 損失函數也就是min DL1

公式:

[公式]

導數:

[公式]

L1 loss 在零點不平滑,學習慢,用的較少。

1.1 平滑版L1損失 SmoothL1Loss

  • 也被稱為 Huber 損失函數。

  • torch.nn.SmoothL1Loss(reduction='mean')
    
  • 公式:

    img

    其中

    img

(二) L2損失

公式:

[公式]

導數:

[公式]

L2 loss:對離群點比較敏感,如果feature 是 unbounded的話,需要好好調整學習率,防止出現梯度爆炸的情況。L2loss學習快,因為是平方增長,但是當預測值太大的時候,會在loss中占據主導位置(如真實值為1,預測多次,有一次預測值為100,其余預測為2)。

  • 一般來說,L1正則會制造稀疏的特征,大部分無用特征的權重會被置為0。

  • L2正則會讓特征的權重不過大,使得特征的權重比較平均。

# L1 loss
def L1_loss(y_true,y_pre):
    return np.sum(np.abs(y_true,y_pre))
# L2 loss
def L2_loss(y_true,y_pre):
    return np.sum(np.square(y_true,y_pre))

#pytorch實現
# L1 loss
# reduction-三個值,none: 不使用約簡;mean:返回loss和的平均值;sum:返回loss的和。默認:mean。
torch.nn.L1Loss(reduction='mean')

(三) 對抗損失

(四) MSE損失

  • 不能與Smogid損失函數聯用。

  • # reduction-三個值,none: 不使用約簡;mean:返回loss和的平均值;sum:返回loss的和。默認:mean。
    torch.nn.MSELoss(reduction='mean')
    

(五) 交叉熵損失

5.1 二進制交叉熵損失 BCELoss

  • 二分類任務時的交叉熵計算函數。用於測量重構的誤差, 例如自動編碼機. 注意目標的值 t[i] 的范圍為0到1之間。

  • # weight (Tensor, optional) – 自定義的每個 batch 元素的 loss 的權重. 必須是一個長度為 “nbatch” 的 的 Tensor
    torch.nn.BCELoss(weight=None, reduction='mean')
    

5.2 BCEWithLogitsLoss

  • BCEWithLogitsLoss損失函數把 Sigmoid 層集成到了 BCELoss 類中. 該版比用一個簡單的 Sigmoid 層和 BCELoss 在數值上更穩定, 因為把這兩個操作合並為一個層之后, 可以利用 log-sum-exp 的 技巧來實現數值穩定。

  • # weight (Tensor, optional) – 自定義的每個 batch 元素的 loss 的權重. 必須是一個長度 為 “nbatch” 的 Tensor
    torch.nn.BCEWithLogitsLoss(weight=None, reduction='mean', pos_weight=None)
    

(六) 感知損失(Perceptual Loss)

感知損失的定義包含以下兩個損失函數(不一定全部都要有)的,一個是feature reconstruction loss L-feat,另一個是style reconstruction loss L-style

6.1)feature reconstruction loss L-feat 特征重建損失


如圖:

現在有兩幅圖xx^,把這兩種圖片輸入到像VGG這樣的預訓練好的卷積網絡中,最后輸出了經過特征提取的 特征圖 ,即feature maps,將這兩對feature maps取一個L2損失,再除以feature maps的維度乘積。

上述的過程,就是feature reconstruction loss L-feat。L-feat是計算 loss network 中每一個特征提取層輸出的L2重建損失。

6.2)style reconstruction loss L-style 風格重建損失

對於L-style, 也要先將原圖輸入到像VGG這樣的預訓練好的卷積網絡,設第j層的特征圖為Cjx Hj x Wj, 則通過構建一個Gram matrix Gj, 得到一個Ci x Cj 的矩陣, 矩陣的元素由下式給出:

這里Gj的數學意義是非中心協方差矩陣。每個矩陣元素為第j個特征圖的cc' 通道上的相關性(針對同一個輸入圖像) . 那么L-style就是要重建目標圖和生成圖在各自特征通道上的相關性

除了以上perceptual 損失外,在《Perceptual Loss for Image Translation and Style Transfer》這篇Paper中,作者還加了整體方差損失L-TV (total variation) 來保證平滑性.最終得到一個baseline的損失

6.3)感知損失特點:

  1. 多應用於風格遷移類的任務中,這是因為預訓練好的圖像分類網絡更加具備編碼感知和語義信息的能力;
  2. 感知損失比每像素損失更可靠地度量圖像相似性;感知損失不同於通常用的L1、L2重建損失在像素級別上監督圖像的轉化, 而是利用特征級別的重建要求來達到這一目的。
  3. 實驗發現, 高層(j的值更大) 的特征重建傾向於保留圖像內容和結構, 而低層(j的值更小) 的特征重建則可保留顏色, 紋理, 細節形狀等。(是否說明卷積層的特性也如此?)

6.4)對Gram matrices的理解

Todo:從數學意義上理解、學習地更深入一點。

Gram matrices即非中心協方差矩陣,它的功能有:

  1. 通過矩陣乘法運算,去除了 Convolution feature 上空間結構信息。
  2. 保留代表全圖的某種共性的語義信息,而這種共性恰好表現為圖像的藝術風格。

(七) 循環一致損失

(八) 整體方差損失 (total variation)

(九) KL 散度損失 KLDivLoss

  • 計算 input 和 target 之間的 KL 散度。KL 散度可用於衡量不同的連續分布之間的距離, 在連續的輸出分布的空間上(離散采樣)上進行直接回歸時 很有效。

  • # eduction-三個值,none: 不使用約簡;mean:返回loss和的平均值;sum:返回loss的和。默認:mean。
    torch.nn.KLDivLoss(reduction='mean')
    

(十) Focal Loss

Focal loss的公式:

\[F L\left(p_{t}\right)=-\left(1-p_{t}\right)^{\gamma} \log \left(p_{t}\right) \]

其中:

\[p_{t}=\left\{\begin{array}{lr} p & \text { if } y=1 \\ 1-p & \text { otherwise } \end{array}\right. \]

合起來就是如下形式:

\[F L=\left\{\begin{array}{rlr} -\alpha(1-p)^{\gamma} \log (p), & \text { if } & y=1 \\ -(1-\alpha) p^{\gamma} \log (1-p), & \text { if } & y=0 \end{array}\right. \]

\({\gamma}\)為常數,當其為0時,FL就和普通的交叉熵損失函數一致了。\({\gamma}\)不同取值,FL曲線如下:

圖片

  • 目的:Focal loss主要是為了解決one-stage目標檢測中正負樣本比例嚴重失衡的問題。該損失函數降低了大量簡單負樣本在訓練中所占的權重,也可理解為一種困難樣本挖掘。

    在原有的基礎上加了一個因子,其中\({\gamma}>0\)使得減少易分類樣本的損失。使得更關注於困難的、錯分的樣本。

    例如\({\gamma}=2\),對於正類樣本而言,預測結果為0.95肯定是簡單樣本,所以(1-0.95)的\({\gamma}\)次方就會很小,這時損失函數值就變得更小。而預測概率為0.3的樣本其損失相對很大。對於負類樣本而言同樣,預測0.1的結果應當遠比預測0.7的樣本損失值要小得多。對於預測概率為0.5時,損失只減少了0.25倍,所以更加關注於這種難以區分的樣本。這樣減少了簡單樣本的影響,大量預測概率很小的樣本疊加起來后的效應才可能比較有效。

實驗表明\({\gamma}=2,\alpha = 0.25\) 時效果最佳。

圖片

這樣以來,訓練過程關注對象的排序為正難>負難>正易>負易。這就是Focal Loss,簡單明了但特別有用。

代碼實現:

# 實現一
def py_sigmoid_focal_loss(pred,
                          target,
                          weight=None,
                          gamma=2.0,
                          alpha=0.25,
                          reduction='mean',
                          avg_factor=None):
    pred_sigmoid = pred.sigmoid()
    target = target.type_as(pred)
    pt = (1 - pred_sigmoid) * target + pred_sigmoid * (1 - target)
    focal_weight = (alpha * target + (1 - alpha) *
                    (1 - target)) * pt.pow(gamma)
    loss = F.binary_cross_entropy_with_logits(
        pred, target, reduction='none') * focal_weight
    loss = weight_reduce_loss(loss, weight, reduction, avg_factor)
    return loss

# 兩個代碼實現的loss是一樣的,注意上下兩個alpha參數。

# 實現二
class FocalLoss(nn.Module):
    def __init__(self, alpha=0.75, gamma=2, logits=False, reduce=True):
        super(FocalLoss, self).__init__()
        self.alpha = alpha
        self.gamma = gamma
        self.logits = logits
        self.reduce = reduce

    def forward(self, inputs, targets):
        if self.logits:
            BCE_loss = F.binary_cross_entropy_with_logits(inputs, targets, reduce=False)
        else:
            BCE_loss = F.binary_cross_entropy(inputs, targets, reduce=False)
        pt = torch.exp(-BCE_loss)
        F_loss = self.alpha * (1-pt)**self.gamma * BCE_loss

        if self.reduce:
            return torch.mean(F_loss)
        else:
            return F_loss

其中focal_weight代表的是如下公式:

\[\text { FocalWeight }=\left\{\begin{array}{lll} \alpha(1-p)^{\gamma}, & \text { if } & \text { target }=1 \\ (1-\alpha) p^{\gamma}, & \text { if } & \text { target }=0 \end{array}\right. \]

激活函數

Sigmoid函數

sigmoid常用於二元分類,將二元輸入映射成0和1。

函數:

[公式]

導數:

[公式]

sigmoid函數推導:

[公式]

其實logistic函數也就是經常說的sigmoid函數,它的幾何形狀也就是一條sigmoid曲線(S型曲線)。sigmoid函數把一個值映射到0-1之間。

該函數具有如下的特性:當x趨近於負無窮時,y趨近於0;當x趨近於正無窮時,y趨近於1;當x= 0時,y=0.5.

優點:

  1. Sigmoid函數的輸出映射在(0,1)之間,單調連續,輸出范圍有限,優化穩定,可以用作輸出層。

  2. 求導容易,處處可導,導數為:f′(x)=f(x)(1−f(x))

缺點:

  1. 由於其軟飽和性,容易產生梯度消失,導致訓練出現問題。
  2. 其輸出並不是以0為中心的。
  3. 當激活函數使用Sigmoid時,損失函數不建議使用均方誤差,而用交叉熵損失函數代替。Sigmoid()函數和均方誤差聯用可能會導致梯度消失的問題。

BN理解

Batch Normalization批標准化

機器學習領域有個很重要的假設:IID獨立同分布假設,就是假設訓練數據和測試數據是滿足相同分布的,這是通過訓練數據獲得的模型能夠在測試集獲得好的效果的一個基本保障。那BatchNorm的作用是什么呢?BatchNorm就是在深度神經網絡訓練過程中使得每一層神經網絡的輸入保持相同分布的。

BN的基本思想其實相當直觀:因為深層神經網絡在做非線性變換前的激活輸入值(就是那個x=WU+B,U是輸入)隨着網絡深度加深或者在訓練過程中,其分布逐漸發生偏移或者變動,之所以訓練收斂慢,一般是整體分布逐漸往非線性函數的取值區間的上下限兩端靠近(對於Sigmoid函數來說,意味着激活輸入值WU+B是大的負值或正值),所以這導致反向傳播時低層神經網絡的梯度消失,這是訓練深層神經網絡收斂越來越慢的本質原因而BN就是通過一定的規范化手段,把每層神經網絡任意神經元這個輸入值的分布強行拉回到均值為0方差為1的標准正態分布,其實就是把越來越偏的分布強制拉回比較標准的分布,這樣使得激活輸入值落在非線性函數對輸入比較敏感的區域,這樣輸入的小變化就會導致損失函數較大的變化,意思是這樣讓梯度變大,避免梯度消失問題產生,而且梯度變大意味着學習收斂速度快,能大大加快訓練速度。

具體實現:

BN在訓練的時候可以根據Mini-Batch里的若干訓練實例進行激活數值調整,但是在推理(inference)的過程中,從所有訓練實例中獲得的統計量來代替Mini-Batch里面m個訓練實例獲得的均值和方差統計量。

BatchNorm為什么NB呢?關鍵還是效果好。經過簡單的變換,帶來的好處多得很,這也是為何現在BN這么快流行起來的原因。

優點:

1. 不僅僅極大提升了訓練速度,收斂過程大大加快;

2. 還能增加分類效果,一種解釋是這是類似於Dropout的一種防止過擬合的正則化表達方式,所以不用Dropout也能達到相當的效果;

3. 另外調參過程也簡單多了,對於初始化要求沒那么高,而且可以使用大的學習率等。

缺點:

  • 優點說了一大堆,但很多大佬在實際訓練時一般不考慮使用BN,他們說實際效果並沒有多大的提升。


免責聲明!

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



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