損失函數

損失函數在神經網絡中具有重要作用,它主要用於衡量模型預測結果與真實標簽之間的差異或錯誤程度。它是用來定義和量化訓練目標的一種數學表達方式。

在神經網絡中,損失函數的通用表達式可以表示為以下形式:

[ mathcal{L}(theta) = frac{1}{N} sum_{i=1}^{N} mathcal{L}(y_i, f(x_i;theta)) ]

其中, mathcal{L} 表示損失函數, theta 表示神經網絡的參數, N 表示樣本的數量, y 表示真實標簽, f(x;theta) 表示神經網絡的輸出或預測結果。

該表達式表示瞭對於每個樣本的損失進行求和,並求平均作為整個訓練集的損失。損失函數的選擇取決於具體的任務和問題類型。常見的損失函數包括交叉熵損失(cross-entropy loss)、均方差損失(mean square error loss)、對數損失(log loss)等。

具體選擇哪種損失函數取決於問題的性質和所需的優化目標。例如,在分類問題中,交叉熵損失通常是一個常見的選擇,而在回歸問題中,均方差損失可能更常見。

需要註意的是,損失函數的表達式可以根據具體的網絡架構和任務特點進行定制化。在實際應用中,選擇適合特定問題和模型的損失函數非常重要,因為它直接影響著網絡的訓練效果和性能。

例如,梯度下降是神經網絡中最常用的優化算法之一,它可以應用在神經網絡的損失函數中進行參數的更新和優化。

梯度下降的基本思想是通過計算損失函數關於參數的梯度(導數),然後沿著梯度的反方向更新參數,以使損失函數不斷減小,從而使網絡的預測結果更接近真實標簽。

具體而言,梯度下降包括兩個重要的步驟:

  1. 前向傳播:通過將輸入數據輸入神經網絡,計算網絡的輸出結果。
  2. 反向傳播:計算損失函數關於網絡參數的梯度。反向傳播使用鏈式法則逐層計算梯度,並將梯度從輸出層傳遞到輸入層。

在反向傳播過程中,使用損失函數的梯度信息來更新網絡參數。常見的梯度下降算法包括批量梯度下降(Batch Gradient Descent)、隨機梯度下降(Stochastic Gradient Descent)和小批量梯度下降(Mini-Batch Gradient Descent)等。

通過迭代執行梯度下降算法,不斷更新網絡參數,神經網絡可以逐漸學習到更好的表示和模型,以最小化損失函數並提高性能。

總結起來,梯度下降是神經網絡中常用的優化算法,通過最小化損失函數來更新網絡參數,使網絡逐步優化並逼近最優解。

在參數更新優化的過程中,損失函數起到瞭關鍵的作用。

交叉熵損失

在之後的討論中,我們將涉及到交叉熵損失函數的使用,選擇我們來介紹交叉熵損失。

交叉熵損失(Cross Entropy Loss)是一種常用的損失函數,特別適用於分類問題。它衡量瞭模型輸出的概率分佈與真實標簽之間的差異,用於度量模型預測結果的準確性。

在分類任務中,交叉熵損失基於模型的輸出概率分佈和真實標簽之間的比較,通過最小化交叉熵損失來優化模型參數。其數學定義如下:

對於一個分類問題,假設有 C 個類別 (Cgeq2) ,模型的輸出為一個概率分佈向量(通常使用 Softmax 函數將原始輸出轉化為概率),表示每個類別的預測概率。真實標簽則表示為一個獨熱編碼向量或者類別索引。

交叉熵損失的計算公式如下:

mathcal{L}(x, y) = -sum_{i} y_i log(p_i)

其中:

  • mathcal{L}(x, y) 表示交叉熵損失;
  • x 表示模型的輸出概率分佈向量;
  • y 表示真實標簽(獨熱編碼或類別索引);
  • p 表示模型預測的類別概率分佈。

交叉熵損失通過對模型輸出概率的對數與真實標簽的點積進行累加求和,得到一個表示模型預測準確性的數值。當模型的預測與真實標簽完全一致時,交叉熵損失為最小值(0)。而當模型的預測與真實標簽有較大差異時,交叉熵損失會較大。

通過最小化交叉熵損失,可以使模型更好地擬合訓練數據,提高分類任務的準確性。在反向傳播算法中,交叉熵損失的梯度可以用於更新網絡參數,從而優化模型。

pytorch中的損失函數

PyTorch是一個開源的深度學習框架,由Facebook的人工智能研究團隊開發和維護。它提供瞭豐富的工具和接口,使得構建和訓練神經網絡變得更加簡單和高效。它能在python中被方便的使用。

MSELoss()

使用pytorch庫時可以調用MSELoss來計算輸入張量 x 和目標張量 y 之間的均方誤差(平方 L^2 范數)。

未經減少的(即 reduction 設置為 'none')損失可以描述為:

ell(x, y) = L = {l_1,dots,l_N}^top, quad l_n = left( x_n – y_n right)^2,

其中 N 是批量大小。如果 reduction 非 'none'(默認為 'mean'),則:

