type
Page
status
Invisible
date
Feb 16, 2026
slug
Machine_Learning/deep-learning-study-notes/3_6
summary
动手深度学习v2课程
tags
机器学习
深度学习
category
icon
password
softmax回归也是重要的基础,因此应该知道实现softmax回归的细节。本节将使用3.5节中提到的Fashion—MNIST数据集,并设置数据迭代器的
batch_size=256。3.6.1. 初始化模型参数
和之前线性回归的例子一样,这里的每个样本都将用固定长度的向量表示。原始数据集中的每个样本都是的图像。本节需要将它们展平,视为长度为784的向量。
在softmax回归中,输出和类别一样多,由于使用的数据集有10个类别,所以网络的输出维度为10。因此权重将构成一个的矩阵,偏置将构成一个的行向量。与线性回归一样,这里使用正态分布初始化权重W,偏置初始化为0。
3.6.2. 定义softmax操作
实现softmax由三个步骤组成:
- 对每个项求幂(使用
exp);
- 对每一行求和(小批量中每个样本是一行),得到每个样本的规范化常数;
- 将每一行除以其规范化常数,确保结果的和为1。
回顾一下softmax的表达式:
根据公式写出代码:
正如上述代码,对于任何随机输入,我们将每个元素变成一个非负数。 此外,依据概率原理,每行总和为1。
虽然这在数学上看起来是正确的,但我们在代码实现中有点草率。矩阵中的非常大或非常小的元素可能造成数值上溢或下溢,但我们没有采取措施来防止这点。
3.6.3. 定义模型
定义softmax操作之后,可以实现softmax回归模型。下面的代码定义了输入如何通过网络映射到输出。注意,将数据传递到模型之前,我们使用
reshape函数将每张原始图像展平为向量。3.6.4. 定义损失函数
接下来,我们实现3.4节中引入的交叉熵损失函数。这可能是深度学习中最常见的损失函数,因为目前分类问题的数量远远超过回归问题的数量。
回顾一下,交叉熵采用真实标签的预测概率的负对数似然。这里我们不使用Python的for循环迭代预测(这往往是低效的),而是通过一个运算符选择所有元素。下面,我们创建一个数据样本
y_hat,其中包含2个样本在3个类别的预测概率,以及它们对应的标签y。有了y,我们知道在第一个样本中,第一类是正确的预测;而在第二个样本中,第三类是正确的预测。然后使用y作为y_hat中概率的索引,我们选择第一个样本中第一个类的概率和第二个样本中第三个类的概率。现在只需要一行代码即可实现交叉熵函数。
3.6.5. 分类精度
给定预测概率分布
y_hat,当我们必须输出硬预测(hard prediction)时,我们通常选择预测概率最高的类。许多应用都要求我们做出选择。如Gmail必须将电子邮件分类为“Primary(主要邮件)”、“Social(社交邮件)”“Updates(更新邮件)”或“Forums(论坛邮件)”。 Gmail做分类时可能在内部估计概率,但最终它必须在类中选择一个。当预测与标签分类
y一致时,即是正确的。分类精度即正确预测数量与总预测数量之比。虽然直接优化精度可能很困难(因为精度的计算不可导),但精度通常是我们最关心的性能衡量标准,我们在训练分类器时几乎总会关注它。为了计算精度,我们执行以下操作。首先,如果
y_hat是矩阵,那么假定第二个维度存储每个类的预测分数。我们使用argmax获得每行中最大元素的索引来获得预测类别。然后我们将预测类别与真实y元素进行比较 由于等式运算符“==”对数据类型很敏感,因此我们将y_hat的数据类型转换为与y的数据类型一致。结果是一个包含0(错)和1(对)的张量。最后,我们求和会得到正确预测的数量。继续使用之前定义的变量
y_hat和y分别作为预测的概率分布和标签。可以看到,第一个样本的预测类别是2(该行的最大元素为0.6,索引为2),这与实际标签0不一致。第二个样本的预测类别是2(该行的最大元素为0.5,索引为2),这与实际标签2一致。因此,这两个样本的分类精度率为0.5。同样,对于任意数据迭代器
data_iter可访问的数据集,可以评估在任意模型net的精度。这里定义一个实用程序类
Accumulator,用于对多个变量进行累加。在上面的evaluate_accuracy函数中,我们在Accumulator实例中创建了2个变量,分别用于存储正确预测的数量和预测的总数量。 当我们遍历数据集时,两者都将随着时间的推移而累加。由于我们使用随机权重初始化
net模型, 因此该模型的精度应接近于随机猜测。 例如在有10个类别情况下的精度为0.1。3.6.6. 训练
首先,我们定义一个函数来训练一个迭代周期。 请注意,
updater是更新模型参数的常用函数,它接受批量大小作为参数。 它可以是d2l.sgd函数(随机梯度下降),也可以是框架的内置优化函数。在展示训练函数的实现之前,我们定义一个在动画中绘制数据的实用程序类
Animator,它能够简化其余部分的代码。接下来我们实现一个训练函数,它会在
train_iter访问到的训练数据集上训练一个模型net。该训练函数将会运行多个迭代周期(由num_epochs指定)。在每个迭代周期结束时,利用test_iter访问到的测试数据集对模型进行评估。我们将利用Animator类来可视化训练进度。作为一个从零开始的实现,我们使用3.2节中定义的小批量随机梯度下降来优化模型的损失函数,设置学习率为0.1。
现在,我们训练模型10个迭代周期。迭代周期(
num_epochs)和学习率(lr)都是可调节的超参数。通过更改它们的值,我们可以提高模型的分类精度。现在训练已经完成,我们的模型已经准备好对图像进行分类预测。给定一系列图像,我们将比较它们的实际标签(文本输出的第一行)和模型预测(文本输出的第二行)。
3.6.8. 小结
- 借助softmax回归,我们可以训练多分类的模型。
- 训练softmax回归循环模型与训练线性回归模型非常相似:先读取数据,再定义模型和损失函数,然后使用优化算法训练模型。大多数常见的深度学习模型都有类似的训练过程。
