一、说明

在本文中,讨论了深度学习中使用的所有常见损失函数,并在NumPy,PyTorch和TensorFlow中实现了它们。

二、内容提要 

我们本文所谈的代价函数如下所列:

  1. 均方误差 (MSE) 损失
  2. 二进制交叉熵损失
  3. 加权二进制交叉熵损失
  4. 分类交叉熵损失
  5. 稀疏分类交叉熵损失
  6. 骰子损失
  7. 吉隆坡背离损失
  8. 平均绝对误差 (MAE) / L1 损耗
  9. 胡贝尔损失

        在下文,我们将逐一演示其不同实现办法。 

三、均方误差 (MSE) 损失

        均方误差 (MSE) 损失是回归问题中常用的损失函数,其目标是预测连续变量。损失计算为预测值和真实值之间的平方差的平均值。MSE 损失的公式为:

MSE loss = (1/n) * sum((y_pred — y_true)²)

        这里:

  • n 是数据集中的样本数
  • 目标变量的预测值y_pred
  • y_true是目标变量的真实值

        MSE损失对异常值很敏感,并且会严重惩罚大误差,这在某些情况下可能是不可取的。在这种情况下,可以使用其他损失函数,如平均绝对误差(MAE)或Huber损失。

        在 NumPy 中的实现

import numpy as np

def 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 values
    
    Returns:
    - mse_loss: mean squared error loss
    """
    n = len(y_true)
    mse_loss = np.sum((y_pred - y_true) ** 2) / n
    return mse_loss

        在此实现中,和 是分别包含预测值和真值的 NumPy 数组。该函数首先计算 和 之间的平方差,然后取这些值的平均值来获得 MSE 损失。该变量表示数据集中的样本数,用于规范化损失。y_predy_truey_predy_truen

TensorFlow 中的实现

import tensorflow as tf

def 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 values
    
    Returns:
    - mse_loss: mean squared error loss
    """
    mse = tf.keras.losses.MeanSquaredError()
    mse_loss = mse(y_true, y_pred)
    return mse_loss

在此实现中,和是分别包含预测值和真值的 TensorFlow 张量。该函数计算 和 之间的 MSE 损耗。该变量包含计算出的损失。y_predy_truetf.keras.losses.MeanSquaredError()y_predy_truemse_loss

在 PyTorch 中的实现

import torch

def 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 values
    
    Returns:
    - mse_loss: mean squared error loss
    """
    mse = torch.nn.MSELoss()
    mse_loss = mse(y_pred, y_true)
    return mse_loss

在此实现中,和 是分别包含预测值和真值的 PyTorch 张量。该函数计算 和 之间的 MSE 损耗。该变量包含计算出的损失。y_predy_truetorch.nn.MSELoss()y_predy_truemse_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)))

        其中 是单热编码格式的真实标签矩阵,是每个类的预测概率矩阵,是样本数,表示自然对数。YY_hatNlog

        在此公式中,形状为 ,其中是样本数,是类数。每行 表示单个样本的真实标签分布,列中的值 1 对应于真实标签,0 对应于所有其他列。Y(N, C)NCY

        类似地,具有 的形状,其中每行表示单个样本的预测概率分布,每个类都有一个概率值。Y_hat(N, C)

        该函数逐个应用于预测的概率矩阵。该函数使用两次来求和矩阵的两个维度。logY_hatsumY

        结果值表示数据集中所有样本的平均交叉熵损失。训练神经网络的目标是最小化这种损失函数。LN

        损失函数对模型的惩罚更大,因为在预测低概率的类时犯了大错误。目标是最小化损失函数,这意味着使预测概率尽可能接近真实标签。

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_truey_predprintnp.sumY

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_truey_predCategoricalCrossentropy.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_truey_logitsCrossEntropyLoss.item()

        请注意,该类将 softmax 激活函数和分类交叉熵损失组合到一个操作中,因此您无需单独应用 softmax。另请注意,真正的标签应采用整数格式,而不是独热编码格式。CrossEntropyLoss

08-13 00:15