ell(x, y) = begin{cases} operatorname{mean}(L), & text{if reduction} = text{`mean';}\ operatorname{sum}(L), & text{if reduction} = text{`sum'.} end{cases}

其中 xy 是任意形狀的張量,每個張量共有 n 個元素。

均值操作仍在所有元素上進行,且除以 n

如果設置 reduction = 'sum',可以避免除以 n

BCELoss()

BCELoss用於測量目標值和輸入概率之間的二元交叉熵。它通常用於評估自編碼器的重構誤差或二元分類任務的錯誤。

未經縮減的損失按元素逐個計算,公式為:

ell(x, y) = L = {l_1,dots,l_N}^top, quad l_n = – w_n left[ y_n cdot log x_n + (1 – y_n) cdot log (1 – x_n) right],

其中, N 是批次大小。如果reduction參數不為'none'(默認為'mean'),則計算方式如下:

ell(x, y) = begin{cases} operatorname{mean}(L), & text{if reduction} = text{`mean';}\ operatorname{sum}(L), & text{if reduction} = text{`sum'.} end{cases}

該損失函數常用於測量自編碼器的重構誤差,需要註意目標值 y 應為介於0和1之間的數。

需要註意的是,如果 x_n01 ,則上述損失公式中的某些對數項在數學上是未定義的。PyTorch選擇將 log(0) 設定為 -∞ ,因為 lim_{xto 0} log (x) = -infty 。然而,在損失公式中存在無窮大的項並不理想,原因如下:

首先,如果 y_n = 0(1 – y_n) = 0 ,我們會將 0 乘以無窮大。其次,如果損失值為無窮大,則梯度也將為無窮大,因為 lim_{xto 0} frac{d}{dx} log (x) = infty 。這將導致BCELoss的反向傳播方法對 x_n 非線性,從而使其在線性回歸等任務中的使用變得困難。

為瞭解決這個問題,BCELoss將其對數函數輸出限制為大於等於-100,以確保總是獲得有限的損失值和線性的反向傳播方法。

CrossEntropyLoss()

這個損失函數計算輸入對數和目標之間的交叉熵損失。

在訓練具有 C 個類別的分類問題時非常有用。如果提供瞭可選的權重參數 weight ,它應該是一個 1D 張量,為每個類別分配權重。這在訓練集不平衡時特別有用。

輸入預期包含每個類別的未歸一化對數(通常情況下不需要是正數或總和為1)。對於未批處理的輸入,輸入的大小應為( C ),對於小批量輸入,大小應為 (minibatch, C) ,對於 K 維情況,大小應為 (minibatch, C, d1, d2, …, dK) ,其中 K≥1 。最後一種情況對於更高維度的輸入很有用,例如計算 2D 圖像的每像素交叉熵損失。

該損失函數預期的目標應包含以下內容之一:

在范圍 [0, C) 內的類別索引,其中 C 是類別的數量;如果指定瞭ignore_index,則該損失函數也接受該類索引(該索引不一定在類范圍內)。對於此情況下的未縮減損失(即reduction設置為'none'),可以描述為:

ell(x, y) = L = {l_1,dots,l_N}^top, quad l_n = – w_{y_n} log frac{exp(x_{n,y_n})}{sum_{c=1}^C exp(x_{n,c})} cdot mathbb{1}{y_n not= text{ignore_index}}

其中, x 是輸入, y 是目標, w 是權重, C 是類別數量, N 跨越小批量維度以及 d₁, …, dₖK 維情況。如果reduction不是'none'(默認為'mean'),則計算方式如下:

ell(x, y) = begin{cases} sum_{n=1}^N frac{1}{sum_{n=1}^N w_{y_n} cdot mathbb{1}{y_n not= text{ignore_index}}} l_n, & text{if reduction} = text{`mean';}\ sum_{n=1}^N l_n, & text{if reduction} = text{`sum'.} end{cases}

註意,此情況相當於LogSoftmax和NLLLoss的組合。

每個類別的概率;當需要每個小批量項的多個類別標簽時(例如混合標簽、標簽平滑等)很有用。對於此情況下的未縮減損失(即reduction設置為'none'),可以描述為:

ell(x, y) = L = {l_1,dots,l_N}^top, quad l_n = – sum_{c=1}^C w_c log frac{exp(x_{n,c})}{sum_{i=1}^C exp(x_{n,i})} y_{n,c}

其中, x 是輸入, y 是目標, w 是權重, C 是類別數量, N 跨越小批量維度以及 d₁, …, dₖK 維情況。如果reduction不是'none'(默認為'mean'),則計算方式如下:

ell(x, y) = begin{cases} frac{sum_{n=1}^N l_n}{N}, & text{if reduction} = text{`mean';}\ sum_{n=1}^N l_n, & text{if reduction} = text{`sum'.} end{cases}

註意,當目標包含類別索引時,此損失函數的性能通常更好,因為這樣可以進行優化計算。如果每個小批量項隻能具有單個類別標簽,可以考慮將目標提供為類別概率。

總結

在之前的實驗中,使用RNN網絡訓練時,由於目標是進行一個類二元分類問題,就使用瞭BCELoss,但是出現瞭無法收斂的現象,而後轉用MSELoss,網絡成功收斂,原因在於所選數據集的目標被設定成瞭0/1,導致BCELoss不能收斂。