2.3深度学习——定义损失函数&定义优先算法&模型参数与真实值对比
在Gluon中,损失函数通过loss模块提供。在这个例子中,我们使用的是L2损失(也叫均方误差(MSE)),它衡量的是模型预测值与真实标签之间的差异。L2Loss:计算预测值和真实值之间的平方差并返回该值作为损失。适用于回归任务,尤其是线性回归模型中。优化算法是训练模型的关键部分,负责调整模型参数,使得损失函数的值最小化。小批量随机梯度下降SGD)是最常用的优化方法之一,Gluon提供了Train
2.3.5 定义损失函数
在 Gluon 中,损失函数通过 loss 模块提供。在这个例子中,我们使用的是 L2损失(也叫 均方误差(MSE)),它衡量的是模型预测值与真实标签之间的差异。
loss = gluon.loss.L2Loss()
L2Loss:计算预测值和真实值之间的平方差并返回该值作为损失。适用于回归任务,尤其是线性回归模型中。
2.3.6 定义优化算法
优化算法是训练模型的关键部分,负责调整模型参数,使得损失函数的值最小化。小批量随机梯度下降(SGD)是最常用的优化方法之一,Gluon 提供了 Trainer 类来处理不同的优化算法及其超参数。
在实例化 Trainer 时,我们需要指定:
- 模型参数:通过
net.collect_params()获取。 - 优化算法:在本例中是
'sgd',即小批量随机梯度下降。 - 超参数字典:包含如 学习率(
learning_rate) 等优化超参数。
from mxnet import gluon
trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': 0.03})
learning_rate:设置学习率,这决定了每次更新参数的步长。这里设为 0.03。
2.3.7 训练
通过高层API,训练过程可以相对简洁。我们不再需要手动管理梯度计算、损失计算等细节。训练过程通常分为以下几个步骤:
- 前向传播:通过
net(X)生成预测值,并计算损失l。 - 反向传播:通过
l.backward()计算损失对参数的梯度。 - 参数更新:通过
trainer.step(batch_size)更新模型参数。
每个训练周期,我们都会遍历一次数据集,并从中获取一个小批量的数据(X)和标签(y)。对于每一个小批量,执行上述三个步骤。
num_epochs = 3
for epoch in range(num_epochs):
for X, y in data_iter:
with autograd.record():
l = loss(net(X), y) # 前向传播
l.backward() # 反向传播
trainer.step(batch_size) # 更新模型参数
# 打印当前周期的损失值
l = loss(net(features), labels)
print(f'epoch {epoch + 1}, loss {l.mean().asnumpy():f}')
例如,训练过程中,损失值会随着训练的进行逐渐下降:
epoch 1, loss 0.025140
epoch 2, loss 0.000089
epoch 3, loss 0.000051
2.3.8 模型参数与真实值对比
训练完成后,我们可以检查模型的参数,并与真实的参数进行对比。在这个例子中,我们查看的是模型的权重(w)和偏置(b)。
w = net[0].weight.data() # 获取权重
print(f'w的估计误差: {true_w - w.reshape(true_w.shape)}')
b = net[0].bias.data() # 获取偏置
print(f'b的估计误差: {true_b - b}')
输出示例:
w的估计误差: [ 0.00055146 -0.0003221 ]
b的估计误差: [0.00057793]
可以看到,训练获得的参数与生成数据的真实参数非常接近。
2.3.9 小结
- 我们使用 Gluon 提供的高层API,简化了模型定义、损失函数定义和优化算法的实现。
data模块 提供了数据处理工具,nn模块 定义了许多神经网络层,loss模块 提供了常见的损失函数。- MXNet 的
initializer模块为模型参数提供了多种初始化方式。 - 通过
autograd和Trainer,可以简化反向传播和参数更新的过程,轻松实现高效的训练。
2.3.10 练习
-
问题: 如果我们用
l = loss(output, y).mean()替换l = loss(output, y),为了使代码的行为相同,需要将trainer.step(batch_size)更改为trainer.step(1),这是为什么?解答:
在使用loss(output, y).mean()时,我们计算的是批量损失的平均值。这会导致损失值的标量形式,因此需要将trainer.step(batch_size)改为trainer.step(1),以确保每次更新的梯度基于单个样本而非整个批次。 -
问题: 查看 MXNet 文档,了解模块
gluon.loss和init中提供了哪些损失函数和初始化方法。用 Huber损失 来代替。解答:
在 MXNet 中,gluon.loss模块提供了多个常用的损失函数,例如 L2Loss, SoftmaxCrossEntropyLoss, HuberLoss 等。我们可以通过以下代码使用 Huber损失:loss = gluon.loss.HuberLoss() -
问题: 你如何访问
dense.weight的梯度?解答:
通过以下方式可以访问Dense层的权重梯度:grad_w = net[0].weight.grad() print(grad_w)这将输出
Dense层权重的梯度。
更多推荐


所有评论(0)