尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

PyTorch线性回归实战:从环境配置到模型训练完整指南

PyTorch线性回归实战:从环境配置到模型训练完整指南 1. 项目缘起为什么从线性回归开始你的PyTorch之旅如果你刚刚打开PyTorch的官方文档或者点开了某个“深度学习入门”的教程大概率会被里面复杂的神经网络结构、各种激活函数和损失函数搞得眼花缭乱。很多人会想是不是得先啃完几百页的理论书才能动手写第一行代码我的经验是恰恰相反。最好的入门方式就是找一个最简单、最经典的问题用PyTorch把它跑通。而线性回归就是这个“最简单的问题”。你可能会觉得线性回归太“低级”了不就是y wx b吗中学就学过用Excel都能做何必动用PyTorch这种“重型武器”这正是关键所在。用PyTorch实现线性回归其目的不在于解决线性回归问题本身而在于通过这个极其简单的模型完整地走一遍PyTorch构建、训练、评估一个模型的标准流程。这个过程就像学开车你不是先学漂移而是先学起步、刹车、打方向盘。线性回归就是PyTorch世界的“起步、刹车、打方向盘”。通过这个项目你将亲手摸到PyTorch最核心的几块积木张量Tensor、自动求导Autograd、优化器Optimizer和损失函数Loss Function。你会理解数据如何被表示模型如何定义梯度如何计算并更新参数。当你用几行代码让一个简单的线性模型从随机猜测到精准预测时你就掌握了PyTorch的“第一性原理”。之后无论面对图像分类还是自然语言处理你都会发现它们不过是这个基本流程上叠加了更复杂的模块而已。所以别小看这个“Hello World”它是你构建所有复杂模型的坚实起点。2. 环境准备避开新手99%的安装坑在写第一行模型代码之前一个正确、干净的环境是重中之重。我看到太多新手在环境配置上折戟沉沙尤其是GPU版本的安装。下面我以最主流的Windows Anaconda CUDA方案为例拆解每一步的要点和避坑指南。如果你用macOS或Linux核心思路也完全一致。2.1 Conda环境管理为PyTorch建立一个“单间”绝对不要在你的Base环境里直接安装PyTorchBase环境是Anaconda的默认环境里面已经有很多包极易产生版本冲突。为每个项目创建独立的虚拟环境是专业开发者的第一课。打开Anaconda PromptWindows或终端macOS/Linux执行以下命令conda create -n pytorch_lr python3.9这里-n pytorch_lr指定了环境名称你可以随意取名。python3.9是指定Python版本我推荐3.8或3.9这是目前与多数库兼容性最好的版本。太新的版本如3.11有时会遇到一些底层库的编译问题。创建完成后激活环境conda activate pytorch_lr你会看到命令行提示符从(base)变成了(pytorch_lr)这表示你已经在“单间”里了接下来所有的操作都只影响这个环境。2.2 PyTorch安装官网命令里的“魔鬼细节”这是最关键也最容易出错的一步。很多人直接去PyTorch官网https://pytorch.org/在首页选择自己的配置然后复制运行下面那条命令。这没错但你必须理解这条命令的每一个部分。假设你有一张NVIDIA显卡并已经安装了CUDA 11.8。官网给你的命令可能长这样pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118我们来拆解一下torch: PyTorch主框架。torchvision: 处理图像数据、经典模型如ResNet和常用数据集的库做CV必备。torchaudio: 处理音频数据的库。--index-url https://download.pytorch.org/whl/cu118: 这是指定从PyTorch官方仓库的CUDA 11.8版本目录下载。cu118就是CUDA 11.8的缩写。你必须核对的几个点CUDA版本在命令行输入nvidia-smi查看右上角显示的CUDA Version。这个版本是你驱动支持的最高CUDA运行时版本。然后你需要去NVIDIA控制面板或通过nvcc --version查看你实际安装的CUDA Toolkit版本。安装PyTorch时应该以你实际安装的CUDA Toolkit版本为准。比如驱动支持12.4但你只装了11.8那就应该选择cu118。包管理器官网命令默认用pip。在Conda环境中使用pip是完全可以的而且通常比conda install更快、版本更全。不用担心冲突只要环境是激活的pip就会把包安装到当前Conda环境里。网络问题如果直接从官网下载慢或超时可以使用国内镜像源。但注意PyTorch的二进制包很大有些镜像可能同步不及时。最稳妥的方法是使用官网命令如果慢可以尝试添加-i https://pypi.tuna.tsinghua.edu.cn/simple但有时镜像源没有对应的CUDA版本whl文件会fallback到CPU版本务必注意安装后的验证。对于没有NVIDIA显卡的用户在官网选择“CPU”选项你会得到类似这样的命令pip3 install torch torchvision torchaudio这个命令会安装CPU版本的PyTorch所有计算都在CPU上进行适合学习和小规模数据。执行安装命令后耐心等待完成。安装的包体积可能超过1GB。2.3 验证安装确保PyTorch能“看到”你的GPU安装完成后千万不要直接开始写代码。先做一个简单的验证。打开Python解释器在激活的环境下输入pythonimport torch print(torch.__version__) # 打印PyTorch版本 print(torch.cuda.is_available()) # 验证CUDAGPU是否可用如果第二行打印出True那么恭喜你PyTorch已经成功识别并可以调用你的GPU了。如果打印False可能有以下几种情况你安装的是CPU版本的PyTorch。你的CUDA驱动或CUDA Toolkit没有正确安装。你的PyTorch版本与CUDA版本不匹配。此时你需要根据错误信息回头检查安装步骤。一个常见的验证CUDA本身是否可用的方法是在命令行尝试nvidia-smi命令是否能正常输出显卡信息。3. 核心概念拆解张量、自动求导与计算图现在环境准备好了让我们深入PyTorch的核心。理解这些概念比你记住十个API更重要。3.1 张量Tensor数据的唯一载体在PyTorch中一切数据都是张量。你可以把它理解为Numpy数组的超级升级版但它不仅能存数据还能“记住”自己是怎么来的为后面的自动求导打下基础。import torch import numpy as np # 从列表创建 data [[1, 2], [3, 4]] x_np np.array(data) # 这是一个NumPy数组 x_tensor torch.tensor(data) # 这是一个PyTorch张量 print(fNumPy array:\n{x_np}) print(fPyTorch tensor:\n{x_tensor}) print(fTensor shape: {x_tensor.shape}) # 形状和NumPy一样 print(fTensor dtype: {x_tensor.dtype}) # 数据类型如torch.float32张量可以存在于CPU或GPU上。这是PyTorch进行高速计算的基础if torch.cuda.is_available(): device torch.device(cuda) # 定义一个CUDA设备 x_gpu x_tensor.to(device) # 将张量移动到GPU print(x_gpu.device) # 输出: cuda:0.to(device)是切换设备的标准方法。在编写代码时一个最佳实践是定义设备变量所有张量和模型都显式地指定设备这样代码在CPU和GPU环境下都能运行。device torch.device(cuda if torch.cuda.is_available() else cpu) model MyModel().to(device) data data.to(device)3.2 自动求导AutogradPyTorch的“魔法”这是PyTorch区别于传统NumPy最革命性的特性。在机器学习中我们通过梯度下降法优化模型参数这就需要计算损失函数对每一个参数的梯度。手动计算梯度对于复杂网络是不可行的。Autograd系统自动为我们完成这件事。它是如何工作的当你创建一个张量并设置requires_gradTrue时PyTorch就开始跟踪track所有施加在这个张量上的操作形成一个计算图。# 假设我们的模型是 y w*x b x torch.tensor([1.0, 2.0, 3.0]) w torch.tensor(2.0, requires_gradTrue) # 需要计算梯度的参数 b torch.tensor(1.0, requires_gradTrue) y_pred w * x b # 前向传播 loss ((y_pred - (2*x 1))**2).mean() # 假设真实值也是 2x1计算均方误差 print(fLoss: {loss.item()}) # 此时计算图已经构建loss - y_pred - w, b现在调用loss.backward()PyTorch会沿着计算图反向传播自动计算出loss对w和b的梯度并将结果存储在w.grad和b.grad中。loss.backward() # 反向传播自动求导 print(fGradient of w: {w.grad}) # 输出: tensor(0.) print(fGradient of b: {b.grad}) # 输出: tensor(0.)为什么是0因为在这个简单的例子里我们的预测y_pred恰好等于假设的“真实值”所以损失为0梯度自然也为0。但这演示了流程。一个至关重要的细节在每次参数更新即执行optimizer.step()之前必须手动将梯度清零。因为梯度是累加的如果不清零下一次backward()时梯度会与上一次的梯度相加导致错误。optimizer.zero_grad() # 清零所有被优化参数的梯度 loss.backward() # 计算新梯度 optimizer.step() # 根据梯度更新参数忘记zero_grad()是新手常犯的错误会导致训练过程无法收敛或行为异常。4. 线性回归模型实战从零构建与训练理论说够了让我们动手。我们将用PyTorch完整实现一个线性回归模型并用人造数据训练它。这个过程会串联起之前讲的所有概念。4.1 第一步准备人造数据我们首先需要一些数据。为了演示我们生成一组有线性关系并添加了少量噪声的数据。import torch import matplotlib.pyplot as plt # 设置随机种子保证结果可复现 torch.manual_seed(42) # 生成特征数据 X: 100个样本每个样本1个特征 num_samples 100 X torch.randn(num_samples, 1) * 2 # 从标准正态分布采样并放大方差 # 定义真实的权重和偏置 true_w 3.5 true_b 2.0 # 生成标签数据 y并添加一些噪声 noise torch.randn(num_samples, 1) * 0.5 y true_w * X true_b noise print(fX shape: {X.shape}) # torch.Size([100, 1]) print(fy shape: {y.shape}) # torch.Size([100, 1]) # 可视化数据 plt.scatter(X.numpy(), y.numpy(), alpha0.6, labelData with noise) plt.plot(X.numpy(), (true_w * X true_b).numpy(), r-, labelTrue line, linewidth2) plt.xlabel(Feature X) plt.ylabel(Target y) plt.legend() plt.title(Synthetic Linear Regression Data) plt.show()这段代码生成了100个数据点。X是我们的输入特征y是目标值。红色的线是真实的、没有噪声的线性关系y 3.5 * X 2.0散点是我们模拟的带噪声的观测数据。我们的模型任务就是从这些散点中学习并逼近那条红线。4.2 第二步定义模型类在PyTorch中我们通过继承torch.nn.Module类来定义自己的模型。nn.Module是所有神经网络模块的基类它帮我们管理参数、提供钩子函数并确保参数能被正确转移到GPU。import torch.nn as nn class LinearRegressionModel(nn.Module): def __init__(self, input_dim, output_dim): super(LinearRegressionModel, self).__init__() # 定义网络层 self.linear nn.Linear(in_featuresinput_dim, out_featuresoutput_dim) # nn.Linear 层已经包含了权重(w)和偏置(b)参数 # 对于我们的例子input_dim1, output_dim1 def forward(self, x): # 定义前向传播即输入x如何经过各层得到输出 out self.linear(x) return out关键点解析__init__方法在这里定义模型的所有层。nn.Linear就是一个全连接层它完成了y x w.T b的计算。我们只需要指定输入和输出的维度它会自动创建并初始化可训练的权重参数w和偏置参数b。forward方法这是定义模型计算逻辑的地方。当调用model(X)时实际上就是在调用model.forward(X)。PyTorch的自动求导系统会记录forward方法中所有的运算构建计算图。初始化模型input_dim 1 output_dim 1 model LinearRegressionModel(input_dim, output_dim) print(model) # 输出 LinearRegressionModel( # (linear): Linear(in_features1, out_features1, biasTrue) # )我们可以查看模型的初始参数for param in model.parameters(): print(param.shape, param.data) # 输出两个张量 # torch.Size([1, 1]) tensor([[0.3367]]) # 权重 w # torch.Size([1]) tensor([0.1288]) # 偏置 b可以看到nn.Linear已经为我们初始化了随机的权重和偏置。这些参数就是模型要学习的东西。4.3 第三步配置损失函数与优化器模型定义好了我们需要告诉它两个事1. 怎么衡量预测的好坏损失函数2. 怎么根据这个衡量结果来改进自己优化器。# 1. 定义损失函数均方误差 (MSE)这是回归问题最常用的损失函数 criterion nn.MSELoss() # 2. 定义优化器随机梯度下降 (SGD) learning_rate 0.01 optimizer torch.optim.SGD(model.parameters(), lrlearning_rate) # 你也可以尝试其他优化器比如Adam它通常收敛更快对学习率不那么敏感 # optimizer torch.optim.Adam(model.parameters(), lrlearning_rate)nn.MSELoss()计算预测值和真实值之间差值的平方的均值。对于我们的线性回归问题它是最直接的选择。torch.optim.SGD随机梯度下降优化器。我们需要把模型的参数model.parameters()传给它它负责在反向传播后更新这些参数。lr是学习率是训练中最重要的超参数之一它控制着每次参数更新的步长。太大容易震荡不收敛太小则收敛太慢。4.4 第四步编写训练循环这是机器学习模型的“学习”过程是一个不断重复的循环前向传播 - 计算损失 - 反向传播 - 更新参数。num_epochs 100 # 整个数据集遍历100次 loss_history [] # 记录每轮的损失用于可视化 for epoch in range(num_epochs): # 将模型设置为训练模式某些层如Dropout、BatchNorm在训练和评估时行为不同 model.train() # 1. 前向传播用当前参数计算预测值 y_pred model(X) # 等价于 model.forward(X) # 2. 计算损失比较预测值和真实值 loss criterion(y_pred, y) # 3. 反向传播前的准备清空过往梯度 optimizer.zero_grad() # 4. 反向传播计算损失对每个参数的梯度 loss.backward() # 5. 更新参数优化器根据梯度更新参数 optimizer.step() # 记录损失 loss_history.append(loss.item()) # 每20轮打印一次损失 if (epoch 1) % 20 0: print(fEpoch [{epoch1}/{num_epochs}], Loss: {loss.item():.4f})逐行解读model.train()这是一个好习惯。虽然线性回归模型没有Dropout或BatchNorm层切换模式没影响但在复杂模型中这行代码至关重要。y_pred model(X)执行前向传播得到预测值。loss criterion(y_pred, y)计算当前预测的损失。optimizer.zero_grad()关键将优化器中所有参数的梯度缓存清零。如果不做这一步梯度会不断累积。loss.backward()PyTorch的Autograd系统沿着计算图反向传播计算loss对每个requires_gradTrue的参数的梯度结果存储在param.grad中。optimizer.step()优化器根据每个参数的梯度param.grad和学习率按照SGD的更新规则param param - lr * param.grad来更新参数。循环结束后我们可以绘制损失下降曲线观察模型是否在学习plt.plot(range(num_epochs), loss_history) plt.xlabel(Epoch) plt.ylabel(Loss (MSE)) plt.title(Training Loss Curve) plt.grid(True) plt.show()你应该会看到一条随着训练轮数增加而单调下降的曲线可能会有小幅波动。如果曲线不下降、爆炸变成NaN或剧烈震荡可能是学习率设置不当。4.5 第五步验证模型与参数提取训练完成后我们需要评估模型学得怎么样并查看它学到的参数是否接近我们预设的真实值w3.5, b2.0。# 将模型切换到评估模式虽然线性回归无影响但养成好习惯 model.eval() # 在评估模式下通常使用 torch.no_grad() 上下文管理器 # 它会禁用梯度计算节省内存和计算资源因为评估时不需要反向传播 with torch.no_grad(): # 用训练好的模型对原数据做预测 y_pred_eval model(X) # 计算评估集上的损失这里我们直接用训练集演示实际应使用未见过的测试集 final_loss criterion(y_pred_eval, y) print(fFinal loss on training data: {final_loss.item():.4f}) # 可视化拟合结果 plt.scatter(X.numpy(), y.numpy(), alpha0.6, labelOriginal data) plt.plot(X.numpy(), y_pred_eval.numpy(), g-, labelFitted line, linewidth3) plt.plot(X.numpy(), (true_w * X true_b).numpy(), r--, labelTrue line, linewidth2) plt.xlabel(Feature X) plt.ylabel(Target y) plt.legend() plt.title(Model Fitting Result) plt.show() # 提取学习到的参数 learned_w model.linear.weight.data.item() learned_b model.linear.bias.data.item() print(fLearned weight: {learned_w:.4f}, True weight: {true_w}) print(fLearned bias: {learned_b:.4f}, True bias: {true_b})model.eval()和torch.no_grad()在评估阶段是黄金搭档。model.eval()通知模型中的特定层如Dropout切换到评估行为torch.no_grad()则告诉PyTorch不要跟踪计算图极大提升推理速度并减少内存占用。最终绿色的“拟合线”应该非常接近红色的“真实线”并且学习到的w和b应该接近3.5和2.0。由于数据中有噪声完全一致是不可能的但应该非常接近。5. 关键技巧与深度解析让模型学得更好如果你只是照搬上面的代码你可能已经得到了一个不错的结果。但要真正掌握你需要理解背后的“旋钮”和“陷阱”。5.1 学习率训练中的“油门与刹车”学习率Learning Rate, LR可能是最重要的超参数。在上面的代码中我们简单地将lr设为0.01。但如果数据尺度变化这个值可能就不合适了。如何选择学习率太大如 lr1.0参数更新步伐太大可能会在最优解附近来回震荡甚至导致损失爆炸变成NaN。在损失曲线图上你会看到损失值上下剧烈跳动无法收敛。太小如 lr1e-6参数更新步伐太小收敛速度极慢可能需要训练成千上万轮才能达到一个较好的结果。损失曲线会缓慢下降但很久都降不到低点。经验值对于许多问题0.01、0.001、0.0001是常见的尝试起点。对于Adam优化器默认的0.001通常效果就不错。一个实用的技巧学习率调度Learning Rate Scheduler我们可以在训练过程中动态调整学习率例如在训练后期降低学习率以便更精细地逼近最优解。PyTorch提供了torch.optim.lr_scheduler。# 在定义优化器之后 optimizer torch.optim.SGD(model.parameters(), lr0.1) # 初始学习率可以设大一点 scheduler torch.optim.lr_scheduler.StepLR(optimizer, step_size30, gamma0.1) # 含义每训练30个epoch将学习率乘以0.1即降为原来的1/10 # 在训练循环中更新参数后调用 for epoch in range(num_epochs): # ... 前向传播、计算损失、反向传播 ... optimizer.step() scheduler.step() # 更新学习率 # ... 记录损失 ...使用调度器后损失曲线通常在前期快速下降后期平稳收敛。5.2 数据标准化加速收敛的“秘密武器”在我们的例子中X是从标准正态分布采样的均值为0标准差为1。但如果你的特征数据尺度差异很大比如一个特征是年龄0-100另一个特征是年薪0-1,000,000直接训练会导致模型对尺度大的特征更敏感收敛困难。解决方案标准化Standardization或归一化Normalization。最常用的是标准化将数据变换为均值为0、标准差为1的分布。# 假设 X_original 是原始数据 X_mean X_original.mean(dim0, keepdimTrue) X_std X_original.std(dim0, keepdimTrue) X_normalized (X_original - X_mean) / X_std # 用标准化后的数据 X_normalized 进行训练 # 注意在预测新数据时也需要用训练集的 mean 和 std 进行同样的变换对于线性回归数据标准化不仅能加速收敛有时还能提高模型的数值稳定性。torch.nn中也提供了nn.BatchNorm1d等层可以在网络内部进行归一化但对于输入数据手动标准化是一个简单有效的好习惯。5.3 批量训练与DataLoader处理大规模数据我们的例子中只有100个样本可以一次性放入模型这称为“批量梯度下降”。当数据量达到数万、数百万时内存可能无法容纳所有数据。这时我们需要小批量梯度下降Mini-batch Gradient Descent。PyTorch提供了torch.utils.data.DataLoader来帮我们优雅地处理批数据加载、打乱顺序等。from torch.utils.data import TensorDataset, DataLoader # 1. 将特征X和标签y包装成一个数据集 dataset TensorDataset(X, y) # 2. 创建数据加载器 batch_size 16 dataloader DataLoader(dataset, batch_sizebatch_size, shuffleTrue) # shuffleTrue 表示每个epoch开始时打乱数据顺序防止模型学习到数据顺序的偏差。 # 3. 修改训练循环 num_epochs 100 for epoch in range(num_epochs): model.train() running_loss 0.0 # 遍历数据加载器每次得到一个批次的数据 for batch_X, batch_y in dataloader: # 前向传播 y_pred model(batch_X) loss criterion(y_pred, batch_y) # 反向传播与优化 optimizer.zero_grad() loss.backward() optimizer.step() running_loss loss.item() * batch_X.size(0) # 累积损失注意乘以batch大小 # 计算这个epoch的平均损失 epoch_loss running_loss / len(dataset) loss_history.append(epoch_loss) if (epoch 1) % 20 0: print(fEpoch [{epoch1}/{num_epochs}], Loss: {epoch_loss:.4f})使用DataLoader后训练循环变成了两层外层循环遍历epoch内层循环遍历每个epoch中的批次batches。batch_size是另一个重要超参数通常选择2的幂次如32, 64, 128以适应GPU的并行计算特性。6. 模型保存、加载与推理训练一个好的模型可能需要很长时间。我们当然需要把训练好的模型保存下来以便后续使用或部署。6.1 保存与加载整个模型这是最简单的方法保存模型的结构和所有参数。# 保存模型 torch.save(model, linear_regression_model.pth) # 加载模型在另一个脚本或未来某个时间 loaded_model torch.load(linear_regression_model.pth) loaded_model.eval() # 别忘了切换到评估模式 # 使用加载的模型进行预测 with torch.no_grad(): sample_input torch.tensor([[1.5]]) # 注意保持维度: [batch_size, features] prediction loaded_model(sample_input) print(prediction)注意这种方法保存的模型文件包含了类定义。如果你在加载时原始的LinearRegressionModel类定义不在当前命名空间中加载可能会失败。因此更推荐下面只保存状态字典的方法。6.2 保存与加载状态字典推荐状态字典state_dict是一个Python字典它将模型的每一层映射到其参数张量。它不包含模型类本身更轻量也更灵活。# 保存状态字典 torch.save(model.state_dict(), linear_regression_state_dict.pth) # 加载状态字典 # 首先需要重新实例化一个结构相同的模型 new_model LinearRegressionModel(input_dim1, output_dim1) # 然后将保存的参数加载到这个新模型中 new_model.load_state_dict(torch.load(linear_regression_state_dict.pth)) new_model.eval() # 进行预测 with torch.no_grad(): prediction new_model(torch.tensor([[1.5]])) print(prediction)这是生产环境中更常用的方式因为它将模型架构代码和模型参数数据分离更符合软件工程的最佳实践。6.3 部署推理将模型应用于新数据训练和保存模型的最终目的是为了对新的、未见过的数据进行预测推理。def predict(model, input_data, feature_mean, feature_std): 使用训练好的模型进行预测。 假设训练时对输入数据进行了标准化这里需要做同样的处理。 model.eval() with torch.no_grad(): # 1. 将输入数据转换为张量 if not torch.is_tensor(input_data): input_tensor torch.tensor(input_data, dtypetorch.float32) else: input_tensor input_data # 2. 应用与训练时相同的标准化如果做了的话 # input_tensor_normalized (input_tensor - feature_mean) / feature_std # 这里我们假设没有做标准化所以直接使用 # 3. 确保输入维度正确 [batch_size, features] if input_tensor.dim() 1: input_tensor input_tensor.unsqueeze(0) # 从 [features] 变为 [1, features] # 4. 进行预测 prediction model(input_tensor) # 5. 如果对输出也做了变换这里需要逆变换 return prediction.numpy() # 返回NumPy数组方便后续处理 # 使用示例 new_x [[0.5], [2.0], [-1.0]] # 三个新样本 predictions predict(model, new_x, X_meanNone, X_stdNone) print(Predictions for new data:, predictions)这个predict函数封装了推理的标准流程切换到评估模式、禁用梯度、处理输入维度、进行预测、后处理输出。在实际项目中你可能会将这部分代码封装成一个独立的服务或API。7. 从线性回归到更广阔的世界下一步学什么恭喜你你已经用PyTorch成功构建、训练并评估了一个线性回归模型。这个简单的模型背后是PyTorch深度学习框架最核心、最通用的流程。现在你已经掌握了打开深度学习大门的钥匙。接下来你可以沿着这几个方向深入增加模型复杂度尝试将nn.Linear层堆叠起来中间加上nn.ReLU()这样的激活函数你就得到了一个简单的全连接神经网络。用它去解决MNIST手写数字分类问题你会立刻感受到“线性”到“非线性”的飞跃。探索不同的任务类型将损失函数nn.MSELoss()换成nn.CrossEntropyLoss()你就从回归问题进入了分类问题。这是图像识别、自然语言处理中最常见的任务类型。使用真实数据集告别人造数据。PyTorch的torchvision.datasets和torchtext.datasets模块提供了MNIST、CIFAR-10、IMDB等经典数据集用它们来训练你的模型挑战会真实得多。理解更深的机制深入研究DataLoader的多进程加载 (num_workers)学习使用TensorBoard或Weights Biases来可视化训练过程尝试自定义网络层和损失函数。记住所有复杂的模型如ResNet、Transformer其训练循环的本质都和你在本文中实现的这个简单循环一模一样前向传播、计算损失、反向传播、更新参数。你刚刚完成的正是所有深度学习项目的基石。
返回列表