?一、說明
在本文中,討論了深度學習中使用的所有常見損失函數,并在NumPy,PyTorch和TensorFlow中實現了它們。
(二-五)見
六、稀疏分類交叉熵損失
????????稀疏分類交叉熵損失類似于分類交叉熵損失,但在真實標簽作為整數而不是獨熱編碼提供時使用。它通常用作多類分類問題中的損失函數。
稀疏分類交叉熵損失的公式為:
L = -1/N * sum(log(Y_hat_i))
????????其中 是每個樣本的真實類標簽的預測概率,是樣本數。Y_hat_i
i
N
????????換句話說,該公式計算每個樣本的真實類標簽的預測概率的負對數,然后對所有樣本的這些值求平均值。
????????與對真實標簽使用獨熱編碼的分類交叉熵損失不同,稀疏分類交叉熵損失直接使用整數標簽。每個樣本的真實標簽表示為 0 到 之間的單個整數值,其中 是類的數量。i
C-1
C
6.1 在 NumPy 中的實現
import numpy as npdef sparse_categorical_crossentropy(y_true, y_pred):# convert true labels to one-hot encodingy_true_onehot = np.zeros_like(y_pred)y_true_onehot[np.arange(len(y_true)), y_true] = 1# calculate lossloss = -np.mean(np.sum(y_true_onehot * np.log(y_pred), axis=-1))return loss
????????在此實現中, 是整數標簽數組,是每個樣本的預測概率數組。該函數首先使用 NumPy 的高級索引功能將真實標簽轉換為獨熱編碼格式,以創建一個形狀數組,其中是樣本數和類數,每行對應于單個樣本的真實標簽分布。y_true
y_pred
(N, C)
N
C
然后,該函數使用上一個答案中描述的公式計算損失:。這是使用 NumPy 的廣播實現的,其中創建一個形狀數組,其中每個元素表示 和 中相應元素的乘積。然后,該函數用于對維度求和,并用于對維度求平均值。-1/N * sum(log(Y_hat_i))
y_true_onehot * np.log(y_pred)
(N, C)
y_true_onehot
np.log(y_pred)
sum
C
mean
N
下面是如何使用該函數的示例:
# define true labels as integers and predicted probabilities as an array
y_true = np.array([1, 2, 0])
y_pred = np.array([[0.1, 0.8, 0.1], [0.3, 0.2, 0.5], [0.4, 0.3, 0.3]])# calculate the loss
loss = sparse_categorical_crossentropy(y_true, y_pred)# print the loss
print(loss)
????????這將輸出給定輸入的稀疏分類交叉熵損失的值。
6.2 TensorFlow 中的實現
import tensorflow as tfdef sparse_categorical_crossentropy(y_true, y_pred):loss = tf.keras.losses.sparse_categorical_crossentropy(y_true, y_pred, from_logits=False)return loss# define true labels as integers and predicted probabilities as a tensor
y_true = tf.constant([1, 2, 0])
y_pred = tf.constant([[0.1, 0.8, 0.1], [0.3, 0.2, 0.5], [0.4, 0.3, 0.3]])# calculate the loss
loss = sparse_categorical_crossentropy(y_true, y_pred)# print the loss
print(loss.numpy())
在此實現中, 是整數標簽數組,是每個樣本的預測概率數組。該函數使用 TensorFlow 提供的函數來計算損失。設置該參數以確保 表示概率而不是對數值。y_true
y_pred
tf.keras.losses.sparse_categorical_crossentropy
from_logits
False
y_pred
6.3 在 PyTorch 中的實現
import torch.nn.functional as F
import torchdef sparse_categorical_crossentropy(y_true, y_pred):loss = F.cross_entropy(y_pred, y_true)return loss# define true labels as integers and predicted logits as a tensor
y_true = torch.tensor([1, 2, 0])
y_pred = torch.tensor([[0.1, 0.8, 0.1], [0.3, 0.2, 0.5], [0.4, 0.3, 0.3]])# calculate the loss
loss = sparse_categorical_crossentropy(y_true, y_pred)# print the loss
print(loss.item())
????????在此實現中, 是一個整數標簽數組,并且是每個樣本的預測對數數組。該函數使用 PyTorch 的函數來計算損失。張量應該具有形狀,其中是樣本的數量,是類的數量。y_true
y_pred
F.cross_entropy
y_pred
(N, C)
N
C
七、骰子損失
????????骰子損失,也稱為索倫森-骰子系數或 F1 分數,是圖像分割任務中使用的損失函數,用于測量預測分割與地面實況之間的重疊。骰子損失范圍從 0 到 1,其中 0 表示沒有重疊,1 表示完全重疊。
骰子損失定義為:
Dice Loss = 1 - (2 * intersection + smooth) / (sum of squares of prediction + sum of squares of ground truth + smooth)
????????其中 是預測和地面真實掩碼的元素乘積,是一個平滑常數(通常是一個較小的值,例如 1e-5),以防止除以零,并且總和將覆蓋掩碼的所有元素。intersection
smooth
????????骰子損失可以在各種深度學習框架中實現,如TensorFlow,PyTorch和NumPy。該實現涉及使用框架中可用的逐元素乘積和求和運算計算交集和平方和。
7.1 在 NumPy 中的實現
import numpy as npdef dice_loss(y_true, y_pred, smooth=1e-5):intersection = np.sum(y_true * y_pred, axis=(1,2,3))sum_of_squares_pred = np.sum(np.square(y_pred), axis=(1,2,3))sum_of_squares_true = np.sum(np.square(y_true), axis=(1,2,3))dice = 1 - (2 * intersection + smooth) / (sum_of_squares_pred + sum_of_squares_true + smooth)return dice
????????在此實現中,分別是基本事實和預測掩碼。該參數用于防止被零除。和函數分別用于計算交集和平方和。最后,使用上一個答案中描述的公式計算骰子損失。y_true
y_pred
smooth
sum
square
????????請注意,此實現假定 和 是具有維度的 4D 數組。如果您的掩碼具有不同的形狀,則可能需要相應地修改實現。y_true
y_pred
(batch_size, height, width, num_classes)
7.2 TensorFlow 中的實現
import tensorflow as tfdef dice_loss(y_true, y_pred, smooth=1e-5):intersection = tf.reduce_sum(y_true * y_pred, axis=(1,2,3))sum_of_squares_pred = tf.reduce_sum(tf.square(y_pred), axis=(1,2,3))sum_of_squares_true = tf.reduce_sum(tf.square(y_true), axis=(1,2,3))dice = 1 - (2 * intersection + smooth) / (sum_of_squares_pred + sum_of_squares_true + smooth)return dice
????????在此實現中,和 是 TensorFlow 張量分別表示地面真相和預測掩碼。該參數用于防止被零除。和函數分別用于計算交集和平方和。最后,使用上一個答案中描述的公式計算骰子損失。y_true
y_pred
smooth
reduce_sum
square
請注意,此實現假定 和 是具有維度的 4D 張量。如果您的掩碼具有不同的形狀,則可能需要相應地修改實現。y_true
y_pred
(batch_size, height, width, num_classes)
7.3 在 PyTorch 中的實現
import torchdef dice_loss(y_true, y_pred, smooth=1e-5):intersection = torch.sum(y_true * y_pred, dim=(1,2,3))sum_of_squares_pred = torch.sum(torch.square(y_pred), dim=(1,2,3))sum_of_squares_true = torch.sum(torch.square(y_true), dim=(1,2,3))dice = 1 - (2 * intersection + smooth) / (sum_of_squares_pred + sum_of_squares_true + smooth)return dice
????????在此實現中,和 是 PyTorch 張量分別表示基本事實和預測掩碼。該參數用于防止被零除。和函數分別用于計算交集和平方和。最后,使用上一個答案中描述的公式計算骰子損失。y_true
y_pred
smooth
sum
square
請注意,此實現假定 和 是具有維度的 4D 張量。如果您的掩碼具有不同的形狀,則可能需要相應地修改實現。y_true
y_pred
(batch_size, num_classes, height, width)
八、KL散度損失
????????KL(Kullback-Leibler)散度損失是兩個概率分布彼此差異程度的度量。在機器學習的上下文中,它通常用作損失函數來訓練從給定分布生成新樣本的模型。
????????兩個概率分布 p 和 q 之間的 KL 散度定義為:
????????KL(p||q) = sum(p(x) * log(p(x) / q(x)))
????????在機器學習的上下文中,p 表示真實分布,q 表示預測分布。KL 散度損失衡量預測分布與真實分布的匹配程度。
????????KL 散度損失可用于各種任務,例如圖像生成、文本生成和強化學習。但是,由于它具有非凸形式,因此可能很難優化。
????????在實踐中,KL散度損失通常與其他損失函數(如交叉熵損失)結合使用。通過將KL散度損失添加到交叉熵損失中,鼓勵模型生成不僅與目標分布匹配,而且與訓練數據具有相似分布的樣本。
8.1 在 NumPy 中的實現
import numpy as npdef kl_divergence_loss(p, q):return np.sum(p * np.log(p / q))
在此實現中,和 是分別表示真實分布和預測分布的 numpy 數組。KL 背離損失使用上述公式計算。p
q
請注意,此實現假定并具有相同的形狀。如果它們具有不同的形狀,則可能需要相應地修改實現。p
q
8.2 TensorFlow 中的實現
???tf.keras.losses.KLDivergence()
是 TensorFlow 中的一個內置函數,用于計算兩個概率分布之間的 KL 背離損失。它可以用作各種機器學習任務中的損失函數,例如圖像生成、文本生成和強化學習。
????????下面是一個用法示例:tf.keras.losses.KLDivergence()
import tensorflow as tf# define true distribution and predicted distribution
p = tf.constant([0.2, 0.3, 0.5])
q = tf.constant([0.4, 0.3, 0.3])# compute KL divergence loss
kl_loss = tf.keras.losses.KLDivergence()(p, q)print(kl_loss.numpy())
????????在此示例中,和 是 TensorFlow 張量分別表示真實分布和預測分布。該函數用于計算 和 之間的 KL 散度損失。結果是一個表示損失值的標量張量。p
q
tf.keras.losses.KLDivergence()
p
q
????????請注意,通過將 和 具有不同形狀的情況廣播到通用形狀,自動處理這些情況。此外,您還可以通過設置函數的參數來調整 KL 散度損失相對于模型中其他損失的權重,該參數控制損失的聚合方式。tf.keras.losses.KLDivergence()
p
q
reduction
8.3 在 PyTorch 中的實現
????????在 PyTorch 中,KL 散度損失可以使用模塊計算。下面是一個示例實現:torch.nn.KLDivLoss
import torchdef kl_divergence_loss(p, q):criterion = torch.nn.KLDivLoss(reduction='batchmean')loss = criterion(torch.log(p), q)return lossIn this implementation, p and q are PyTorch tensors representing the true distribution and predicted distribution, respectively. The torch.nn.KLDivLoss module is used to compute the KL divergence loss between p and q. The reduction parameter is set to 'batchmean' to compute the mean loss over the batch.
????????請注意,和 應該是概率,沿最后一個維度的總和為 1。該函數用于在將 的對數傳遞給模塊之前獲取對數。這是因為模塊期望輸入是對數概率。p
q
torch.log
p
torch.nn.KLDivLoss
九、平均絕對誤差 (MAE) 損耗 / L1 損耗
????????L1 損失,也稱為平均絕對誤差 (MAE) 損失,是深度學習中用于回歸任務的常見損失函數。它測量目標變量的預測值和真實值之間的絕對差異。
????????L1損失的公式為:
????????L1 LOSS = 1/n * Σ|y_pred — y_true|
????????其中 n 是樣本數,y_pred 是預測值,y_true 是真實值。
????????簡單來說,L1 損失是預測值和真實值之間絕對差值的平均值。它對異常值的敏感度低于均方誤差 (MSE) 損失,因此對于可能受異常值影響的模型來說,它是一個不錯的選擇。
9.1 在 Numpy 中的實現
import numpy as npdef l1_loss(y_pred, y_true):loss = np.mean(np.abs(y_pred - y_true))return loss
L1 損失的 NumPy 實現與公式非常相似,其中您從真實值中減去預測值并取絕對值。然后,取所有樣本中這些絕對差異的平均值,以獲得平均 L1 損失。
9.2 TensorFlow 中的實現
import tensorflow as tfdef l1_loss(y_pred, y_true):loss = tf.reduce_mean(tf.abs(y_pred - y_true))return loss
在 TensorFlow 中,您可以使用該函數計算所有樣本中預測值和真實值之間的絕對差值的平均值。tf.reduce_mean()
9.3 在 PyTorch 中的實現
import torchdef l1_loss(y_pred, y_true):loss = torch.mean(torch.abs(y_pred - y_true))return loss
在 PyTorch 中,您可以使用該函數計算所有樣本中預測值和真實值之間的絕對差值的平均值。torch.mean()
十、Huber 胡貝爾損失
????????Huber 損失是回歸任務中使用的損失函數,它對異常值的敏感度低于均方誤差 (MSE) 損失。它被定義為MSE損失和平均絕對誤差(MAE)損失的組合,其中損失函數是MSE表示小誤差,MAE表示較大誤差。這使得Huber損失比MSE損失對異常值更穩健。
????????Huber 損失函數定義如下:
L(y_pred, y_true) = 1/n * sum(0.5 * (y_pred - y_true)^2) if |y_pred - y_true| <= delta1/n * sum(delta * |y_pred - y_true| - 0.5 * delta^2) otherwise
????????其中 是樣本數,是預測值,是真實值,并且是確定在 MSE 和 MAE 損失之間切換的閾值的超參數。n
y_pred
y_true
delta
????????當 ,損失函數是 MSE 損失。當 時,損失函數是斜率為 的 MAE 損失。|y_pred - y_true| <= delta
|y_pred - y_true| > delta
delta
????????在實踐中,通常設置為平衡 MSE 和 MAE 損耗的值,例如 。delta
1.0
10.1 在 Numpy 中的實現
import numpy as npdef huber_loss(y_pred, y_true, delta=1.0):error = y_pred - y_trueabs_error = np.abs(error)quadratic = np.minimum(abs_error, delta)linear = (abs_error - quadratic)return np.mean(0.5 * quadratic ** 2 + delta * linear)
????????此函數將預測值、真值和超參數作為輸入,并返回 Huber 損失。y_pred
y_true
delta
????????該函數首先計算預測值和真值之間的絕對誤差,然后根據超參數將誤差拆分為兩個分量。二次分量是 時的 MSE 損耗,線性分量是 時的 MAE 損耗。最后,該函數返回所有樣本的平均Huber損失。delta
abs_error <= delta
abs_error > delta
????????您可以在基于 numpy 的回歸任務中使用此函數,方法是使用預測值和真實值以及所需值調用它。delta
10.2 TensorFlow 中的實現
import tensorflow as tfdef huber_loss(y_pred, y_true, delta=1.0):error = y_pred - y_trueabs_error = tf.abs(error)quadratic = tf.minimum(abs_error, delta)linear = (abs_error - quadratic)return tf.reduce_mean(0.5 * quadratic ** 2 + delta * linear)
此函數將預測值、真值和超參數作為輸入,并返回 Huber 損失。y_pred
y_true
delta
該函數首先使用該函數計算預測值和真值之間的絕對誤差,然后使用 and 運算符根據超參數將誤差拆分為兩個分量。二次分量是 時的 MSE 損耗,線性分量是 時的 MAE 損耗。最后,該函數使用該函數返回所有樣本的平均Huber損失。tf.abs
delta
tf.minimum
-
abs_error <= delta
abs_error > delta
tf.reduce_mean
您可以在基于 TensorFlow 的回歸任務中使用此函數,方法是使用預測值和真實值以及所需值調用它。delta
10.3 在 PyTorch 中的實現
import torch.nn.functional as Fdef huber_loss(y_pred, y_true, delta=1.0):error = y_pred - y_trueabs_error = torch.abs(error)quadratic = torch.min(abs_error, delta)linear = (abs_error - quadratic)return 0.5 * quadratic ** 2 + delta * linear
????????此函數將預測值、真值和超參數作為輸入,并返回 Huber 損失。y_pred
y_true
delta
????????該函數首先使用該函數計算預測值和真值之間的絕對誤差,然后使用 and 運算符根據超參數將誤差拆分為兩個分量。二次分量是 時的 MSE 損耗,線性分量是 時的 MAE 損耗。最后,該函數使用公式返回 Huber 損失。torch.abs
delta
torch.min
-
abs_error <= delta
abs_error > delta
0.5 * quadratic ** 2 + delta * linear
????????您可以在基于 PyTorch 的回歸任務中使用此函數,方法是使用預測值和真實值以及所需值調用它。delta