简介这是一份面向深度学习初学者的PyTorch入门电子书由吴茂贵等著、机械工业出版社出版适合零基础或刚接触框架的开发者系统学习。内容从Numpy基础讲起逐步过渡到Tensor与Autograd、神经网络工具箱、数据处理工具再深入机器学习基础、卷积神经网络、循环神经网络与生成式深度学习最后以人脸检测识别和迁移学习等实践收尾对每个函数与用法均有细致讲解。资源包内共1个pdf文件大小约21.68MB即《Python深度学习基于PyTorch》完整电子版目录结构清晰便于按章节检索。目前已有5658人学习下载读者可借此掌握PyTorch核心API、经典网络实现与项目落地思路是入门与查漏补缺的实用参考。1. 从一本 PDF 到一套能跑的环境PyTorch 深度学习到底在学什么很多人拿到《Python深度学习基于PyTorch》这类资料第一反应是找配套代码第二反应是卡在环境上。真正让人放弃的往往不是反向传播而是torch.cuda.is_available()返回False或者conda install pytorch卡在 solving environment 半小时。这个标题背后其实是一条完整的链路Python 语法基础、PyTorch 张量操作、深度学习模型搭建、训练循环、GPU 加速最后落到 CNN、Transformer 这类具体结构上。它适合两类人一类是刚学完 Python 基础、想用 PyTorch 入门深度学习的开发者另一类是从 TensorFlow 或传统机器学习模型转过来需要快速对齐 PyTorch 写法的人。本文不逐页讲书而是把这条链路上最容易出问题的环节拆开环境怎么配、张量怎么理解、模型怎么搭、训练怎么调、GPU 怎么用起来。每一段都给出可复现的命令或代码参数含义和失败排查一并说清。2. PyTorch 环境搭建conda、pip 与 CUDA 版本怎么对齐2.1 为什么优先用 conda 而不是全局 pip深度学习环境最大的痛点是依赖冲突。全局 pip 装完 PyTorch过两天装个别的库把 numpy 升级了训练直接报错。conda 的价值在于环境隔离和二进制依赖管理尤其是 CUDA、cuDNN 这类非 Python 依赖conda 能一次性解决。常见做法是给每个项目建独立环境# 创建名为 dl 的环境指定 Python 3.10 conda create -n dl python3.10 -y conda activate dl # 查看当前环境列表确认激活成功 conda env list-n dl是环境名建议用项目名而不是pytorch这种通用名避免多个项目混用。python3.10是版本约束PyTorch 对 3.9 到 3.11 支持较好3.12 早期版本曾出现部分 wheel 缺失。激活后命令行前缀会变成(dl)这是判断是否激活成功的直接标志。2.2 安装 PyTorchCPU 版与 GPU 版的命令差异安装命令必须和你的 CUDA 驱动匹配。先查驱动支持的 CUDA 上限nvidia-smi输出右上角的CUDA Version是驱动支持的最高版本不是已安装版本。比如显示 12.4你可以装 cu121 或 cu118 的 PyTorch但不能装 cu124 以上的。CPU 版无独显或只想跑通代码pip install torch torchvision torchaudioGPU 版以 CUDA 11.8 为例pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118--index-url指定 PyTorch 官方 wheel 源比默认 PyPI 更全且能避免装到 CPU 版。torchvision管图像torchaudio管音频做 CV 和 NLP 时通常都要。安装完成后验证import torch print(torch.__version__) # 版本号 print(torch.cuda.is_available()) # True 表示 GPU 可用 print(torch.cuda.get_device_name(0)) # 显卡型号如果is_available()为 False先确认装的是 GPU 版版本号带cu118这类后缀再确认驱动版本够。两者都满足还不行重启终端或检查是否在正确的 conda 环境里。2.3 常见安装失败与排查路径现象可能原因处理方式solving environment 卡住conda 依赖求解慢改用 pip 装 PyTorchconda 只建环境下载速度极慢默认源在国外用官方 index-url或配置国内镜像is_available()为 False装了 CPU 版卸载后按 GPU 命令重装报CUDA out of memory显存不足减小 batch size或torch.cuda.empty_cache()版本号带cpu源选错检查--index-url是否漏写提示不要同时用 conda 和 pip 装同一个包混装是环境损坏的高频原因。建环境用 conda装 PyTorch 用 pip这条分工最稳。3. 张量与自动求导PyTorch 写法的地基3.1 Tensor 与 NumPy 的互操作及设备迁移PyTorch 的一切计算都建立在Tensor上。它和 NumPy 数组共享内存转换几乎零成本这是从传统机器学习模型转过来的人最容易上手的一点。import torch import numpy as np # NumPy 转 Tensor共享内存 a np.array([1.0, 2.0, 3.0]) t torch.from_numpy(a) t[0] 99 print(a) # a 也被改了说明共享 # Tensor 转 NumPy b t.numpy() # 迁移到 GPU if torch.cuda.is_available(): t_gpu t.to(cuda) print(t_gpu.device) # cuda:0from_numpy共享内存改一个另一个跟着变适合省内存但要注意副作用。.to(cuda)返回新张量原张量不动。设备不匹配是新手最常见的报错来源模型在 GPU、数据在 CPU就会报Expected all tensors to be on the same device。统一写法是在训练循环里对每个 batch 做.to(device)。3.2 autograd 的工作机制与 detach 的使用场景自动求导是 PyTorch 区别于 NumPy 的核心。设置requires_gradTrue后所有对张量的操作都会被记录成计算图调用.backward()自动算梯度。x torch.tensor([2.0], requires_gradTrue) y x ** 2 3 * x y.backward() print(x.grad) # 2*x 3 7x.grad存的是 dy/dx。注意梯度会累加每轮训练前必须optimizer.zero_grad()否则梯度越滚越大。推理或只想取值时用with torch.no_grad():它不建计算图省显存也更快。.detach()则是把张量从计算图里摘出来常用于把 loss 转成普通数值打印。3.3 用 nn.Module 搭一个最小可训练模型nn.Module是 PyTorch 组织模型的基类。一个最小全连接网络import torch.nn as nn class Net(nn.Module): def __init__(self): super().__init__() self.fc1 nn.Linear(784, 128) self.relu nn.ReLU() self.fc2 nn.Linear(128, 10) def forward(self, x): x self.relu(self.fc1(x)) return self.fc2(x) model Net() print(sum(p.numel() for p in model.parameters())) # 参数量__init__里声明层forward里定义数据流向。PyTorch 不要求显式定义反向传播autograd 自动完成。nn.Linear(784, 128)的 784 对应 28x28 图像展平128 是隐藏层宽度10 是分类数。参数量打印出来能帮你判断模型规模是否合理。4. 训练循环与 CNN 实战从数据加载到指标验证4.1 Dataset 与 DataLoader 的标准写法真实项目不会把全部数据读进内存。Dataset定义单条样本怎么取DataLoader负责批处理、打乱和多进程加载。from torch.utils.data import Dataset, DataLoader class MyDataset(Dataset): def __init__(self, data, labels): self.data data self.labels labels def __len__(self): return len(self.data) def __getitem__(self, idx): return self.data[idx], self.labels[idx] loader DataLoader(MyDataset(X, y), batch_size32, shuffleTrue, num_workers2)batch_size32是显存和梯度稳定性的折中显存小就降到 16 或 8。shuffleTrue只在训练集开验证集要关否则指标不可比。num_workers2开两个子进程读数据Windows 下有时需要设 0 避免报错。4.2 一个完整训练循环的六个必备步骤device torch.device(cuda if torch.cuda.is_available() else cpu) model Net().to(device) criterion nn.CrossEntropyLoss() optimizer torch.optim.Adam(model.parameters(), lr1e-3) for epoch in range(10): model.train() for x, y in loader: x, y x.to(device), y.to(device) optimizer.zero_grad() # 1 清梯度 out model(x) # 2 前向 loss criterion(out, y) # 3 算损失 loss.backward() # 4 反向 optimizer.step() # 5 更新 print(fepoch {epoch}, loss {loss.item():.4f}) # 6 记录顺序不能乱zero_grad必须在backward前step必须在backward后。lr1e-3是 Adam 的常用起点太大震荡太小收敛慢。loss.item()把张量转成 Python 浮点数避免显存里堆积计算图。4.3 CNN 结构设计与验证集评估图像任务用 CNN 比全连接更合理因为卷积能利用空间局部性。class CNN(nn.Module): def __init__(self): super().__init__() self.conv nn.Sequential( nn.Conv2d(1, 32, 3, padding1), nn.ReLU(), nn.MaxPool2d(2), nn.Conv2d(32, 64, 3, padding1), nn.ReLU(), nn.MaxPool2d(2), ) self.fc nn.Linear(64 * 7 * 7, 10) def forward(self, x): x self.conv(x) x x.view(x.size(0), -1) # 展平 return self.fc(x)Conv2d(1, 32, 3)表示输入 1 通道、输出 32 通道、卷积核 3x3padding1保持尺寸。两次MaxPool2d(2)把 28x28 降到 7x7所以全连接输入是64*7*7。x.view(x.size(0), -1)保留 batch 维、其余展平这是 CNN 接全连接层的固定动作。验证阶段model.eval() correct 0 with torch.no_grad(): for x, y in val_loader: x, y x.to(device), y.to(device) pred model(x).argmax(dim1) correct (pred y).sum().item() print(facc: {correct / len(val_dataset):.4f})model.eval()切换 BN 和 Dropout 的行为torch.no_grad()省显存。argmax(dim1)取每行最大值的下标作为预测类别。这两个开关漏掉任何一个验证指标都会失真。5. 显存、混合精度与模型保存的三个进阶技巧5.1 用 AMP 混合精度把 batch size 提上去显存不够时除了降 batch size还可以用自动混合精度。它让部分计算走 float16显存占用和速度都有改善。from torch.cuda.amp import autocast, GradScaler scaler GradScaler() for x, y in loader: x, y x.to(device), y.to(device) optimizer.zero_grad() with autocast(): out model(x) loss criterion(out, y) scaler.scale(loss).backward() scaler.step(optimizer) scaler.update()autocast自动决定哪些算子用半精度GradScaler防止半精度下梯度下溢。三步scale/step/update必须配套缺一个训练就会不稳定。这套写法在 CNN 和 Transformer 上都通用。5.2 保存与加载state_dict 而不是整个模型# 保存 torch.save(model.state_dict(), model.pth) # 加载 model CNN().to(device) model.load_state_dict(torch.load(model.pth, map_locationdevice)) model.eval()存state_dict只存参数文件小、跨设备兼容。存整个模型会把类定义路径也序列化换目录或改类名就加载失败。map_location让在 GPU 上存的权重能加载到 CPU反之亦然。5.3 排查 loss 不下降的四个检查点检查项具体动作学习率从 1e-3 降到 1e-4 试一轮数据标签打印几个 batch 的 x 和 y确认没对错梯度打印p.grad.norm()全为 0 说明图断了设备确认模型和数据在同一 device注意loss.backward()前如果对 loss 做了.item()或.detach()计算图就断了梯度永远是 None。这是最隐蔽的一类错误。最后一招是过拟合一个小样本取 10 条数据关掉 shuffle训练几十轮loss 应该趋近 0。如果连这都做不到问题一定在代码而不是数据或模型容量。这个自检能省掉大量盲目调参的时间。本文还有配套的精品资源点击获取