一、說明
在本文中,討論了深度學習中使用的所有常見損失函數,并在NumPy,PyTorch和TensorFlow中實現了它們。
二、內容提要?
我們本文所談的代價函數如下所列:
- 均方誤差 (MSE) 損失
- 二進制交叉熵損失
- 加權二進制交叉熵損失
- 分類交叉熵損失
- 稀疏分類交叉熵損失
- 骰子損失
- 吉隆坡背離損失
- 平均絕對誤差 (MAE) / L1 損耗
- 胡貝爾損失
????????在下文,我們將逐一演示其不同實現辦法。?
三、均方誤差 (MSE) 損失
????????均方誤差 (MSE) 損失是回歸問題中常用的損失函數,其目標是預測連續變量。損失計算為預測值和真實值之間的平方差的平均值。MSE 損失的公式為:
MSE loss = (1/n) * sum((y_pred — y_true)2)
????????這里:
- n 是數據集中的樣本數
- 目標變量的預測值y_pred
- y_true是目標變量的真實值
????????MSE損失對異常值很敏感,并且會嚴重懲罰大誤差,這在某些情況下可能是不可取的。在這種情況下,可以使用其他損失函數,如平均絕對誤差(MAE)或Huber損失。
????????在 NumPy 中的實現
import numpy as npdef mse_loss(y_pred, y_true):"""Calculates the mean squared error (MSE) loss between predicted and true values.Args:- y_pred: predicted values- y_true: true valuesReturns:- mse_loss: mean squared error loss"""n = len(y_true)mse_loss = np.sum((y_pred - y_true) ** 2) / nreturn mse_loss
????????在此實現中,和 是分別包含預測值和真值的 NumPy 數組。該函數首先計算 和 之間的平方差,然后取這些值的平均值來獲得 MSE 損失。該變量表示數據集中的樣本數,用于規范化損失。y_pred
y_true
y_pred
y_true
n
TensorFlow 中的實現
import tensorflow as tfdef mse_loss(y_pred, y_true):"""Calculates the mean squared error (MSE) loss between predicted and true values.Args:- y_pred: predicted values- y_true: true valuesReturns:- mse_loss: mean squared error loss"""mse = tf.keras.losses.MeanSquaredError()mse_loss = mse(y_true, y_pred)return mse_loss
在此實現中,和是分別包含預測值和真值的 TensorFlow 張量。該函數計算 和 之間的 MSE 損耗。該變量包含計算出的損失。y_pred
y_true
tf.keras.losses.MeanSquaredError()
y_pred
y_true
mse_loss
在 PyTorch 中的實現
import torchdef mse_loss(y_pred, y_true):"""Calculates the mean squared error (MSE) loss between predicted and true values.Args:- y_pred: predicted values- y_true: true valuesReturns:- mse_loss: mean squared error loss"""mse = torch.nn.MSELoss()mse_loss = mse(y_pred, y_true)return mse_loss
在此實現中,和 是分別包含預測值和真值的 PyTorch 張量。該函數計算 和 之間的 MSE 損耗。該變量包含計算出的損失。y_pred
y_true
torch.nn.MSELoss()
y_pred
y_true
mse_loss
四、二進制交叉熵損失
????????二進制交叉熵損失,也稱為對數損失,是二元分類問題中使用的常見損失函數。它測量預測概率分布與實際二進制標簽分布之間的差異。
????????二進制交叉熵損失的公式如下:
????????L(y, ?) = -[y * log(?) + (1 — y) * log(1 — ?)]
????????其中 y 是真正的二進制標簽(0 或 1),? 是預測概率(范圍從 0 到 1),log 是自然對數。
????????等式的第一項計算真實標簽為 1 時的損失,第二項計算真實標簽為 0 時的損失。總損失是兩個項的總和。
????????當預測概率接近真實標簽時,損失較低,當預測概率遠離真實標簽時,損失較高。此損失函數通常用于在輸出層中使用 sigmoid 激活函數來預測二進制標簽的神經網絡模型。
4.1 在 NumPy 中的實現
????????在numpy中,二進制交叉熵損失可以使用我們前面描述的公式來實現。下面是如何計算它的示例:
# define true labels and predicted probabilities
y_true = np.array([0, 1, 1, 0])
y_pred = np.array([0.1, 0.9, 0.8, 0.3])# calculate the binary cross-entropy loss
loss = -(y_true * np.log(y_pred) + (1 - y_true) * np.log(1 - y_pred)).mean()# print the loss
print(loss)
4.2 TensorFlow 中的實現
????????在 TensorFlow 中,二進制交叉熵損失可以使用 tf.keras.loss.BinaryCrossentropy() 函數實現。下面是如何使用它的示例:
import tensorflow as tf# define true labels and predicted probabilities
y_true = tf.constant([0, 1, 1, 0])
y_pred = tf.constant([0.1, 0.9, 0.8, 0.3])# define the loss function
bce_loss = tf.keras.losses.BinaryCrossentropy()# calculate the loss
loss = bce_loss(y_true, y_pred)# print the loss
print(loss)
4.3 在 PyTorch 中的實現
????????在 PyTorch 中,二進制交叉熵損失可以使用該函數實現。下面是如何使用它的示例:torch.nn.BCELoss()
import torch# define true labels and predicted probabilities
y_true = torch.tensor([0, 1, 1, 0], dtype=torch.float32)
y_pred = torch.tensor([0.1, 0.9, 0.8, 0.3], dtype=torch.float32)# define the loss function
bce_loss = torch.nn.BCELoss()# calculate the loss
loss = bce_loss(y_pred, y_true)# print the loss
print(loss)
4.4 加權二進制交叉熵損失
????????加權二元交叉熵損失是二元交叉熵損失的一種變體,允許為正熵和負示例分配不同的權重。這在處理不平衡的數據集時非常有用,其中一類與另一類相比明顯不足。
????????加權二元交叉熵損失的公式如下:
L(y, ?) = -[w_pos * y * log(?) + w_neg * (1 — y) * log(1 — ?)]
????????其中 y 是真正的二進制標簽(0 或 1),? 是預測概率(范圍從 0 到 1),log 是自然對數,w_pos 和 w_neg 分別是正權重和負權重。
????????等式的第一項計算真實標簽為 1 時的損失,第二項計算真實標簽為 0 時的損失。總損失是兩個項的總和,每個項按相應的權重加權。
????????可以根據每個類的相對重要性選擇正權重和負權重。例如,如果正類更重要,則可以為其分配更高的權重。同樣,如果負類更重要,則可以為其分配更高的權重。
????????當預測概率接近真實標簽時,損失較低,當預測概率遠離真實標簽時,損失較高。此損失函數通常用于在輸出層中使用 sigmoid 激活函數來預測二進制標簽的神經網絡模型。
五、分類交叉熵損失
????????分類交叉熵損失是多類分類問題中使用的一種常用損失函數。它衡量每個類的真實標簽和預測概率之間的差異。
????????分類交叉熵損失的公式為:
L = -1/N * sum(sum(Y * log(Y_hat)))
????????其中 是單熱編碼格式的真實標簽矩陣,是每個類的預測概率矩陣,是樣本數,表示自然對數。Y
Y_hat
N
log
????????在此公式中,形狀為 ,其中是樣本數,是類數。每行 表示單個樣本的真實標簽分布,列中的值 1 對應于真實標簽,0 對應于所有其他列。Y
(N, C)
N
C
Y
????????類似地,具有 的形狀,其中每行表示單個樣本的預測概率分布,每個類都有一個概率值。Y_hat
(N, C)
????????該函數逐個應用于預測的概率矩陣。該函數使用兩次來求和矩陣的兩個維度。log
Y_hat
sum
Y
????????結果值表示數據集中所有樣本的平均交叉熵損失。訓練神經網絡的目標是最小化這種損失函數。L
N
????????損失函數對模型的懲罰更大,因為在預測低概率的類時犯了大錯誤。目標是最小化損失函數,這意味著使預測概率盡可能接近真實標簽。
5.1 在 NumPy 中的實現
????????在numpy中,分類交叉熵損失可以使用我們前面描述的公式來實現。下面是如何計算它的示例:
import numpy as np# define true labels and predicted probabilities as NumPy arrays
y_true = np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]])
y_pred = np.array([[0.8, 0.1, 0.1], [0.2, 0.3, 0.5], [0.1, 0.6, 0.3]])# calculate the loss
loss = -1/len(y_true) * np.sum(np.sum(y_true * np.log(y_pred)))# print the loss
print(loss)In this example, y_true represents the true labels (in integer format), and y_pred represents the predicted probabilities for each class (in a 2D array). The eye() function is used to convert the true labels to one-hot encoding, which is required for the loss calculation. The categorical cross-entropy loss is calculated using the formula we provided earlier, and the mean() function is used to average the loss over the entire dataset. Finally, the calculated loss is printed to the console.
????????在此示例中, 以獨熱編碼格式表示真實標簽,并表示每個類的預測概率,兩者都為 NumPy 數組。使用上述公式計算損失,然后使用該函數打印到控制臺。請注意,該函數使用兩次來對矩陣的兩個維度求和。y_true
y_pred
print
np.sum
Y
5.2 TensorFlow 中的實現
????????在TensorFlow中,分類交叉熵損失可以使用該類輕松計算。下面是如何使用它的示例:tf.keras.losses.CategoricalCrossentropy
import tensorflow as tf# define true labels and predicted probabilities as TensorFlow Tensors
y_true = tf.constant([[0, 1, 0], [0, 0, 1], [1, 0, 0]])
y_pred = tf.constant([[0.8, 0.1, 0.1], [0.2, 0.3, 0.5], [0.1, 0.6, 0.3]])# create the loss object
cce_loss = tf.keras.losses.CategoricalCrossentropy()# calculate the loss
loss = cce_loss(y_true, y_pred)# print the loss
print(loss.numpy())
????????在此示例中,以獨熱編碼格式表示真實標簽,并表示每個類的預測概率,兩者都作為 TensorFlow 張量。該類用于創建損失函數的實例,然后通過將真實標簽和預測概率作為參數傳遞來計算損失。最后,使用該方法將計算出的損失打印到控制臺。y_true
y_pred
CategoricalCrossentropy
.numpy()
請注意,該類在內部處理將真實標簽轉換為獨熱編碼,因此無需顯式執行此操作。如果你的真實標簽已經是獨熱編碼格式,你可以將它們直接傳遞給損失函數,沒有任何問題。CategoricalCrossentropy
5.3 在 PyTorch 中的實現
????????在 PyTorch 中,分類交叉熵損失可以使用該類輕松計算。下面是如何使用它的示例:torch.nn.CrossEntropyLoss
import torch# define true labels and predicted logits as PyTorch Tensors
y_true = torch.LongTensor([1, 2, 0])
y_logits = torch.Tensor([[0.8, 0.1, 0.1], [0.2, 0.3, 0.5], [0.1, 0.6, 0.3]])# create the loss object
ce_loss = torch.nn.CrossEntropyLoss()# calculate the loss
loss = ce_loss(y_logits, y_true)# print the loss
print(loss.item())
????????在此示例中, 以整數格式表示真實標簽,并表示每個類的預測對數,兩者都作為 PyTorch 張量。該類用于創建損失函數的實例,然后通過將預測的對數和 true 標簽作為參數傳遞來計算損失。最后,使用該方法將計算出的損失打印到控制臺。y_true
y_logits
CrossEntropyLoss
.item()
????????請注意,該類將 softmax 激活函數和分類交叉熵損失組合到一個操作中,因此您無需單獨應用 softmax。另請注意,真正的標簽應采用整數格式,而不是獨熱編碼格式。CrossEntropyLoss