营销类型的公司网站,中国建设银行网站企业,大型服装网站建设,南京汽车 企业 网站建设实现步骤
下载数据集处理好数据集确定好模型#xff08;初始化模型参数等等#xff09;确定优化函数#xff08;损失函数也称为目标函数#xff09;和优化方法#xff08;一般选用随机梯度下降 SDG #xff09;进行模型的训练进行模型的评估
import torch
import torch…实现步骤
下载数据集处理好数据集确定好模型初始化模型参数等等确定优化函数损失函数也称为目标函数和优化方法一般选用随机梯度下降 SDG 进行模型的训练进行模型的评估
import torch
import torchvision
from torch import nn
from torch import optim
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
import matplotlib.pyplot as plt# 1. 下载数据集
mnist_train torchvision.datasets.MNIST(root../data, trainTrue, transformtransforms.ToTensor(), downloadTrue)
mnist_test torchvision.datasets.MNIST(root../data, trainFalse, transformtransforms.ToTensor(), downloadTrue)# 2. 创建批量数据迭代器
train_iter DataLoader(mnist_train, batch_size256, shuffleTrue)
test_iter DataLoader(mnist_test, batch_size256)# 3. 可视化检查数据
var next(iter(train_iter))
plt.title(str(var[1][0])) # 显示标签
plt.imshow(var[0][0].squeeze().numpy(), cmapgray) # 显示图片
plt.show()# 4. 定义模型多层感知机
net nn.Sequential(nn.Flatten(),nn.Linear(28 * 28, 512),nn.ReLU(),nn.Linear(512, 256),nn.ReLU(),nn.Linear(256, 10) # 注意这里是不需要加 Softmax 了的因为后面定义了nn.CrossEntropyLoss()这个会自动帮我们进行 Softmax 以及进行损失计算。其实就是目标函数
)# 初始化模型参数
def init_weights(m):if isinstance(m, nn.Linear):nn.init.normal_(m.weight, std0.01)net.apply(init_weights)# 5. 定义损失函数和优化器
loss_fn nn.CrossEntropyLoss() # CrossEntropyLoss已经包含了softmax所以不需要LogSoftmax
optimizer optim.SGD(net.parameters(), lr0.2)# 6. 训练模型
epoch_num 20
for epoch in range(epoch_num):net.train() # 设置为训练模式total_loss 0for X, y in train_iter:optimizer.zero_grad() # 清除梯度y_hat net(X) # 前向传播loss loss_fn(y_hat, y) # 计算损失loss.backward() # 反向传播optimizer.step() # 更新参数total_loss loss.item() * X.shape[0] # 累积损失avg_loss total_loss / len(mnist_train) # 计算平均损失print(fEpoch {epoch 1}/{epoch_num}, Loss: {avg_loss:.4f})# 7. 评估模型
def evaluate_model(net, test_iter):net.eval() # 设置为评估模式correct, total 0, 0with torch.no_grad(): # 在评估时不需要计算梯度for X, y in test_iter:y_hat net(X)_, predicted torch.max(y_hat, 1) # 获取预测的标签correct (predicted y).sum().item() # 统计正确的个数total y.size(0) # 统计总数accuracy correct / totalprint(fAccuracy on test set: {accuracy * 100:.2f}%)# 评估模型的表现
evaluate_model(net, test_iter) 代码实践的结果 自己不会去计算损失在模型进行训练的时候不知道如何把数据放进去原来只需要创建好了 DataLoader 以后通过枚举 就可以拿到数据了。最后进行模型评估的时候也是用 AI 进行完成了。所以多少还是差点意思。后面的代码多去实践实践并且思考吧 关于代码中交叉熵计算的理解
理解损失函数loss_fn是如何计算的对于训练神经网络来说是非常重要的。具体到你提到的这行代码
loss loss_fn(y_hat, y) # 计算损失损失函数的定义
在你的代码中损失函数是
loss_fn nn.CrossEntropyLoss()nn.CrossEntropyLoss() 是一种常用于多分类问题的损失函数它实际上包含了两个步骤
Softmax将模型的输出转换为概率分布。交叉熵损失计算真实标签与预测概率分布之间的差距。 为什么要用交叉熵呢因为交叉熵可以来衡量预测差距这个我们只需要这个知识点并且知道上面的公式就好了。 我们逐步分析这两个步骤。
1. Softmax概率转换
假设模型的输出 y_hat 是一个向量其中每个元素代表对应类别的“分数”或者说是原始的 logits。例如假设有 3 个类别模型的输出可能是
y_hat [2.0, 1.0, -1.0] # 这三个数字是 logits不是概率通过 Softmax 函数我们将这些 logits 转换成概率
# 计算 softmax
softmax torch.nn.functional.softmax(y_hat, dim-1)softmax 的输出会是一个概率分布每个数值的范围在 [0, 1] 之间且所有数值加起来为 1。例如经过 Softmax 后可能得到
softmax [0.7, 0.2, 0.1] # 类别 0 的概率是 0.7类别 1 的概率是 0.2类别 2 的概率是 0.12. 交叉熵损失Cross Entropy Loss
交叉熵是衡量两个概率分布之间差异的一个标准方法。在分类任务中我们希望预测的类别概率与真实标签分布尽可能接近。
对于一个单一的样本交叉熵损失的计算公式为 L − ∑ i 1 C y i log ( p i ) L - \sum_{i1}^{C} y_i \log(p_i) L−i1∑Cyilog(pi)
( C ) 是类别数。( y_i ) 是真实标签在 one-hot 编码下真实类别的标签为 1其他类别为 0。( p_i ) 是模型预测的概率。
对于多分类任务来说交叉熵损失会选择对应真实标签的类别概率 ( p_{\text{true}} ) 来计算损失。例如如果真实标签是类别 0那么我们只关注模型在类别 0 上的预测概率。
假设真实标签 y 是类别 0对应的 one-hot 编码是 [1, 0, 0]而模型的预测是
softmax [0.7, 0.2, 0.1]那么交叉熵损失为 L − ( 1 ⋅ log ( 0.7 ) 0 ⋅ log ( 0.2 ) 0 ⋅ log ( 0.1 ) ) − log ( 0.7 ) ≈ 0.3567 L - (1 \cdot \log(0.7) 0 \cdot \log(0.2) 0 \cdot \log(0.1)) - \log(0.7) \approx 0.3567 L−(1⋅log(0.7)0⋅log(0.2)0⋅log(0.1))−log(0.7)≈0.3567
nn.CrossEntropyLoss() 如何工作
在 PyTorch 中nn.CrossEntropyLoss 会自动处理上述两个步骤
将 y_hatlogits转换为概率。使用真实标签 y 计算交叉熵损失。
输入和输出
y_hat: 这是模型的原始输出logits形状为 (batch_size, num_classes)。每一行是一个样本的 logits。y: 这是标签通常是一个包含类别索引的向量形状为 (batch_size,)。每个元素是该样本的真实类别索引。
例如
假设我们有以下数据 模型的输出logits为 y_hat torch.tensor([[2.0, 1.0, -1.0], # 第一个样本[0.5, 1.5, 0.3]]) # 第二个样本真实标签 y 为 y torch.tensor([0, 1]) # 第一个样本的标签是类别 0第二个样本的标签是类别 1使用 nn.CrossEntropyLoss() 计算损失
loss_fn nn.CrossEntropyLoss()
loss loss_fn(y_hat, y)CrossEntropyLoss 会首先对 y_hat 进行 softmax 转换然后计算每个样本的交叉熵损失。你可以通过打印出来的 loss 来查看模型的表现。
总结
y_hat 是模型的原始输出logits表示每个类别的“分数”。nn.CrossEntropyLoss 会自动处理 softmax 和交叉熵损失的计算。损失函数的目的是衡量模型的输出与真实标签之间的差异差异越小损失值越小说明模型的预测越准确。
使用nn.CrossEntropyLoss 会自动进行独热编码
在计算交叉熵损失时nn.CrossEntropyLoss 会自动处理标签并且不需要你手动将标签转换为独热编码one-hot encoding。
具体来说
y_hat是模型的原始输出logits形状为 (batch_size, num_classes)每一行是一个样本的预测结果包含每个类别的分数logits。y是标签形状为 (batch_size,)每个元素是该样本的真实类别的 索引而不是独热编码。
nn.CrossEntropyLoss 会自动使用标签 y 中的类别索引如类别 0, 1, 2来计算损失它会根据该类别索引选择对应的模型输出进行计算而不需要你事先将标签转换为独热编码。
举个例子
假设我们有一个批次的两个样本模型的输出 y_hat 和真实标签 y 如下
模型的输出 y_hatlogits
y_hat torch.tensor([[2.0, 1.0, -1.0], # 第一个样本的 logits[0.5, 1.5, 0.3]]) # 第二个样本的 logits真实标签 y类别索引
y torch.tensor([0, 1]) # 第一个样本的标签是类别 0第二个样本的标签是类别 1在这个例子中y_hat 的形状是 (2, 3)表示有两个样本每个样本有三个类别的 logits。
对于第一个样本它的真实标签是类别 0y[0] 0。对于第二个样本它的真实标签是类别 1y[1] 1。
当使用 nn.CrossEntropyLoss 时它会根据真实标签中的类别索引来选择对应的类别概率通过 softmax 后的结果然后计算交叉熵损失。PyTorch 会自动完成
Softmax 转换将 y_hat 的 logits 转换为概率分布。损失计算根据真实标签的类别索引计算交叉熵损失。
损失计算过程
假设 y_hat 的 softmax 输出经过 softmax 转换后为
softmax torch.nn.functional.softmax(y_hat, dim1)# softmax 结果
# [[0.7, 0.2, 0.1], # 第一个样本的概率
# [0.3, 0.6, 0.1]] # 第二个样本的概率然后计算交叉熵损失时
对于第一个样本真实标签是 0损失将仅计算 softmax[0][0]即类别 0 的概率即 -log(0.7)。对于第二个样本真实标签是 1损失将仅计算 softmax[1][1]即类别 1 的概率即 -log(0.6)。
因此nn.CrossEntropyLoss 会自动从 y 中提取类别索引并计算相应的损失。
总结
不需要手动进行独热编码因为 nn.CrossEntropyLoss 会自动处理。标签 y 只需要是一个包含类别索引的张量每个元素是一个整数表示类别。nn.CrossEntropyLoss 会根据标签中的类别索引从 y_hat 中提取对应的 logits然后计算交叉熵损失。
通过这种方式PyTorch 简化了损失计算的过程让你不需要显式地进行独热编码的转换。
为什么在实验的时候我去掉了参数初始化对结果并没有很大影响
在深度学习模型中尤其是在多层感知机MLP中初始化模型参数对于训练的收敛速度和结果有重要影响。虽然初始化通常有助于提升训练过程的稳定性和准确性但在某些情况下即使没有显式初始化训练仍然可能得到较好的结果。这有以下几个原因
1. PyTorch 默认的权重初始化
如果你没有手动初始化模型参数PyTorch 会使用默认的初始化方式。对于 nn.Linear 层PyTorch 默认使用的是 均匀分布初始化U(-sqrt(k), sqrt(k))其中 k 是每一层的输入特征数即该层的输入维度。这种初始化方式通常可以在大部分场景下有效工作尤其是在简单的任务或小型模型中。
2. 任务本身比较简单
MNIST 数据集是一个相对简单的任务具有以下特点
样本相对简单28x28 的灰度图像。类别数量较少10 个类别。数据集规模较小60,000 个训练样本。
由于这些原因即使没有特别优化初始化方式模型仍然能在训练过程中较好地拟合数据因此准确率可能不会受到显著影响。
3. 优化器的鲁棒性
现代优化器如 SGD、Adam 等通常具有较强的鲁棒性能够在一定范围内有效地调整模型的参数避免了初始化差异带来的过度影响。即使没有进行显式初始化优化器也能够逐步调整模型的参数从而避免梯度消失或梯度爆炸等问题保证训练的顺利进行。
4. 训练过程中参数的调整
在模型训练初期即使初始化不完美随着训练的进行网络的权重会在反向传播过程中逐步调整到合适的值。因此即使开始时的参数较为随机优化过程仍然能够找到有效的解决方案。这就是深度学习的一个特性即使参数初始不理想优化过程通常能通过梯度更新找到合适的解。
5. 初始化不影响最终收敛结果
对于一些简单的任务模型可能在多个初始化条件下都能够达到一个相对接近的局部最优解。在这种情况下即使没有手动初始化权重模型也能收敛到较好的解。
总结
默认初始化PyTorch 内部的初始化方式通常已经能在很多简单的任务中有效工作特别是像 MNIST 这样简单的图像分类任务。优化器的鲁棒性帮助模型调整参数避免了初始化不完美时对结果产生显著影响。对于 MNIST 这种简单任务初始化参数的不同可能不会导致显著差异尤其是在训练的过程中优化器能够找到较好的解。
然而在一些更复杂的任务中初始化的方式会直接影响模型的训练效率和性能。在这些任务中精心设计的初始化例如 Xavier、He 初始化等能够帮助模型更快地收敛并避免训练过程中遇到的问题。