资讯动态

PyTorch 32页样章实战:训练循环、DataLoader与回归项目

发布时间:2026/10/23 5:10:09 来源:尧图企业网站定制
简介这份资源是《Deep Learning with PyTorch》官方样章PDF面向希望入门PyTorch与深度学习实践的开发者、学生及算法爱好者帮助读者在正式购书前了解全书结构与核心内容。压缩包内仅含1个PDF文件大小约399KB内容为英文原版样章涵盖训练循环构建、训练统计收集、tqdm进度报告、DataLoader与Dataset使用以及一个完整的回归模型项目包括数据集描述、模型搭建、训练与预处理优化等关键环节。样章还包含免责声明、版权说明与目录预览便于读者判断内容深度与学习路径。目前已有138人浏览学习适合作为PyTorch实战入门的轻量级参考通过样章中的项目示例可快速理解深度学习模型训练的主要步骤与数据预处理思路为后续系统学习打下基础。1. 一份只有 32 页的 PyTorch 样章为什么值得先跑一遍如果你手上正拿着这份deep-learning-with-pytorch-sample.pdf第一反应大概是才 32 页目录里却列了训练循环、回归项目、DataLoader 与 Dataset 这些硬核主题能讲透吗我一开始也这么想。但翻完目录和前言后判断变了——它不是一本“从零讲数学”的教材而是一份把 PyTorch 工程链路拆成可执行片段的样章。作者在前言里明确说不需要线性代数、概率统计的深厚基础先动手把模型跑起来再按需补理论。这个定位对已经会 Python、想快速上手 PyTorch 做回归或分类的开发者非常友好。样章里出现的tqdm训练进度、DataLoader批处理、回归模型预处理都是真实项目里绕不开的环节。下面我按“能干什么、怎么跑、怎么改”把这份样章拆开讲。2. 样章内容拆解从训练循环到 DataLoader 的工程链路2.1 训练循环的四个必备元素样章第 8 章标题是 “Creating a Training Loop for Your Models”目录里列了四个子项训练元素、收集统计、用 tqdm 报告进度、延伸阅读。虽然正文只有样章片段但按 PyTorch 项目的常见做法一个最小可用的训练循环一定包含这几步前向传播、计算损失、反向传播、参数更新。我一般会把它写成下面这种结构方便后面加验证和日志import torch import torch.nn as nn from tqdm import tqdm # 假设 model、train_loader、optimizer 已定义 criterion nn.MSELoss() # 回归任务常用均方误差 model.train() # 切换到训练模式影响 Dropout/BatchNorm for epoch in range(num_epochs): running_loss 0.0 # 用 tqdm 包住 DataLoader进度条直接显示在终端 loop tqdm(train_loader, descfEpoch {epoch1}/{num_epochs}) for batch_X, batch_y in loop: optimizer.zero_grad() # 清空上一轮梯度否则会累加 outputs model(batch_X) # 前向传播 loss criterion(outputs, batch_y) loss.backward() # 反向传播计算梯度 optimizer.step() # 更新参数 running_loss loss.item() loop.set_postfix(lossloss.item()) # 进度条右侧实时显示 loss avg_loss running_loss / len(train_loader) print(fEpoch {epoch1} average loss: {avg_loss:.4f})这段代码里几个参数值得注意optimizer.zero_grad()必须放在前向之前否则梯度会跨 batch 累积model.train()和后面的model.eval()要成对出现否则 Dropout 和 BatchNorm 行为不一致tqdm的set_postfix是样章里提到的“报告训练进度”的常见做法比单纯 print 更直观。样章还强调“收集统计”实际项目里我会把每个 epoch 的 loss、学习率、耗时写进列表最后统一画曲线而不是只靠终端输出。2.2 回归项目的预处理为什么能提分样章第 12 章是一个完整的回归项目目录里明确写了“Building a Model and Train”和“Improving the Model with Preprocessing”。这说明作者想传达一个工程习惯先跑通基线再加预处理。回归任务里最常见的预处理是标准化StandardScaler或归一化MinMaxScaler因为不同特征的量纲差异会让梯度下降走得很慢。我一般会这样组织from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split import numpy as np import torch # 假设 X 是特征矩阵y 是目标值 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42 ) scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) # 只在训练集上 fit X_test_scaled scaler.transform(X_test) # 测试集用同样的均值方差 # 转成 PyTorch 张量注意回归目标通常是 float32 X_train_t torch.tensor(X_train_scaled, dtypetorch.float32) y_train_t torch.tensor(y_train.values, dtypetorch.float32).view(-1, 1)这里的关键点是fit_transform只用在训练集测试集必须用transform否则数据泄露会让评估结果虚高。样章把“预处理改善模型”单独列一节说明作者踩过这个坑。另外view(-1, 1)是把目标变成二维因为 PyTorch 的MSELoss要求输入输出形状一致很多新手会在这里报形状不匹配的错。2.3 DataLoader 与 Dataset 的分工样章第 18 章专门讲 DataLoader 和 Dataset目录里问了 “What is DataLoader?” 并演示了在训练循环里使用以及用 Dataset 类创建迭代器。我的理解是Dataset 负责“一条数据怎么取”DataLoader 负责“一批数据怎么组”。自定义 Dataset 必须实现__len__和__getitem__常见写法如下from torch.utils.data import Dataset, DataLoader class TabularDataset(Dataset): def __init__(self, X, y): self.X torch.tensor(X, dtypetorch.float32) self.y torch.tensor(y, dtypetorch.float32).view(-1, 1) def __len__(self): return len(self.X) # 告诉 DataLoader 总共多少条 def __getitem__(self, idx): return self.X[idx], self.y[idx] # 返回单条特征和标签 dataset TabularDataset(X_train_scaled, y_train.values) loader DataLoader(dataset, batch_size32, shuffleTrue, num_workers0)batch_size决定一次梯度更新用多少条数据太小则训练不稳定太大则显存吃紧shuffleTrue在训练集上必须开验证集和测试集要关num_workers在 Windows 上建议设 0否则容易卡在子进程启动。样章把 DataLoader 放在训练循环之后讲顺序很合理——先知道循环里要什么再学怎么高效喂数据。3. 把样章跑起来环境、依赖与最小复现步骤3.1 环境准备与依赖安装样章前言里写得很清楚所有教程都能在普通 CPU 工作站上完成GPU 不是必须的。这对没有显卡的开发者很友好。我一般会先建一个干净的虚拟环境避免和系统里的包打架python -m venv pytorch-sample-env source pytorch-sample-env/bin/activate # Windows 用 pytorch-sample-env\Scripts\activate pip install torch torchvision numpy scikit-learn tqdm这里torch和torchvision是核心numpy用于数据转换scikit-learn提供预处理和数据集划分tqdm是样章明确提到的进度条库。如果你用的是 conda也可以conda install pytorch numpy scikit-learn tqdm -c pytorch。安装完在 Python 里跑import torch; print(torch.__version__)确认版本样章没有指定具体版本号但建议用 1.10 以上因为tqdm和DataLoader的 API 在旧版本里略有差异。3.2 从样章目录反推最小可跑脚本样章正文只有片段但目录给了足够线索。我按第 8、12、18 章的标题拼了一个最小回归训练脚本你可以直接复制到一个.py文件里跑import torch import torch.nn as nn from torch.utils.data import Dataset, DataLoader from sklearn.datasets import make_regression from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from tqdm import tqdm # 1. 造一份回归数据模拟样章里的数据集 X, y make_regression(n_samples1000, n_features10, noise0.1, random_state42) X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state42) scaler StandardScaler() X_train scaler.fit_transform(X_train) X_test scaler.transform(X_test) # 2. 自定义 Dataset class RegressionDataset(Dataset): def __init__(self, X, y): self.X torch.tensor(X, dtypetorch.float32) self.y torch.tensor(y, dtypetorch.float32).view(-1, 1) def __len__(self): return len(self.X) def __getitem__(self, idx): return self.X[idx], self.y[idx] train_loader DataLoader(RegressionDataset(X_train, y_train), batch_size32, shuffleTrue) test_loader DataLoader(RegressionDataset(X_test, y_test), batch_size32, shuffleFalse) # 3. 定义模型 model nn.Sequential( nn.Linear(10, 64), nn.ReLU(), nn.Linear(64, 32), nn.ReLU(), nn.Linear(32, 1) ) criterion nn.MSELoss() optimizer torch.optim.Adam(model.parameters(), lr1e-3) # 4. 训练循环带 tqdm 进度条 for epoch in range(50): model.train() loop tqdm(train_loader, descfEpoch {epoch1}) for batch_X, batch_y in loop: optimizer.zero_grad() loss criterion(model(batch_X), batch_y) loss.backward() optimizer.step() loop.set_postfix(lossloss.item()) # 5. 测试集评估 model.eval() with torch.no_grad(): total_loss 0 for batch_X, batch_y in test_loader: total_loss criterion(model(batch_X), batch_y).item() print(fTest MSE: {total_loss / len(test_loader):.4f})这个脚本把样章里训练循环、回归项目、DataLoader 三条线串起来了。跑通后你会看到进度条和 loss 下降测试 MSE 通常在 0.01 量级。如果 loss 不降先检查StandardScaler是否只 fit 了训练集再看学习率是不是太大。3.3 训练过程统计与 tqdm 的实用参数样章第 8 章专门有一节 “Collecting Statistics During Training”我习惯在训练循环里额外记录每个 epoch 的平均 loss 和耗时方便后面判断是否过拟合import time history {loss: [], time: []} for epoch in range(50): start time.time() model.train() epoch_loss 0.0 loop tqdm(train_loader, descfEpoch {epoch1}, leaveFalse) for batch_X, batch_y in loop: optimizer.zero_grad() loss criterion(model(batch_X), batch_y) loss.backward() optimizer.step() epoch_loss loss.item() loop.set_postfix(lossf{loss.item():.4f}) avg_loss epoch_loss / len(train_loader) history[loss].append(avg_loss) history[time].append(time.time() - start) print(fEpoch {epoch1}: loss{avg_loss:.4f}, time{history[time][-1]:.2f}s)tqdm的leaveFalse让每个 epoch 的进度条结束后消失避免终端刷屏set_postfix里的 loss 保留四位小数方便肉眼观察震荡。样章提到用 tqdm 报告进度但没有展开参数这些是我在实际项目里调出来的习惯。如果你发现 loss 突然变成nan大概率是学习率太大或者数据里有异常值先查StandardScaler之后的数值范围。4. 避坑与排查样章里没写但一定会遇到的 5 个问题4.1 现象训练 loss 不下降一直卡在某个值原因通常是学习率过大或过小或者数据没有标准化。样章在回归项目里专门用一节讲预处理说明作者知道这个坑。解决方法是先把学习率调到1e-3或1e-4再确认StandardScaler是否只 fit 了训练集。如果还是不动打印一个 batch 的输入看看数值范围超过几百的量纲基本都要标准化。4.2 现象RuntimeError: expected scalar type Float but found Double原因很常见sklearn返回的数组是float64而 PyTorch 默认用float32。样章没有显式写 dtype但所有 PyTorch 项目都会遇到。解决方法是在torch.tensor里加dtypetorch.float32或者用.float()转换。我一般在 Dataset 的__init__里统一转避免后面每个 batch 都报错。4.3 现象DataLoader在 Windows 上卡住或报BrokenPipeError原因是num_workers大于 0 时Windows 的子进程启动方式和 Linux 不同。样章没有提平台差异但这是血泪经验。解决方法是在 Windows 上把num_workers设为 0或者把训练代码放在if __name__ __main__:里面。如果你在 Jupyter Notebook 里跑num_workers也只能是 0。4.4 现象测试集 loss 远高于训练集 loss原因是过拟合或者测试集预处理用了不同的 scaler。样章把“预处理改善模型”单独列出来暗示了这一点。解决方法是先确认scaler.transform而不是fit_transform用在测试集上再加 Dropout 或减小模型参数量。如果训练集 loss 很低但测试集很高优先查数据泄露而不是急着调模型。4.5 现象tqdm进度条不显示或输出乱码原因是终端不支持\r回车或者tqdm被其他 print 打断。样章推荐用 tqdm 报告进度但没讲兼容性。解决方法是在循环里避免混用print或者给tqdm加filesys.stdout。在 Jupyter 里用from tqdm.notebook import tqdm代替普通 tqdm显示效果更好。5. 二次开发把样章模板改成自己的项目样章最大的价值不是那 32 页文字而是它给出了一套可复制的工程骨架Dataset 定义数据接口DataLoader 管批处理训练循环管梯度更新tqdm 管进度预处理管提分。你要做二次开发第一步是把第 3 章那个最小脚本里的make_regression换成自己的数据源。如果是 CSV用pandas.read_csv读进来把类别特征做 one-hot数值特征做标准化然后塞进同一个RegressionDataset类。第二步是改模型结构样章用的是全连接网络如果你做图像把nn.Linear换成nn.Conv2d和nn.MaxPool2d做时间序列换成nn.LSTM。第三步是改损失函数回归用MSELoss二分类用BCEWithLogitsLoss多分类用CrossEntropyLoss。这三步走完样章里的训练循环和 DataLoader 几乎不用动。我一般还会加两个改造点。一是把训练循环里的history字典存成 JSON方便后面画曲线对比不同超参数二是用torch.save(model.state_dict(), model.pth)保存权重样章第 3 部分目录里提到了 “Save and Load Your PyTorch Models”虽然样章正文没展开但这是必加的一步。验证方法很简单加载权重后跑一遍测试集MSE 和保存前一致就说明没存错。改造点样章对应章节改动位置验证方式换数据源第 12 章回归项目Dataset 的__init__打印一个 batch 的形状换模型第 8 章训练循环nn.Sequential内部前向传播不报错换损失第 8 章训练元素criterion定义loss 能正常反向传播存权重第 3 部分目录训练结束后加载后测试 MSE 一致从那以后我每次拿到一份新样章或新模板都强制先跑通最小脚本再动一行改一行绝不一次性大改。这份 PyTorch 样章虽然只有 32 页但目录里的训练循环、回归项目、DataLoader 三条线足够撑起一个可运行的项目骨架。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