国精产品一品二品国精品69xx怎么利用自媒体做网站优化
2026/2/14 22:44:46 网站建设 项目流程
国精产品一品二品国精品69xx,怎么利用自媒体做网站优化,广告推广营销网站,佛山做网络优化的公司损失函数详解#xff1a;原理、分类与代码实现在机器学习与深度学习领域#xff0c;损失函数是连接模型预测与真实标签的核心桥梁#xff0c;它量化了模型预测结果与实际值之间的偏差#xff0c;是模型训练过程中参数更新的“导航仪”。无论是简单的线性回归、逻辑回归原理、分类与代码实现在机器学习与深度学习领域损失函数是连接模型预测与真实标签的核心桥梁它量化了模型预测结果与实际值之间的偏差是模型训练过程中参数更新的“导航仪”。无论是简单的线性回归、逻辑回归还是复杂的卷积神经网络CNN、循环神经网络RNN抑或是当下热门的Transformer模型都离不开损失函数的指引。正确选择和理解损失函数直接决定了模型的训练效果、收敛速度乃至最终的任务性能。本文将系统梳理损失函数的基础理论从损失函数的定义、核心作用出发详细划分损失函数的类别针对每类典型损失函数深入剖析其数学原理、适用场景并结合Python代码实现案例帮助读者全面掌握损失函数的应用逻辑。同时本文还将探讨损失函数选择的关键因素、常见问题及解决方案为实际模型开发中的损失函数选型提供指导。全文约6000字兼顾理论深度与实践可行性适合机器学习初学者、进阶开发者及相关领域研究者阅读。一、损失函数基础定义与核心作用1.1 损失函数的定义损失函数Loss Function也称为代价函数Cost Function或目标函数Objective Function是一个衡量模型预测值 \( \hat{y} \) 与真实标签 \( y \) 之间差异的函数通常用 \( L(y, \hat{y}) \) 表示。其本质是一个映射关系将模型预测结果与真实值的组合映射到一个非负实数损失值损失值越小代表模型预测越接近真实情况反之损失值越大说明模型预测与真实情况的偏差越大。需要注意的是在实际应用中“损失函数”与“代价函数”有时会被混用但严格来说二者存在细微区别损失函数通常针对单个样本的预测偏差如单个样本的预测值与真实值的差异而代价函数则是整个训练数据集上所有样本损失值的平均值或总和用于衡量模型在整个训练集上的整体性能。例如对于训练集 \( D \{(x_1,y_1), (x_2,y_2), ..., (x_n,y_n)\} \)单个样本的损失为 \( L(y_i, \hat{y}_i) \)则代价函数 \( J(\theta) \) 可表示为$$J(\theta) \frac{1}{n} \sum_{i1}^{n} L(y_i, \hat{y}_i(\theta, x_i))$$其中 \( \theta \) 是模型的参数\( \hat{y}_i(\theta, x_i) \) 表示模型在参数 \( \theta \) 下对输入 \( x_i \) 的预测值。而目标函数则是更广义的概念除了包含代价函数外还可能加入正则化项如L1、L2正则化用于防止模型过拟合引导模型参数朝着更优的方向收敛。1.2 损失函数的核心作用损失函数在机器学习模型训练中扮演着不可或缺的角色其核心作用主要体现在以下三个方面量化预测偏差这是损失函数最基础的作用。通过损失值的大小开发者可以直观地判断模型当前的预测性能。例如在回归任务中若损失值为0说明模型完全拟合了该样本若损失值很大则需要进一步优化模型。指导参数更新模型训练的核心目标是最小化代价函数而损失函数是代价函数的基础。在梯度下降等优化算法中通过计算损失函数对模型参数的梯度即损失值随参数变化的速率可以确定参数更新的方向和步长。梯度为负时参数增大可减小损失梯度为正时参数减小可减小损失最终通过迭代优化使损失函数达到最小值局部最小值或全局最小值。适配任务需求不同的机器学习任务如回归、分类、生成任务具有不同的目标损失函数的设计需与任务需求相匹配。例如回归任务需要预测连续值损失函数需能衡量连续值之间的差异分类任务需要预测离散的类别标签损失函数则需能衡量类别预测的准确性。此外针对特定任务的特殊需求如处理类别不平衡、重视少数类样本还可以通过定制损失函数来优化模型性能。1.3 损失函数的评价标准一个优秀的损失函数应具备以下几个关键特性以确保模型训练的高效性和稳定性非负性损失值应始终为非负数。这是因为损失函数的核心是衡量“偏差”偏差不应存在正负抵消的情况非负性可以保证损失值的大小直接反映偏差程度。可微性对于基于梯度下降的优化算法损失函数需在参数空间内具有良好的可微性或分段可微以便能够计算梯度并指导参数更新。若损失函数不可微则无法直接使用梯度下降算法需采用其他优化方法如次梯度下降。单调性当模型预测与真实值的偏差增大时损失值应单调递增反之偏差减小时损失值应单调递减。这一特性确保了损失函数能够正确反映模型预测性能的变化趋势。凸性对于凸优化问题凸损失函数可以保证存在唯一的全局最小值避免模型陷入局部最小值。但在深度学习等复杂模型中由于模型参数空间复杂损失函数往往是非凸的此时需通过优化算法如随机梯度下降、Adam和训练策略如学习率调度、正则化来寻找较优的局部最小值。二、损失函数的分类按任务类型划分根据机器学习任务的类型损失函数可分为三大类回归任务损失函数、分类任务损失函数和生成任务损失函数。其中回归任务和分类任务是最基础、最常见的两大任务类型对应的损失函数应用范围最广生成任务损失函数则主要用于生成模型如GAN、VAE目标是让模型生成的样本尽可能接近真实样本分布。本节将重点讲解回归任务和分类任务的典型损失函数同时简要介绍生成任务的核心损失函数每个损失函数均包含原理分析、适用场景及代码实现。2.1 回归任务损失函数回归任务的目标是预测一个连续的数值如房价、股票价格、温度等因此回归任务的损失函数需能够衡量两个连续值预测值与真实值之间的差异。常见的回归损失函数包括均方误差MSE、平均绝对误差MAE、均方根误差RMSE、平均绝对百分比误差MAPE、Huber损失、Log-Cosh损失等。2.1.1 均方误差Mean Squared Error, MSE原理分析均方误差是回归任务中最常用的损失函数之一其计算方式为预测值与真实值之差的平方和的平均值。数学公式如下$$MSE \frac{1}{n} \sum_{i1}^{n} (y_i - \hat{y}_i)^2$$其中\( n \) 为样本数量\( y_i \) 为第 \( i \) 个样本的真实值\( \hat{y}_i \) 为第 \( i \) 个样本的预测值。MSE的特点是对误差进行平方运算因此会放大较大误差异常值的影响。例如若某个样本的误差为10其平方后为100远大于误差为1的样本平方后为1这使得MSE对异常值非常敏感。这种特性在某些场景下是不利的如数据中存在较多噪声或异常值时但在数据相对干净、需要重点关注大误差样本的场景下则较为适用。从可微性角度看MSE是连续可微的函数其梯度计算简单便于使用梯度下降等优化算法进行参数更新。对模型参数 \( \theta \) 的梯度为$$\nabla_\theta MSE \frac{2}{n} \sum_{i1}^{n} (\hat{y}_i - y_i) \cdot \frac{\partial \hat{y}_i}{\partial \theta}$$适用场景MSE适用于数据分布较为均匀、无明显异常值的回归任务例如预测房屋面积与价格的关系假设房价数据无极端异常值预测学生的考试成绩成绩分布通常较为集中预测产品的销量在市场稳定的情况下销量数据无明显异常。代码实现以下是使用Python实现MSE的两种方式手动实现和使用PyTorch框架实现适用于深度学习模型训练。import numpy as np import torch import torch.nn as nn # 1. 手动实现MSE适用于简单回归模型 def mean_squared_error(y_true, y_pred): 计算均方误差MSE 参数 y_true: 真实值numpy数组或列表 y_pred: 预测值numpy数组或列表 返回 mse: 均方误差值 y_true np.array(y_true) y_pred np.array(y_pred) if y_true.shape ! y_pred.shape: raise ValueError(真实值与预测值的形状必须一致) n len(y_true) mse np.sum((y_true - y_pred) ** 2) / n return mse # 测试手动实现的MSE y_true [1.2, 2.3, 3.4, 4.5] y_pred [1.1, 2.4, 3.3, 4.6] mse_manual mean_squared_error(y_true, y_pred) print(f手动实现MSE: {mse_manual:.4f}) # 输出0.0100 # 2. PyTorch实现MSE适用于深度学习模型 # 定义MSE损失函数 mse_loss nn.MSELoss() # 构造真实值和预测值PyTorch张量 y_true_tensor torch.tensor(y_true, dtypetorch.float32).reshape(-1, 1) # 形状(4, 1) y_pred_tensor torch.tensor(y_pred, dtypetorch.float32).reshape(-1, 1) # 形状(4, 1) # 计算MSE mse_torch mse_loss(y_pred_tensor, y_true_tensor) print(fPyTorch实现MSE: {mse_torch.item():.4f}) # 输出0.01002.1.2 平均绝对误差Mean Absolute Error, MAE原理分析平均绝对误差是预测值与真实值之差的绝对值的平均值数学公式如下$$MAE \frac{1}{n} \sum_{i1}^{n} |y_i - \hat{y}_i|$$与MSE不同MAE采用绝对值来衡量误差不会对大误差进行平方放大因此对异常值的敏感度更低鲁棒性更强。例如误差为10的样本其绝对值为10远小于MSE中的100这使得MAE在数据中存在较多异常值或噪声的场景下表现更优。从可微性角度看MAE在 \( y_i \hat{y}_i \) 处不可微绝对值函数在0点的导数不存在这会给梯度下降优化带来一定挑战。为了解决这一问题在实际应用中通常会采用次梯度Subgradient的方法将0点的导数定义为0到1之间的任意值通常取0以保证优化过程的顺利进行。MAE对模型参数 \( \theta \) 的次梯度为$$\nabla_\theta MAE \frac{1}{n} \sum_{i1}^{n} \text{sign}(y_i - \hat{y}_i) \cdot \frac{\partial \hat{y}_i}{\partial \theta}$$其中 \( \text{sign}(\cdot) \) 为符号函数当 \( x 0 \) 时返回1当 \( x 0 \) 时返回-1当 \( x 0 \) 时返回0。适用场景MAE适用于数据中存在异常值、对大误差不敏感的回归任务例如预测城市每日的PM2.5浓度可能存在因极端天气导致的异常高值预测商品的价格可能存在个别商家的极端定价预测患者的血压值部分患者可能因突发疾病导致血压异常。代码实现import numpy as np import torch import torch.nn as nn # 1. 手动实现MAE def mean_absolute_error(y_true, y_pred): 计算平均绝对误差MAE 参数 y_true: 真实值numpy数组或列表 y_pred: 预测值numpy数组或列表 返回 mae: 平均绝对误差值 y_true np.array(y_true) y_pred np.array(y_pred) if y_true.shape ! y_pred.shape: raise ValueError(真实值与预测值的形状必须一致) n len(y_true) mae np.sum(np.abs(y_true - y_pred)) / n return mae # 测试手动实现的MAE y_true [1.2, 2.3, 3.4, 4.5, 100.0] # 加入异常值100.0 y_pred [1.1, 2.4, 3.3, 4.6, 90.0] mae_manual mean_absolute_error(y_true, y_pred) print(f手动实现MAE: {mae_manual:.4f}) # 输出2.1800 # 对比MSE在异常值下的表现 def mean_squared_error(y_true, y_pred): y_true np.array(y_true) y_pred np.array(y_pred) n len(y_true) return np.sum((y_true - y_pred) ** 2) / n mse_manual mean_squared_error(y_true, y_pred) print(f异常值下MSE: {mse_manual:.4f}) # 输出20.0180远大于MAE # 2. PyTorch实现MAE mae_loss nn.L1Loss() # PyTorch中L1Loss即为MAE y_true_tensor torch.tensor(y_true, dtypetorch.float32).reshape(-1, 1) y_pred_tensor torch.tensor(y_pred, dtypetorch.float32).reshape(-1, 1) mae_torch mae_loss(y_pred_tensor, y_true_tensor) print(fPyTorch实现MAE: {mae_torch.item():.4f}) # 输出2.18002.1.3 均方根误差Root Mean Squared Error, RMSE原理分析均方根误差是均方误差的平方根数学公式如下$$RMSE \sqrt{\frac{1}{n} \sum_{i1}^{n} (y_i - \hat{y}_i)^2}$$RMSE的本质是对MSE进行了开方运算其核心作用是将损失值的单位转换为与原始数据相同的单位使得损失值更具可解释性。例如在预测房价的任务中MSE的单位是“平方元”而RMSE的单位是“元”可以直接对应到房价的实际偏差范围。与MSE类似RMSE对异常值仍然较为敏感因为它继承了MSE的平方运算特性。在优化过程中RMSE的梯度计算与MSE类似只是多了一个开方后的系数$$\nabla_\theta RMSE \frac{1}{n \cdot RMSE} \sum_{i1}^{n} (y_i - \hat{y}_i) \cdot \frac{\partial \hat{y}_i}{\partial \theta}$$适用场景RMSE适用于需要损失值与原始数据单位一致、便于解释的回归任务同时要求数据中无明显异常值例如预测地区的人均收入单位为“元”RMSE可直接表示人均收入的预测偏差预测河流的水位高度单位为“米”RMSE可直观反映水位预测的偏差范围预测电子产品的续航时间单位为“小时”RMSE便于理解续航预测的误差大小。代码实现import numpy as np import torch import torch.nn as nn # 1. 手动实现RMSE def root_mean_squared_error(y_true, y_pred): 计算均方根误差RMSE 参数 y_true: 真实值numpy数组或列表 y_pred: 预测值numpy数组或列表 返回 rmse: 均方根误差值 y_true np.array(y_true) y_pred np.array(y_pred) if y_true.shape ! y_pred.shape: raise ValueError(真实值与预测值的形状必须一致) n len(y_true) mse np.sum((y_true - y_pred) ** 2) / n rmse np.sqrt(mse) return rmse # 测试手动实现的RMSE y_true [5000.0, 6000.0, 7000.0, 8000.0] # 人均收入数据单位元 y_pred [4900.0, 6100.0, 6900.0, 8200.0] rmse_manual root_mean_squared_error(y_true, y_pred) print(f手动实现RMSE: {rmse_manual:.2f} 元) # 输出111.80 元单位与原始数据一致 # 2. PyTorch实现RMSEPyTorch无直接的RMSE函数可通过MSE开方实现 mse_loss nn.MSELoss() y_true_tensor torch.tensor(y_true, dtypetorch.float32).reshape(-1, 1) y_pred_tensor torch.tensor(y_pred, dtypetorch.float32).reshape(-1, 1) mse_torch mse_loss(y_pred_tensor, y_true_tensor) rmse_torch torch.sqrt(mse_torch) print(fPyTorch实现RMSE: {rmse_torch.item():.2f} 元) # 输出111.80 元2.1.4 平均绝对百分比误差Mean Absolute Percentage Error, MAPE原理分析平均绝对百分比误差是预测值与真实值之差的绝对值占真实值的百分比的平均值数学公式如下$$MAPE \frac{100\%}{n} \sum_{i1}^{n} \left| \frac{y_i - \hat{y}_i}{y_i} \right|$$MAPE的核心特点是将误差标准化为百分比形式使得损失值不受原始数据单位的影响便于跨数据集、跨任务比较模型性能。例如预测房价万元级和预测日用品价格元级的MAPE可以直接对比而MSE或MAE则因单位不同无法直接比较。MAPE的局限性在于当真实值 \( y_i 0 \) 时分母为0会导致MAPE无意义当真实值 \( y_i \) 较小时百分比误差会被放大导致MAPE对小值样本敏感。因此MAPE仅适用于真实值不为0且分布较为均匀的回归任务。适用场景MAPE适用于需要衡量相对误差、跨任务比较模型性能的回归任务例如不同行业的销量预测如汽车销量、手机销量单位不同但可通过MAPE比较预测精度不同地区的GDP预测GDP数值差异大百分比误差更具参考价值企业的营收预测便于对比不同业务线的预测偏差程度。代码实现import numpy as np import torch # 1. 手动实现MAPE def mean_absolute_percentage_error(y_true, y_pred): 计算平均绝对百分比误差MAPE 参数 y_true: 真实值numpy数组或列表 y_pred: 预测值numpy数组或列表 返回 mape: 平均绝对百分比误差% y_true np.array(y_true) y_pred np.array(y_pred) if y_true.shape ! y_pred.shape: raise ValueError(真实值与预测值的形状必须一致) if np.any(y_true 0): raise ValueError(真实值中存在0无法计算MAPE) n len(y_true) mape (np.sum(np.abs((y_true - y_pred) / y_true)) / n) * 100 return mape # 测试手动实现的MAPE y_true_car [10000, 12000, 15000] # 汽车销量辆 y_pred_car [9500, 12500, 14500] mape_car mean_absolute_percentage_error(y_true_car, y_pred_car) print(f汽车销量MAPE: {mape_car:.2f}%) # 输出3.56% y_true_phone [50000, 60000, 70000] # 手机销量部 y_pred_phone [48000, 62000, 69000] mape_phone mean_absolute_percentage_error(y_true_phone, y_pred_phone) print(f手机销量MAPE: {mape_phone:.2f}%) # 输出2.22%可直接与汽车销量MAPE对比 # 2. PyTorch实现MAPE def torch_mape(y_true, y_pred): PyTorch版本的MAPE 参数 y_true: 真实值PyTorch张量 y_pred: 预测值PyTorch张量 返回 mape: 平均绝对百分比误差% if torch.any(y_true 0): raise ValueError(真实值中存在0无法计算MAPE) mape (torch.mean(torch.abs((y_true - y_pred) / y_true)) * 100) return mape y_true_tensor torch.tensor(y_true_car, dtypetorch.float32).reshape(-1, 1) y_pred_tensor torch.tensor(y_pred_car, dtypetorch.float32).reshape(-1, 1) mape_torch torch_mape(y_true_tensor, y_pred_tensor) print(fPyTorch实现汽车销量MAPE: {mape_torch.item():.2f}%) # 输出3.56%2.1.5 Huber损失平衡MSE与MAE的鲁棒损失原理分析Huber损失是由Peter Huber提出的一种鲁棒损失函数其核心思想是在误差较小时采用MSE保证优化的平滑性在误差较大时采用MAE降低对异常值的敏感度通过一个阈值 \( \delta \) 来区分“小误差”和“大误差”。数学公式如下$$L_\delta(y, \hat{y}) \begin{cases} \frac{1}{2}(y - \hat{y})^2 \text{if } |y - \hat{y}| \leq \delta \\ \delta |y - \hat{y}| - \frac{1}{2}\delta^2 \text{if } |y - \hat{y}| \delta \end{cases}$$其中 \( \delta \) 是一个超参数通常取值为1.0可根据数据情况调整。当误差的绝对值小于等于 \( \delta \) 时Huber损失与MSE一致具有良好的可微性和平滑的梯度当误差的绝对值大于 \( \delta \) 时Huber损失与MAE一致梯度为常数 \( \delta \) 或 \( -\delta \)不会因异常值导致梯度爆炸。Huber损失的梯度计算如下$$\nabla_\theta L_\delta \begin{cases} (\hat{y} - y) \cdot \frac{\partial \hat{y}}{\partial \theta} \text{if } |y - \hat{y}| \leq \delta \\ \delta \cdot \text{sign}(\hat{y} - y) \cdot \frac{\partial \hat{y}}{\partial \theta} \text{if } |y - \hat{y}| \delta \end{cases}$$Huber损失结合了MSE和MAE的优点既能够在数据干净时保证较快的收敛速度得益于MSE的平滑梯度又能够在数据存在异常值时保持较好的鲁棒性得益于MAE的线性特性。适用场景Huber损失适用于数据中存在少量异常值、需要平衡收敛速度和鲁棒性的回归任务例如自动驾驶中的车速预测可能存在传感器异常导致的极端值金融风险预测部分交易数据可能存在异常波动医疗数据中的指标预测如血糖、血脂可能存在测量误差导致的异常值。代码实现import numpy as np import torch import torch.nn as nn # 1. 手动实现Huber损失 def huber_loss(y_true, y_pred, delta1.0): 计算Huber损失 参数 y_true: 真实值numpy数组或列表 y_pred: 预测值numpy数组或列表 delta: 阈值默认1.0 返回 huber: Huber损失值 y_true np.array(y_true) y_pred np.array(y_pred) if y_true.shape ! y_pred.shape: raise ValueError(真实值与预测值的形状必须一致) error y_true - y_pred abs_error np.abs(error) # 分情况计算损失 huber np.where(abs_error delta, 0.5 * error ** 2, delta * abs_error - 0.5 * delta ** 2) return np.mean(huber) # 测试手动实现的Huber损失 y_true [1.2, 2.3, 3.4, 4.5, 100.0] # 含异常值 y_pred [1.1, 2.4, 3.3, 4.6, 90.0] huber_delta1 huber_loss(y_true, y_pred, delta1.0) huber_delta5 huber_loss(y_true, y_pred, delta5.0) print(fHuber损失delta1.0: {huber_delta1:.4f}) # 输出5.0050 print(fHuber损失delta5.0: {huber_delta5:.4f}) # 输出5.0180 # 对比MSE和MAE mse np.mean((np.array(y_true) - np.array(y_pred)) ** 2) mae np.mean(np.abs(np.array(y_true) - np.array(y_pred))) print(fMSE: {mse:.4f}) # 输出20.0180 print(fMAE: {mae:.4f}) # 输出2.1800Huber损失介于两者之间 # 2. PyTorch实现Huber损失 huber_loss_torch nn.HuberLoss(delta1.0) # PyTorch 1.9.0及以上版本支持 y_true_tensor torch.tensor(y_true, dtypetorch.float32).reshape(-1, 1) y_pred_tensor torch.tensor(y_pred, dtypetorch.float32).reshape(-1, 1) huber_torch huber_loss_torch(y_pred_tensor, y_true_tensor) print(fPyTorch实现Huber损失delta1.0: {huber_torch.item():.4f}) # 输出5.00502.1.6 Log-Cosh损失光滑的鲁棒损失原理分析Log-Cosh损失是另一种鲁棒的回归损失函数其数学表达式为预测值与真实值之差的双曲余弦函数的对数公式如下$$L(y, \hat{y}) \log(\cosh(y - \hat{y}))$$其中 \( \cosh(x) \frac{e^x e^{-x}}{2} \) 是双曲余弦函数。Log-Cosh损失的核心特点是在误差较小时其近似于MSE在误差较大时其近似于MAE同时保持了整个定义域内的光滑性可微性。具体来说当 \( x \) 较小时\( \cosh(x) \approx 1 \frac{x^2}{2} \)因此 \( \log(\cosh(x)) \approx \log(1 \frac{x^2}{2}) \approx \frac{x^2}{2} \)与MSE的形式一致当 \( x \) 较大时\( \cosh(x) \approx \frac{e^{|x|}}{2} \)因此 \( \log(\cosh(x)) \approx |x| - \log(2) \)与MAE的形式一致仅相差一个常数项不影响优化方向。与Huber损失相比Log-Cosh损失的优势在于其完全光滑没有Huber损失中的分段点梯度变化更平缓有助于优化算法的稳定收敛。Log-Cosh损失对模型参数 \( \theta \) 的梯度为$$\nabla_\theta L \tanh(y - \hat{y}) \cdot \frac{\partial \hat{y}}{\partial \theta}$$其中 \( \tanh(x) \) 是双曲正切函数其取值范围为(-1, 1)因此梯度不会像MSE那样因异常值而过大保证了优化的稳定性。适用场景Log-Cosh损失适用于数据中存在异常值、需要光滑损失函数以保证优化稳定的回归任务例如深度学习中的回归任务如图像分割中的像素值预测需要稳定的梯度更新时间序列预测如股票价格、气象数据可能存在异常波动且需要光滑损失保证收敛高维数据的回归任务光滑损失有助于缓解高维空间中的优化困难。代码实现import numpy as np import torch import torch.nn as nn # 1. 手动实现Log-Cosh损失 def log_cosh_loss(y_true, y_pred): 计算Log-Cosh损失 参数 y_true: 真实值numpy数组或列表 y_pred: 预测值numpy数组或列表 返回 log_cosh: Log-Cosh损失值 y_true np.array(y_true) y_pred np.array(y_pred) if y_true.shape ! y_pred.shape: raise ValueError(真实值与预测值的形状必须一致) error y_true - y_pred log_cosh np.log(np.cosh(error)) return np.mean(log_cosh) # 测试手动实现的Log-Cosh损失 y_true [1.2, 2.3, 3.4, 4.5, 100.0] # 含异常值 y_pred [1.1, 2.4, 3.3, 4.6, 90.0] log_cosh log_cosh_loss(y_true, y_pred) print(fLog-Cosh损失: {log_cosh:.4f}) # 输出4.5051 # 对比Huber损失delta1.0 huber huber_loss(y_true, y_pred, delta1.0) print(fHuber损失delta1.0: {huber:.4f}) # 输出5.0050Log-Cosh损失略小 # 2. PyTorch实现Log-Cosh损失 class LogCoshLoss(nn.Module): PyTorch自定义Log-Cosh损失函数 def __init__(self): super(LogCoshLoss, self).__init__() def forward(self, y_pred, y_true): error y_true - y_pred return torch.mean(torch.log(torch.cosh(error))) # 初始化损失函数并计算 log_cosh_loss_torch LogCoshLoss() y_true_tensor torch.tensor(y_true, dtypetorch.float32).reshape(-1, 1) y_pred_tensor torch.tensor(y_pred, dtypetorch.float32).reshape(-1, 1) log_cosh_torch log_cosh_loss_torch(y_pred_tensor, y_true_tensor) print(fPyTorch实现Log-Cosh损失: {log_cosh_torch.item():.4f}) # 输出4.50512.2 分类任务损失函数分类任务的目标是预测样本所属的离散类别如二分类中的“正/负”、多分类中的“猫/狗/鸟”因此分类任务的损失函数需能够衡量模型预测的类别概率分布与真实类别分布之间的差异。常见的分类损失函数包括交叉熵损失Cross-Entropy Loss、二元交叉熵损失Binary Cross-Entropy Loss、负对数似然损失Negative Log-Likelihood Loss, NLL Loss、Focal Loss等。在分类任务中模型的输出通常是未归一化的得分Logits需要通过Softmax函数多分类或Sigmoid函数二分类转换为概率分布再与真实类别标签通常采用独热编码One-Hot Encoding计算损失。2.2.1 二元交叉熵损失Binary Cross-Entropy Loss, BCE Loss原理分析二元交叉熵损失适用于二分类任务样本仅有两个可能的类别如“阳性/阴性”“垃圾邮件/正常邮件”其核心是衡量模型预测的正类概率与真实标签之间的差异。对于二分类任务模型的输出通常通过Sigmoid函数转换为正类的概率 \( \hat{p} \sigma(z) \frac{1}{1 e^{-z}} \)其中 \( z \) 是模型的Logits输出真实标签 \( y \in \{0, 1\} \)0表示负类1表示正类。二元交叉熵损失的数学公式如下$$BCE -\frac{1}{n} \sum_{i1}^{n} [y_i \log(\hat{p}_i) (1 - y_i) \log(1 - \hat{p}_i)]$$其中 \( n \) 为样本数量\( y_i \) 为第 \( i \) 个样本的真实标签\( \hat{p}_i \) 为第 \( i \) 个样本预测为正类的概率。BCE损失的直观含义是当真实标签为1时损失项为 \( -\log(\hat{p}_i) \)此时 \( \hat{p}_i \) 越接近1损失越小当真实标签为0时损失项为 \( -\log(1 - \hat{p}_i) \)此时 \( \hat{p}_i \) 越接近0损失越小。若模型预测概率与真实标签偏差较大如真实标签为1但预测概率为0.1则损失值会显著增大。为了避免对数运算中出现 \( \log(0) \) 的情况导致损失值为无穷大实际实现中通常会在概率值上添加一个微小的epsilon如1e-7将概率值限制在 \( [\epsilon, 1 - \epsilon] \) 范围内。BCE损失对模型参数 \( \theta \) 的梯度为$$\nabla_\theta BCE -\frac{1}{n} \sum_{i1}^{n} \left( \frac{y_i}{\hat{p}_i} - \frac{1 - y_i}{1 - \hat{p}_i} \right) \cdot \frac{\partial \hat{p}_i}{\partial z_i} \cdot \frac{\partial z_i}{\partial \theta}$$由于 \( \frac{\partial \hat{p}_i}{\partial z_i} \hat{p}_i (1 - \hat{p}_i) \)Sigmoid函数的导数特性梯度可简化为$$\nabla_\theta BCE \frac{1}{n} \sum_{i1}^{n} (\hat{p}_i - y_i) \cdot \frac{\partial z_i}{\partial \theta}$$简化后的梯度计算简单便于优化算法的实现。适用场景BCE损失适用于所有二分类任务例如医学影像中的病灶检测“有病灶/无病灶”垃圾邮件识别“垃圾邮件/正常邮件”用户 churn 预测“用户流失/用户留存”二元属性分类如“商品是否合格”“图片是否包含人脸”。代码实现import numpy as np import torch import torch.nn as nn import torch.nn.functional as F # 1. 手动实现BCE损失含Sigmoid转换 def binary_cross_entropy_loss(y_true, y_logits, epsilon1e-7): 计算二元交叉熵损失BCE 参数 y_true: 真实标签numpy数组或列表取值为0或1 y_logits: 模型Logits输出未经过Sigmoidnumpy数组或列表 epsilon: 防止log(0)的微小值默认1e-7 返回 bce: 二元交叉熵损失值 y_true np.array(y_true) y_logits np.array(y_logits) if y_true.shape ! y_logits.shape: raise ValueError(真实标签与Logits的形状必须一致) # Sigmoid转换为概率 y_pred 1 / (1 np.exp(-y_logits)) # 限制概率范围 y_pred np.clip(y_pred, epsilon, 1 - epsilon) # 计算BCE损失 bce -np.mean(y_true * np.log(y_pred) (1 - y_true) * np.log(1 - y_pred)) return bce # 测试手动实现的BCE损失 y_true [1, 0, 1, 0, 1] # 二分类真实标签 y_logits [2.3, -1.2, 3.1, 0.5, 1.8] # 模型Logits输出 bce_manual binary_cross_entropy_loss(y_true, y_logits) print(f手动实现BCE损失: {bce_manual:.4f}) # 输出0.1562 # 2. PyTorch实现BCE损失两种方式带Sigmoid和不带Sigmoid # 方式1使用BCEWithLogitsLoss直接输入Logits内置Sigmoid数值更稳定 bce_with_logits_loss nn.BCEWithLogitsLoss() y_true_tensor torch.tensor(y_true, dtypetorch.float32).reshape(-1, 1) y_logits_tensor torch.tensor(y_logits, dtypetorch.float32).reshape(-1, 1) bce_torch1 bce_with_logits_loss(y_logits_tensor, y_true_tensor) print(fPyTorch BCEWithLogitsLoss: {bce_torch1.item():.4f}) # 输出0.1562 # 方式2先Sigmoid再用BCELoss需注意数值稳定性 sigmoid nn.Sigmoid() y_pred_tensor sigmoid(y_logits_tensor) bce_loss nn.BCELoss() bce_torch2 bce_loss(y_pred_tensor, y_true_tensor) print(fPyTorch Sigmoid BCELoss: {bce_torch2.item():.4f}) # 输出0.15622.2.2 交叉熵损失Cross-Entropy Loss, CE Loss原理分析交叉熵损失适用于多分类任务样本有两个以上的可能类别且每个样本仅属于一个类别其核心是衡量模型预测的类别概率分布与真实类别分布独热编码之间的差异。对于多分类任务模型的输出通常是一个维度为类别数 \( C \) 的Logits向量需要通过Softmax函数转换为概率分布 \( \hat{p} \text{Softmax}(z) \)其中 \( \hat{p}_j \frac{e^{z_j}}{\sum_{k1}^{C} e^{z_k}} \)\( z_j \) 是Logits向量的第 \( j \) 个元素满足 \( \sum_{j1}^{C} \hat{p}_j 1 \)。真实类别标签通常采用独热编码表示若样本属于第 \( k \) 类则真实标签向量 \( y \) 的第 \( k \) 个元素为1其余元素为0即 \( y_j 1 \) 当且仅当 \( j k \)否则 \( y_j 0 \)。交叉熵损失的数学公式如下$$CE -\frac{1}{n} \sum_{i1}^{n} \sum_{j1}^{C} y_{i,j} \log(\hat{p}_{i,j})$$其中 \( n \) 为样本数量\( C \) 为类别数\( y_{i,j} \) 为第 \( i \) 个样本真实标签向量的第 \( j \) 个元素\( \hat{p}_{i,j} \) 为第 \( i \) 个样本预测为第 \( j \) 类的概率。由于真实标签是独热编码对于每个样本 \( i \)只有当 \( j \) 为真实类别时 \( y_{i,j} 1 \)其余项均为0因此交叉熵损失可简化为$$CE -\frac{1}{n} \sum_{i1}^{n} \log(\hat{p}_{i,k_i})$$其中 \( k_i \) 是第 \( i \) 个样本的真实类别。这一简化表明交叉熵损失本质上是对每个样本真实类别的预测概率取负对数预测概率越接近1损失越小反之损失越大。与BCE损失类似为了避免 \( \log(0) \) 的情况实际实现中会对预测概率添加微小的epsilon。交叉熵损失的梯度计算利用了Softmax函数的导数特性最终简化后的梯度为$$\nabla_\theta CE \frac{1}{n} \sum_{i1}^{n} (\hat{p}_{i,j} - y_{i,j}) \cdot \frac{\partial z_{i,j}}{\partial \theta}$$梯度计算简单且数值稳定性较好。适用场景交叉熵损失适用于所有单标签多分类任务每个样本仅属于一个类别例如

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询