在上一篇文章中,我们详细探讨了激活函数的种类。激活函数与损失函数在模型训练中紧密配合,共同确保输出能够合理地表示预测的概率。激活函数的作用是将模型的原始输出映射为概率形式,而损失函数则通过计算预测概率与真实标签之间的差异,指导模型的参数优化。
在训练过程中,激活函数提供有效的概率特性,损失函数通过优化过程不断调整模型,使其输出的概率更接近真实分布,从而实现可靠的预测结果。
1 损失函数的作用
损失函数是机器学习算法中的核心组件,它在模型预测值与实际结果之间架起桥梁。通过计算预测值与真实值之间的差异(即“损失”),损失函数量化了模型的表现优劣。这一差异为优化过程提供指导,帮助提高模型的准确性。
重要性
损失函数是模型训练过程中的关键指标,衡量了模型预测与实际数据的匹配程度。通过最小化损失,模型逐渐学习并提升预测能力。 损失函数的选择对模型性能影响显著,必须根据具体任务选择合适的损失函数,以充分满足任务需求。
损失函数的分类
根据学习任务的类型,损失函数可以分为以下两类:
- 回归模型:用于预测连续值。
- 分类模型:用于预测有限类别的离散值。
通过选择适合的损失函数,可以优化模型以满足回归或分类问题的具体需求。
2 损失函数
2.1 回归任务中的损失函数
回归任务旨在预测连续值,例如房价或温度。以下是一些常用的回归损失函数:
2.1.1 均方误差(Mean Squared Error, MSE)
MSE 是数据集中所有样本残差平方的平均值。残差指模型预测值与实际值之间的差异。计算公式为:
M
S
E
=
∑
i
=
1
n
(
y
i
−
y
^
i
)
2
n
MSE = \frac{\sum_{i=1}^{n} \left(y_i - \hat{y}_i \right)^2}{n}
MSE=n∑i=1n(yi−y^i)2
- i i i:数据集中的第 i i i 个样本
- n n n:训练样本总数
- y i y_i yi:第 i i i 个样本的实际输出值
- y ^ i \hat{y}_i y^i:第 i i i 个样本的预测值
平方残差的重要性
- 避免正负抵消:直接对残差求和可能导致正负误差相互抵消,使模型误以为表现良好。平方残差能够将所有误差转为正值,真实反映模型的表现。
- 惩罚较大误差:平方残差对较大的误差赋予更高权重,帮助模型更快收敛至最优值。
- 独立于样本量:通过取均值,MSE 不受训练集中数据点数量的影响,是一个适用性较强的评价指标。
局限性
MSE 对异常值敏感,因为较大的误差会对结果产生不成比例的影响。
代码实现
import numpy as np
# 定义均方误差函数
def mse(y, y_pred):
return np.sum((y - y_pred) ** 2) / np.size(y)
2.1.2 平均绝对误差(Mean Absolute Error, MAE)
MAE 是机器学习中常用的损失函数,通过计算数据集中所有样本残差的绝对值平均来衡量模型误差。公式如下:
M
A
E
=
∑
i
=
1
n
∣
y
i
−
y
^
i
∣
n
MAE = \frac{\sum_{i=1}^{n} \left| y_i - \hat{y}_i \right|}{n}
MAE=n∑i=1n∣yi−y^i∣
绝对值残差的重要性
- 确保正值:对残差取绝对值,将负误差转为正值,确保所有误差被同等对待。
- 独立于样本量:通过计算均值,MAE 不受训练集中数据点数量的影响,是一个一致性较强的误差度量方法。
优点
MAE 对异常值具有较强的鲁棒性,极端值不会对整体误差计算产生不成比例的影响。
缺点
尽管 MAE 对异常值敏感性较低,但在实践中不如均方误差(MSE)常用。这是因为绝对值函数在极小值处不可微,导致基于梯度的优化算法难以高效计算梯度。
代码实现
# 平均绝对误差函数
def mae(y, y_pred):
return np.sum(np.abs(y - y_pred)) / np.size(y)
2.1.3 平均偏差误差(Mean Bias Error, MBE)
MBE 类似于均方误差(MSE),但其精度较低。它通过计算预测值与实际值的偏差均值,帮助判断模型是否存在正偏差或负偏差。通过分析损失函数结果,可以评估模型是倾向于高估还是低估实际值,从而进一步优化模型以提高预测准确性。 公式如下:
M
B
E
=
∑
i
=
1
n
(
y
i
−
y
^
i
)
n
MBE = \frac{\sum_{i=1}^{n} \left( y_i - \hat{y}_i \right)}{n}
MBE=n∑i=1n(yi−y^i)
- n n n:训练样本总数
- y i y_i yi:第 i i i 个样本的实际值
- y ^ i \hat{y}_i y^i:第 i i i 个样本的预测值
Python 实现:
# 平均偏差误差
def mbe(y, y_pred):
return np.sum(y - y_pred) / np.size(y)
2.1.4 Huber 损失(Huber Loss / Smooth Mean Absolute Error)
Huber 损失结合了均方误差(MSE)和平均绝对误差(MAE)的优点,适用于对异常值不敏感但仍可微的场景。
特性:
- 当误差较小时,采用 MSE 组件,模型对小误差更敏感。
- 当误差较大时,采用 MAE 组件,降低异常值的影响。
- 引入一个超参数 δ \delta δ,用于定义从 MSE 切换到 MAE 的阈值。此超参数平衡了两种损失函数的转换,保证损失函数在切换时平滑过渡。
公式如下:
Loss
=
{
1
2
(
x
−
y
)
2
,
if
∣
x
−
y
∣
≤
δ
δ
∣
x
−
y
∣
−
1
2
δ
2
,
otherwise
\text{Loss} = \begin{cases} \frac{1}{2}(x - y)^2, & \text{if } |x - y| \leq \delta \\ \delta |x - y| - \frac{1}{2} \delta^2, & \text{otherwise} \end{cases}
Loss={21(x−y)2,δ∣x−y∣−21δ2,if ∣x−y∣≤δotherwise
- n n n:训练样本总数
- y i y_i yi:第 i i i 个样本的实际值
- y ^ i \hat{y}_i y^i:第 i i i 个样本的预测值
- δ \delta δ:控制从 MSE 到 MAE 切换的阈值
Python 实现:
# Huber 损失
def Huber(y, y_pred, delta):
condition = np.abs(y - y_pred) < delta
l = np.where(condition, 0.5 * (y - y_pred) ** 2,
delta * (np.abs(y - y_pred) - 0.5 * delta))
return np.sum(l) / np.size(y)
Huber 损失在包含异常值的数据集中表现出很好的灵活性和平衡性,适合大多数回归任务中的应用。
2.2 分类任务中的损失函数
2.2.1 交叉熵损失(Cross-Entropy Loss)
交叉熵损失(也称为负对数似然损失)是分类任务中常用的损失函数。它衡量预测概率与真实标签之间的匹配程度。
交叉熵损失的值会随着预测概率偏离真实标签而增加。换句话说,模型的预测越接近真实类别,损失越低。因此,通过最小化交叉熵损失,模型可以有效提高分类任务的准确性。
交叉熵损失的公式如下:
CrossEntropyLoss
=
−
(
y
i
log
(
y
^
i
)
+
(
1
−
y
i
)
log
(
1
−
y
^
i
)
)
\text{CrossEntropyLoss} = -\left( y_i \log(\hat{y}_i) + (1 - y_i) \log(1 - \hat{y}_i) \right)
CrossEntropyLoss=−(yilog(y^i)+(1−yi)log(1−y^i))
Python 实现:
# 交叉熵损失
def cross_entropy(y, y_pred):
return - np.sum(y * np.log(y_pred) + (1 - y) * np.log(1 - y_pred)) / np.size(y)
2.2.2 Hinge损失(Hinge Loss)
Hinge 损失也称为多分类 SVM 损失,用于最大边界分类任务,最常用于支持向量机(SVM)中。它通过确保决策边界尽可能远离数据点来提高分类性能。
Hinge 损失是凸函数,可以通过凸优化器有效优化。它鼓励模型在不同类别之间实现更大的间隔,从而提高泛化能力。
Hinge 损失的公式如下:
SVMLoss
=
∑
j
≠
y
i
max
(
0
,
s
j
−
s
y
i
+
1
)
\text{SVMLoss} = \sum_{j \neq y_i} \max(0, s_j - s_{y_i} + 1)
SVMLoss=j=yi∑max(0,sj−syi+1)
- y i y_i yi:第 i i i 个样本的真实类别标签。
- s j s_j sj:模型为类别 j j j 预测的分数(得分或 logit 值)。
- s y i s_{y_i} syi:模型为真实类别 y i y_i yi 预测的分数(得分或 logit 值)。
-
max
(
0
,
s
j
−
s
y
i
+
1
)
\max(0, s_j - s_{y_i} + 1)
max(0,sj−syi+1):如果类别
j
j
j 的预测分数与真实类别分数的差值加上
1
1
1 为正,则计算此值;否则为
0
0
0。
- 该公式保证了当预测分数的间隔大于 1 1 1 时,损失为 0 0 0,从而鼓励更大的分类边界。
# Hinge 损失
def hinge(y, y_pred):
l = 0
size = np.size(y)
for i in range(size):
l = l + max(0, 1 - y[i] * y_pred[i])
return l / size
2.2.3 KL 散度(Kullback-Leibler Divergence, KL Divergence)
KL 散度是一种衡量两个概率分布差异的损失函数。它量化了预测概率分布与参考概率分布之间的“距离”。
在机器学习中,KL 散度常用于涉及概率输出的模型,例如使用 softmax 输出的分类任务。通过最小化 KL 散度,模型确保其预测概率分布尽可能接近真实分布,是一种在需要精确概率输出时非常有用的损失函数。
KL 散度的公式如下:
KL
(
P
∣
∣
Q
)
=
∑
i
P
(
i
)
log
(
P
(
i
)
Q
(
i
)
)
\text{KL}(P || Q) = \sum_i P(i) \log\left(\frac{P(i)}{Q(i)}\right)
KL(P∣∣Q)=i∑P(i)log(Q(i)P(i))
- P ( i ) P(i) P(i):真实分布中类别 i i i 的概率值。
- Q ( i ) Q(i) Q(i):模型预测分布中类别 i i i 的概率值。
-
log
(
P
(
i
)
Q
(
i
)
)
\log\left(\frac{P(i)}{Q(i)}\right)
log(Q(i)P(i)):类别
i
i
i 的真实概率与预测概率的相对熵(信息增益)。
- 该公式量化了两个概率分布 P P P 和 Q Q Q 之间的“距离”。当 Q Q Q 接近 P P P 时,KL 散度的值越小,表示模型预测的概率分布越接近真实分布。
import numpy as np
def kl_divergence(P, Q):
"""
计算两个分布 P 和 Q 之间的 Kullback-Leibler (KL) 散度。
"""
# 确保 P 和 Q 是 numpy 数组
P = np.asarray(P, dtype=np.float32)
Q = np.asarray(Q, dtype=np.float32)
# 添加小的 epsilon 避免除零或 log(0)
epsilon = 1e-10
P = np.clip(P, epsilon, 1)
Q = np.clip(Q, epsilon, 1)
return np.sum(P * np.log(P / Q))
2.3 选择合适的损失函数
在机器学习中,选择损失函数需要考虑以下关键因素:
- 任务的性质:判断问题是回归任务还是分类任务。
比较维度 | 回归任务的损失函数 | 分类任务的损失函数 |
---|---|---|
目标 | 预测连续数值,关注预测值与真实值的数值差异。 | 预测离散类别标签,关注预测概率与真实标签的匹配程度。 |
数据特性 | 输出为连续值,需要量化数值误差。 | 输出为概率分布,需要衡量概率分布与真实标签之间的距离。 |
常用损失函数 | 均方误差(MSE)、平均绝对误差(MAE)、Huber 损失等。 | 交叉熵损失、Hinge 损失、KL 散度等。 |
优化目标 | 最小化数值误差(如偏差或方差),使预测值更接近真实值。 | 最小化分类错误率或最大化分类概率,优化模型的分类能力。 |
梯度特性 | 梯度平滑、连续可微,有助于优化算法稳定收敛。 | 梯度与概率输出相关,适合优化分类模型的准确性和概率分布。 |
适配的模型 | 线性回归、决策树回归、支持向量回归(SVR)等。 | 逻辑回归、神经网络(带 softmax 或 sigmoid 输出层)、SVM 等。 |
异常值的影响 | 对异常值敏感(如 MSE),或可通过 MAE、Huber 损失增强鲁棒性。 | 通常通过交叉熵等损失函数自动调整,不直接受异常值影响。 |
输出形式 | 预测值为连续数值。 | 预测值为概率分布(如 softmax 输出)。 |
- 异常值的影响:如果数据集中存在异常值,需选择对异常值更鲁棒的损失函数(如平均绝对误差(MAE)或 Huber 损失)。
- 模型复杂度:简单模型更适合使用简单的损失函数,如均方误差(MSE)或交叉熵损失。
- 可解释性:某些损失函数比其他函数更直观易懂,在实际应用中更便于解释。
2.4 损失函数总结
损失函数 | 使用场景 | 公式特点 | 适用场景特点 |
---|---|---|---|
均方误差(MSE) | 用于回归任务,衡量预测值与实际值之间的平方差,例如预测房价、温度等连续变量。 | 对较大的误差赋予更高权重,因此对异常值敏感,适合需要精确预测的任务。 | 当异常值较少时表现较好,优化时梯度平滑,适合基于梯度的优化算法。 |
平均绝对误差(MAE) | 用于回归任务,与 MSE 类似,但更加关注绝对误差,例如用在受异常值影响较大的数据集上,如交通流量预测。 | 对所有误差赋予相同权重,因此对异常值鲁棒,但绝对值函数在 0 点不可微,优化梯度不平滑。 | 适合存在异常值的数据集,但优化速度可能比 MSE 慢。 |
平均偏差误差(MBE) | 用于回归任务,衡量模型的偏差趋势,适合需要检测模型是否有持续高估或低估问题的场景,例如天气预报模型的性能评估。 | 能反映模型的偏差方向,但不能直接反映误差的大小,对模型性能评估作用有限。 | 当需要判断模型的正偏差或负偏差时适用,适合作为辅助分析指标而非主要损失函数。 |
Huber 损失 | 适用于同时存在小误差和异常值的回归任务,例如金融数据预测、噪声影响较大的工业传感器数据。 | 小误差时与 MSE 类似,大误差时与 MAE 类似,平滑可微,对异常值鲁棒,优化稳定性强。 | 适合需要平衡小误差精度和异常值鲁棒性的任务,尤其在存在噪声的数据集中表现良好。 |
交叉熵损失 | 用于分类任务,特别是多类别分类问题,例如图像分类(如猫、狗、鸟)或文本分类(如正面评论和负面评论)。 | 衡量预测概率与真实标签的匹配程度,预测值越接近真实类别,损失越低;对概率输出敏感,可用于调整模型的概率分布。 | 适用于所有分类任务,尤其是需要输出概率分布的场景,优化过程稳定。 |
Hinge 损失 | 用于支持向量机(SVM)中,确保决策边界远离分类点,例如二分类任务中的图像目标检测(猫或狗)。 | 通过最大化分类间隔增强泛化能力,但对小误差的梯度不敏感,不适合用于深度学习中的连续优化问题。 | 适用于需要最大化边界的分类任务,尤其是支持向量机模型,但不常用于神经网络中。 |
KL 散度 | 用于测量两个概率分布的差异,例如 NLP 中语言模型的训练(如目标分布和预测分布的差异),以及深度学习中的软标签学习。 | 量化预测概率分布与真实概率分布的“距离”,适合需要精确概率输出的场景;对预测概率中为零的值敏感。 | 适合概率分布对齐的任务,尤其是多类别分类任务或生成模型中的对数似然优化问题。 |
3 代码中损失函数的定义
3.1 TensorFlow
参数
损失函数 | 数学定义 | 描述 |
---|---|---|
tf.keras.losses.MeanSquaredError | L = 1 n ∑ i = 1 n ( y i − y ^ i ) 2 L = \frac{1}{n}\sum_{i=1}^n(y_i - \hat{y}_i)^2 L=n1∑i=1n(yi−y^i)2 | 均方误差(MSE),用于回归任务,衡量预测值与实际值之间的平方差。 |
tf.keras.losses.MeanAbsoluteError | L = 1 n ∑ i = 1 n ∣ y i − y ^ i ∣ L = \frac{1}{n}\sum_{i=1}^n|y_i - \hat{y}_i| L=n1∑i=1n∣yi−y^i∣ | 平均绝对误差(MAE),对异常值鲁棒,适用于回归任务。 |
tf.keras.losses.Huber | L = { 1 2 ( y − y ^ ) 2 if ∣ y − y ^ ∣ ≤ δ δ ∣ y − y ^ ∣ − 1 2 δ 2 otherwise L = \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{otherwise} \end{cases} L={21(y−y^)2δ∣y−y^∣−21δ2if ∣y−y^∣≤δotherwise | Huber 损失,结合了 MSE 和 MAE 的优点,适用于对异常值敏感的回归任务。 |
tf.keras.losses.BinaryCrossentropy | L = − 1 n ∑ i = 1 n ( y i log ( y ^ i ) + ( 1 − y i ) log ( 1 − y ^ i ) ) L = -\frac{1}{n} \sum_{i=1}^n \left( y_i \log(\hat{y}_i) + (1 - y_i) \log(1 - \hat{y}_i) \right) L=−n1∑i=1n(yilog(y^i)+(1−yi)log(1−y^i)) | 二分类交叉熵损失,用于衡量预测概率与实际标签的匹配程度,常用于二分类任务。 |
tf.keras.losses.CategoricalCrossentropy | L = − ∑ i = 1 n y i log ( y ^ i ) L = -\sum_{i=1}^n y_i \log(\hat{y}_i) L=−∑i=1nyilog(y^i) | 多分类交叉熵损失,用于多类别分类问题,通常结合 softmax 激活函数使用。 |
tf.keras.losses.KLDivergence | L = ∑ i P ( i ) log ( P ( i ) Q ( i ) ) L = \sum_i P(i) \log\left(\frac{P(i)}{Q(i)}\right) L=∑iP(i)log(Q(i)P(i)) | KL 散度,用于衡量两个概率分布的差异,常用于生成模型或概率分布校正。 |
代码
import tensorflow as tf
# 构建一个简单的神经网络
model = tf.keras.Sequential([
tf.keras.layers.Dense(128, activation='relu', input_shape=(784,)), # 隐藏层
tf.keras.layers.Dense(64, activation='relu'), # 隐藏层
tf.keras.layers.Dense(10, activation='softmax') # 输出层,用于多分类
])
# 编译模型,指定损失函数
model.compile(optimizer='adam',
loss=tf.keras.losses.CategoricalCrossentropy(), # 多分类交叉熵
metrics=['accuracy'])
# 打印模型结构
model.summary()
3.2 Keras 损失函数
参数
损失函数 | 数学定义 | 描述 |
---|---|---|
MeanSquaredError | L = 1 n ∑ i = 1 n ( y i − y ^ i ) 2 L = \frac{1}{n}\sum_{i=1}^n(y_i - \hat{y}_i)^2 L=n1∑i=1n(yi−y^i)2 | 均方误差(MSE),用于回归任务,衡量预测值与实际值之间的平方差。 |
MeanAbsoluteError | L = 1 n ∑ i = 1 n ∣ y i − y ^ i ∣ L = \frac{1}{n}\sum_{i=1}^n|y_i - \hat{y}_i| L=n1∑i=1n∣yi−y^i∣ | 平均绝对误差(MAE),对异常值鲁棒,适用于回归任务。 |
Huber | L = { 1 2 ( y − y ^ ) 2 if ∣ y − y ^ ∣ ≤ δ δ ∣ y − y ^ ∣ − 1 2 δ 2 otherwise L = \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{otherwise} \end{cases} L={21(y−y^)2δ∣y−y^∣−21δ2if ∣y−y^∣≤δotherwise | Huber 损失,结合了 MSE 和 MAE 的优点,适用于对异常值敏感的回归任务。 |
BinaryCrossentropy | L = − 1 n ∑ i = 1 n ( y i log ( y ^ i ) + ( 1 − y i ) log ( 1 − y ^ i ) ) L = -\frac{1}{n} \sum_{i=1}^n \left( y_i \log(\hat{y}_i) + (1 - y_i) \log(1 - \hat{y}_i) \right) L=−n1∑i=1n(yilog(y^i)+(1−yi)log(1−y^i)) | 二分类交叉熵损失,用于衡量预测概率与实际标签的匹配程度,常用于二分类任务。 |
CategoricalCrossentropy | L = − ∑ i = 1 n y i log ( y ^ i ) L = -\sum_{i=1}^n y_i \log(\hat{y}_i) L=−∑i=1nyilog(y^i) | 多分类交叉熵损失,用于多类别分类问题,通常结合 softmax 激活函数使用。 |
KLDivergence | L = ∑ i P ( i ) log ( P ( i ) Q ( i ) ) L = \sum_i P(i) \log\left(\frac{P(i)}{Q(i)}\right) L=∑iP(i)log(Q(i)P(i)) | KL 散度,用于衡量两个概率分布的差异,常用于生成模型或概率分布校正。 |
代码
from keras.models import Sequential
from keras.layers import Dense
# 构建一个简单的神经网络
model = Sequential([
Dense(128, activation='relu', input_dim=784), # 隐藏层
Dense(64, activation='relu'), # 隐藏层
Dense(10, activation='softmax') # 输出层,用于多分类
])
# 编译模型,指定损失函数
model.compile(optimizer='adam',
loss='categorical_crossentropy', # 多分类交叉熵
metrics=['accuracy'])
# 打印模型结构
model.summary()
3.3 PyTorch 损失函数
参数
损失函数 | 数学定义 | 描述 |
---|---|---|
torch.nn.MSELoss | L = 1 n ∑ i = 1 n ( y i − y ^ i ) 2 L = \frac{1}{n}\sum_{i=1}^n(y_i - \hat{y}_i)^2 L=n1∑i=1n(yi−y^i)2 | 均方误差(MSE),用于回归任务,衡量预测值与实际值之间的平方差。 |
torch.nn.L1Loss | L = 1 n ∑ i = 1 n ∣ y i − y ^ i ∣ L = \frac{1}{n}\sum_{i=1}^n|y_i - \hat{y}_i| L=n1∑i=1n∣yi−y^i∣ | 平均绝对误差(MAE),对异常值鲁棒,适用于回归任务。 |
torch.nn.SmoothL1Loss | L = { 1 2 ( y − y ^ ) 2 if ∣ y − y ^ ∣ ≤ δ δ ∣ y − y ^ ∣ − 1 2 δ 2 otherwise L = \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{otherwise} \end{cases} L={21(y−y^)2δ∣y−y^∣−21δ2if ∣y−y^∣≤δotherwise | 平滑 L1 损失(Huber 损失),结合了 MSE 和 MAE 的优点,适用于对异常值敏感的回归任务。 |
torch.nn.BCELoss | L = − 1 n ∑ i = 1 n ( y i log ( y ^ i ) + ( 1 − y i ) log ( 1 − y ^ i ) ) L = -\frac{1}{n} \sum_{i=1}^n \left( y_i \log(\hat{y}_i) + (1 - y_i) \log(1 - \hat{y}_i) \right) L=−n1∑i=1n(yilog(y^i)+(1−yi)log(1−y^i)) | 二分类交叉熵损失,用于衡量预测概率与实际标签的匹配程度,常用于二分类任务。 |
torch.nn.CrossEntropyLoss | L = − ∑ i = 1 n y i log ( y ^ i ) L = -\sum_{i=1}^n y_i \log(\hat{y}_i) L=−∑i=1nyilog(y^i) | 多分类交叉熵损失,用于多类别分类问题,通常结合 softmax 激活函数使用。 |
torch.nn.KLDivLoss | L = ∑ i P ( i ) log ( P ( i ) Q ( i ) ) L = \sum_i P(i) \log\left(\frac{P(i)}{Q(i)}\right) L=∑iP(i)log(Q(i)P(i)) | KL 散度,用于衡量两个概率分布的差异,常用于生成模型或概率分布校正。 |
代码
import torch
import torch.nn as nn
import torch.optim as optim
# 定义一个简单的神经网络
class SimpleNet(nn.Module):
def __init__(self):
super(SimpleNet, self).__init__()
self.model = nn.Sequential(
nn.Linear(784, 128), # 输入层到隐藏层
nn.ReLU(), # 使用 ReLU 激活函数
nn.Linear(128, 64),
nn.ReLU(), # 使用 ReLU 激活函数
nn.Linear(64, 10),
nn.Softmax(dim=1) # 使用 Softmax 激活函数
)
def forward(self, x):
return self.model(x)
# 初始化网络
net = SimpleNet()
# 定义损失函数和优化器
loss_fn = nn.CrossEntropyLoss() # 多分类交叉熵损失函数
optimizer = optim.Adam(net.parameters()) # 使用 Adam 优化器
# 模拟输入数据和标签
inputs = torch.rand(32, 784) # 32 个样本,每个样本有 784 个特征
labels = torch.randint(0, 10, (32,)) # 32 个样本的标签,每个标签为 0-9 的整数
# 前向传播
outputs = net(inputs) # 网络输出
loss = loss_fn(outputs, labels) # 计算损失
# 反向传播和优化
optimizer.zero_grad() # 清除梯度
loss.backward() # 反向传播
optimizer.step() # 更新模型参数
# 打印损失值
print(f"Loss: {loss.item()}")
4 总结
理解并选择合适的损失函数是构建高效机器学习模型的关键。无论是处理回归任务还是分类任务,每种损失函数都有其优势和局限性,适用于特定场景。通过仔细权衡这些因素,实践者可以优化模型性能,提升预测准确性,从而确保机器学习工作的成功。