这套 PyTorch 深度学习实践的课程笔记到这里算是走完了一整轮从最开始张量的创建一直写到循环神经网络中间穿插了环境搭建、数据集加载、训练循环、卷积结构这些绕不开的环节。之所以最后要单独拿出一篇做目录与索引是因为前面每一篇都是独立成文的知识点之间的依赖关系散落在各自正文里学到后面想回头找某个函数或者某段参数设置翻起来相当费劲。这份索引要做的事情很明确把整条学习路线的章节顺序、每章的核心知识点、彼此之间的前置依赖还有真正容易卡住人的地方一次性摊开摆清楚。不管你刚装好环境准备入门还是已经写过几个小模型想系统补一遍底层逻辑都可以照这份索引安排自己的节奏。1. 这份索引为什么值得单独整理1.1 课程本身的定位与适合人群这套公开课最大的特点是把深度学习从调包拉回到手写的路上。它不会一上来就让你调用现成的高层接口跑一个图像分类而是先让你用最原始的循环去穷举权重、算损失、手动更新梯度把y w * x b这种简单到有点笨的模型跑通之后再一步步过渡到反向传播、多层网络、卷积和循环结构。主讲老师的风格很实在PPT 上写的公式不花哨但推导过程一步不落很适合那些学过一点线性代数和微积分、但完全没碰过神经网络的人。我建议把它的适合人群划成三类。第一类是本科阶段修过数学基础课、想补编程落地的学生这门课能把课本上的链式法则变成几行能跑的代码印象会深很多。第二类是转行做算法方向的人你可能看过《动手深度学习》这类成体系的教材但真上手写训练循环时还是会发懵这门课的手写推导正好补上这块。第三类是已经会用 PyTorch 搭模型、但说不清backward()到底做了什么的人回头做一遍手写梯度很多模糊的地方会突然清晰。值得注意的是这门课不是项目实战课。它不会教你写一个完整的工业级训练框架也不会讲分布式、混合精度这些工程话题。把它当成打地基的工具别指望学完就能直接上手做业务项目这是定位问题先拎清楚能省下不少纠结。1.2 整理索引的三个实际理由第一个理由是知识依赖链太长。这门课的顺序是刻意设计的张量基础不熟后面view、squeeze、permute这些维度变换就会卡线性模型里的梯度下降没搞懂反向传播那一节的loss.backward()就只是抄代码Dataset和DataLoader没吃透等到 CNN 和 RNN 阶段加载数据就全靠复制。整理一份带前置依赖的索引等于给自己画了一张路线图知道现在卡在哪一环、该回去补哪一节。第二个理由是复习检索效率。学到 RNN 的时候很多人会突然忘了nn.CrossEntropyLoss内部已经包含了 softmax或者忘了卷积输出尺寸的公式怎么算。如果每章笔记是独立的你得一篇篇翻。有了索引表直接定位到对应的知识点和公式几秒钟的事。这在我自己复习的时候帮助非常大尤其是隔了一两个月再回来看索引几乎就是救命的东西。第三个理由是项目复用。等你学完想自己搭一个小模型比如做一个手写数字识别或者简单的时序预测你需要快速把训练循环的标准骨架维度变换的常用组合损失函数和优化器的搭配这几块拼起来。索引里把这些可复用的代码块单独拎出来比重新翻视频快得多。2. 学习前必须打好的环境地基2.1 环境方案的选型对比环境这一步劝退的人比想象中多。方案大致有四种直接在本机装 Anaconda 再用 conda 装 PyTorch、用 pip 装、用云端平台、以及在 Windows 上装 WSL 子系统。我一个个说清楚取舍。本机 Anaconda conda 是最省心的组合尤其对新手。conda 能帮你把 Python 版本、PyTorch、CUDA 运行时这些依赖一次性理清环境之间互相隔离出问题直接删环境重来不污染系统。缺点是体积大、下载慢国内网络下 conda 源需要换镜像否则容易卡在求解环境那一步。pip 装更适合已经装了 Python、追求轻量的人。pip 装的包更干净速度也快但它不管理 Python 版本和非 Python 依赖装 GPU 版本时对 CUDA 版本匹配要自己盯。云端平台的好处是不用折腾驱动适合显卡不给力或者只是临时想跑几段代码的人缺点是免费额度有限、环境不持久学完课想长期用要考虑成本。WSL 这个方案我要多说一句。它本质是在 Windows 上跑一个 Linux 子系统好处是很多深度学习生态的教程和脚本默认面向 Linux命令行工具更齐全装环境踩的坑会少一些。代价是初次配置要花点时间磁盘和内存的分配也要调。如果你主力是 Windows 又有耐心这条路过一遍会有长期收益。选型这事没有标准答案我的建议是纯新手先用 Anaconda conda 把课跑通等上手了再考虑 WSL 或云端。别在选型上纠结太久环境是手段不是目的。2.2 装环境的具体步骤与验证以 conda 方案为例把步骤拆细。第一步去官网下 Anaconda 安装包Windows 下记得勾选把 conda 加入 PATH否则后面命令行找不到指令。装完之后开一个终端敲conda --version确认能用。第二步建一个专门的环境别往 base 里装东西conda create -n pytorch python3.10 conda activate pytorch这里的 Python 版本不要选太新3.10 或 3.11 兼容性最好太新的版本有时候对应的 PyTorch 轮子还没出。第三步装 PyTorch。CPU 版本和 GPU 版本命令不同GPU 版本需要先确认你的显卡驱动支持的 CUDA 版本用nvidia-smi看右上角显示的 CUDA Version。然后去 PyTorch 官网的安装选择器里选对应组合官方会自动生成命令比如# GPU 版本示例 conda install pytorch torchvision torchaudio pytorch-cuda12.1 -c pytorch -c nvidia # CPU 版本示例 conda install pytorch torchvision torchaudio cpuonly -c pytorch复制官方给的命令别自己手写版本号错一个数字就可能装上不匹配的组合。第四步验证。这一步千万别省import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else CPU only)cuda.is_available()返回True才说明 GPU 版本装对了。如果返回False八成是 CUDA 版本和驱动不匹配或者装成了 CPU 版本。注意换过 conda 镜像源之后如果装包报PackagesNotFoundError先检查源里有没有对应的 CUDA 版本包很多国内镜像同步不全。2.3 环境搭建的坑与检查清单环境这块的坑我踩得不少列几条高频的。第一个是装了 GPU 版本但is_available()是 False。原因通常是显卡驱动太旧或者 CUDA 运行时版本比驱动支持的高。解决办法是更新显卡驱动或者降一档 CUDA 版本重装。第二个是多个环境互相串。你明明在 pytorch 环境里装的东西运行时却报找不到很可能是平时用 IDE 的时候解释器选错了。在 PyCharm 或 VSCode 里要手动指定当前环境的 Python 路径别用系统的默认解释器。这个小细节至少让我的调试时间少了一半。第三个是conda 求解环境卡半小时。这是 conda 的依赖求解算法在大包集合上效率低导致的换libmamba求解器或者直接用 pip 装能缓解。实测下来装 PyTorch 这种大包pip 往往比 conda 快。第四个是磁盘空间不够。一个 conda 环境加上缓存几个 G 很正常装多了缓存能到十几个 G。定期跑conda clean -a清理缓存能省不少空间。我把环境检查整理成一张清单装完之后逐项过一遍检查项命令期望结果Python 版本python --version3.9 到 3.11 之间PyTorch 版本torch.__version__显示具体版本号CUDA 可用性torch.cuda.is_available()GPU 版为 True显卡型号torch.cuda.get_device_name(0)显示你的显卡名张量运算torch.randn(2,3).sum()能正常输出结果IDE 解释器IDE 内查看指向当前 conda 环境3. 课程主线内容的目录与索引拆解3.1 第一部分入门基础篇入门基础这一段的章节顺序是张量创建与运算、线性模型、梯度下降、反向传播、用 PyTorch 实现线性回归。核心思路是从纯手工逐步过渡到框架半自动。张量那几节重点讲的是数据怎么存、形状怎么读、常用创建函数有哪些像torch.Tensor、torch.zeros、torch.ones、torch.randn、torch.arange这些要熟练到闭着眼睛能写。线性模型那一节是整门课的第一个思维转折点。它让你用穷举法去找y w * x b里最优的 w 和 b具体做法是把 w 从某个范围里一格一格取对每个 w 算预测值和真实值的均方误差挑误差最小的那个。这个过程很笨但它把训练就是找让损失最小的参数这个核心观念刻进脑子里。很多人直接跳过这一节去学梯度下降结果对损失函数的理解始终是浮的。梯度下降那一节紧接着讲怎么用导数的方向去更新参数公式是w w - lr * grad。这里有两个必须记住的细节一是学习率不能太大也不能太小太大会震荡不收敛太小会走得极慢二是在 PyTorch 里梯度是累加的每轮更新前必须手动清零。反向传播那节引入链式法则把梯度从输出层往输入层逐层传回去代码上就是loss.backward()。到用 PyTorch 实现线性回归这一节你会看到前面手写的东西被nn.Linear、optim.SGD这些接口替代训练循环的骨架开始定型。3.2 第二部分神经网络与数据处理篇这一部分的章节是逻辑回归、多维输入的处理、Dataset 和 DataLoader、多分类与 Softmax、以及用 PyTorch 搭一个简单的多层网络。逻辑回归这一节是整个课程里我认为最值得反复看的一节因为它把为什么分类任务要用交叉熵而不是均方误差讲清楚了。具体来说逻辑回归的输出要经过 sigmoid 压缩到 0 到 1 之间如果这里还用均方误差损失函数会变得非凸、梯度容易消失训练效果很差。换成二分类交叉熵BCELoss之后梯度形式简洁很多收敛也快。这个知识点在后面多分类用CrossEntropyLoss时会再次出现而且CrossEntropyLoss内部已经包含了 softmax所以网络的最后一层不要再加 softmax这个坑非常多人踩。Dataset 和 DataLoader 这一节讲的是数据怎么进来。自定义数据集要继承Dataset实现__getitem__和__len__两个方法前者负责按索引取一条样本后者返回样本总数。然后用DataLoader包装指定batch_size、shuffle、num_workers这些参数。这里是后续所有项目的基础写不好这一步后面无论 CNN 还是 RNN 都会很难受。多维输入那一节讲的是特征从一维扩展到多维之后模型怎么从w*x变成矩阵乘法Wx。中间会涉及.view()改变形状、.squeeze()和.unsqueeze()增删维度这些操作这些操作我建议单独整理一份速查因为维度不匹配的报错几乎贯穿整门课。3.3 第三部分卷积神经网络实战篇进了 CNN 这几节内容一下子变得具体。章节大致是卷积层的原理与参数、池化层、用 GPU 加速训练、以及一个完整的卷积网络案例。卷积层的核心参数有三个输入通道数、输出通道数、卷积核大小另外还有 stride 和 padding。输出尺寸的计算公式必须记住我把它写在这里output (input - kernel 2 * padding) / stride 1这个公式是排查一切维度报错的基础。比如输入 28x28卷积核 3x3padding 取 1stride 取 1输出就是 (28 - 3 2) / 1 1 28尺寸不变。很多入门的人以为加了卷积核尺寸一定会变小其实 padding 可以保持尺寸这在深层网络里很关键。用 GPU 加速那一节会讲.to(device)的用法模型和数据都要搬到同一个设备上否则会报 Expected all tensors to be on the same device 这个经典错误。搬移的时机也有讲究数据最好在进入网络前搬到 GPU而不是在里面反复搬否则传输开销会吃掉加速的收益。完整的卷积网络案例一般会用手写数字识别这类数据集把卷积、池化、全连接串起来训练循环和前面线性模型的结构基本一致区别在于网络的 forward 里多了卷积和展平的操作。3.4 第四部分循环神经网络进阶篇RNN 这几节是课程的收尾难度也最高。章节包括RNN 的基本结构、LSTM 与 GRU、以及一个简单的时序任务。RNN 的核心是隐藏状态在时间步之间传递理解这个循环结构之后LSTM 的门控机制本质上是在解决长序列上梯度消失的问题GRU 则是 LSTM 的简化版。PyTorch 里用 RNN 有几个形状约定要记牢。默认情况下输入张量是 (seq_len, batch, input_size)隐藏状态 h0 是 (num_layers, batch, hidden_size)。如果加了batch_firstTrue输入就变成 (batch, seq_len, input_size)这个开关不设对报错同样全是维度问题。我建议一开始都用默认布局等熟悉了再看batch_first。到这里整门课的主线就闭环了从张量到线性模型从手写梯度到自动求导从全连接到卷积再到处理序列的循环结构。每一环都建立在前一环上索引表把这条链如实呈现出来复盘的时候按表过一遍基本不会漏。部分核心章节关键知识点前置依赖入门基础张量、线性模型、梯度下降形状、损失函数、参数更新基础 Python神经网络反向传播、逻辑回归链式法则、交叉熵入门基础篇数据处理Dataset、DataLoader__getitem__、批处理神经网络篇卷积网络卷积、池化、GPU 加速输出尺寸公式、设备一致数据处理篇循环网络RNN、LSTM、GRU隐藏状态、序列形状卷积网络篇4. 关键知识点的深挖与代码索引4.1 张量操作的易错点张量这块最先要分清楚的是创建张量和把数据转成张量这两件事。torch.tensor(data)是复制数据并推断类型torch.Tensor(data)是老式写法容易产生类型问题一般用后者构造再自己指定dtype更稳。torch.from_numpy(arr)则是共享内存改张量会改到原数组这点要留意。第二个易错点是形状的理解。一个 shape 为 (2, 3, 4) 的张量读法是两个 3x4 的矩阵第一维是最外层。view和reshape都改形状区别是view要求内存连续reshape不要求遇到报 view size is not compatible with input tensors size and stride 的时候换成reshape基本能解决。第三个是维度增删。unsqueeze(dim)在指定位置加一个长度为 1 的维度squeeze(dim)去掉它是unsqueeze的反操作。处理单样本的时候经常需要unsqueeze(0)模拟出一个 batch 维度因为网络通常按 batch 设计。第四个是广播机制。两个形状不同的张量做运算时PyTorch 会按规则自动扩展。这个特性很方便但也容易隐藏错误。比如你本意是矩阵乘法写成了*它按元素乘广播之后不报错结果却是错的。遇到结果诡异的情况先打印两个张量的 shape 核对。4.2 训练循环的固定骨架不管你后面用 CNN 还是 RNN训练循环的骨架是不变的。我把标准写法整理出来可以直接当模板model MyNet() criterion torch.nn.CrossEntropyLoss() optimizer torch.optim.SGD(model.parameters(), lr0.01) for epoch in range(num_epochs): model.train() for inputs, labels in train_loader: inputs, labels inputs.to(device), labels.to(device) optimizer.zero_grad() # 清空上一轮梯度 outputs model(inputs) # 前向 loss criterion(outputs, labels) loss.backward() # 反向 optimizer.step() # 更新参数 # 验证阶段 model.eval() with torch.no_grad(): # 计算验证集指标 pass这里有几处细节值得说。optimizer.zero_grad()必须在backward()之前否则梯度会一直累加。我在最开始学的时候忘了清零loss 看着往下走其实是假象模型参数乱跳。model.train()和model.eval()要成对出现因为 dropout 和 batch normalization 在训练和推理时行为不同忘了切换会导致验证结果失真。torch.no_grad()包住验证阶段能关掉自动求导省显存也更快。4.3 损失函数与优化器的搭配损失函数和优化器的选择其实有一套固定逻辑。回归任务用均方误差MSELoss二分类用BCELoss记得输入先过 sigmoid多分类用CrossEntropyLoss内部含 softmax最后别再加。这些搭配搞错模型要么不收敛要么结果完全对不上。优化器里SGD是最基础的配上 momentum 效果好很多常用参数是momentum0.9。Adam是另一个高频选项学习率一般设 1e-3收敛快但对最终精度有影响有些任务上不如调好的 SGD。学习率不是固定不变的可以在训练中途用lr_scheduler降下来常见的是每若干轮乘 0.1。这里有个经验如果 loss 一开始就震荡得很厉害先检查学习率是不是大了通常先从 0.01 或 1e-3 试起。如果 loss 降得很慢几乎不动可能是学习率太小也可能是数据没归一化。归一化这件事在做图像和序列任务时几乎是必须的把输入缩放到 0 到 1 或标准化到均值 0 方差 1能明显改善训练稳定性。5. 常见报错与排查技巧实录5.1 环境类报错环境类的报错里ModuleNotFoundError: No module named torch 出现的频率最高原因基本是解释器选错或环境没激活。先确认终端里conda activate过了再确认 IDE 里指定的解释器路径和终端用的是同一个。这两个都对了基本不会出现这个错误。另一个高频的是 CUDA 相关。报 CUDA out of memory 说明显存不够解决办法是调小 batch_size或者检查有没有张量被意外保留在计算图里。如果是 no kernel image is available for execution on the device那多半是 PyTorch 的 CUDA 版本和显卡算力不匹配需要重装匹配的版本。还有一种很隐蔽的现象是训练速度异常慢。如果is_available()返回 True 但训练比 CPU 还慢检查一下是不是把数据搬上 GPU 的位置放错了或者在循环里反复调用.item()导致频繁同步。数据搬运放在循环外或集体搬移能有效缓解。5.2 张量维度类报错维度类的报错是入门阶段最头疼的一类常见的几条我列在表里。报错信息常见原因解决思路size mismatch网络输出和标签形状不符打印两者 shape 核对expected input to have X channels通道数对不上检查 Conv2d 的 in_channelsview size is not compatible内存不连续改用 reshapeExpected all tensors on same device模型和数据设备不一致统一.to(device)mat1 and mat2 shapes cannot be multiplied全连接层输入维度错重算展平后的维度排查这类问题有个通用手法在报错位置前面加一句打印 shape 的代码看看进入这一层之前数据到底是什么形状。九成的维度错误都能靠这个定位。我养成了一个习惯写完一个新网络先用一个假输入跑一遍前向把每层输出形状打印出来确认无误再上真实数据。5.3 训练不收敛类问题模型能跑起来但 loss 不降这种情况比报错更磨人因为它不给你任何提示。我的排查顺序是这样的先看损失函数和任务类型是否匹配回归用 MSE、分类用 CE这个搞错必不收敛再看数据有没有归一化输入的范围过大或过小都会让梯度出问题然后看学习率从 1e-3 到 1e-2 之间调一调观察 loss 走势。如果前面都正常就要考虑网络结构本身。层数太深、激活函数选错、初始化不合理都会导致梯度消失或爆炸。入门阶段遇到这种情况先把网络做浅做小跑通了再逐步加深度。还有一个小技巧先用一个极小的数据集比如几十条样本去训如果连这个小数据集都过拟合不了说明网络或训练逻辑有硬伤先解决这个再上全量数据。6. 学习节奏与复习方法6.1 时间分配与推进节奏这门课的内容密度不算低我的建议是每个大章节留出两到三天的消化时间而不是一天刷好几集。张量和线性模型这两块各花一天梯度下降和反向传播至少要两天因为这两节是整门课的分水岭理解到位的标志是你能不看笔记推一遍链式法则并用代码实现。逻辑回归和 Dataset 这两节也是各一到两天动手把数据加载流程写一遍比单纯看视频有用得多。CNN 和 RNN 这两部分内容多、涉及的新概念也多每一部分可以留出一周。这段时间不要只是跟着视频敲代码最好是看完之后关掉笔记自己从头搭一遍卡住了再回去翻。这个合上笔记重写一遍的过程是检验有没有真学会的唯一标准。我第一遍学的时候照着视频敲完感觉都懂第二遍脱离视频自己写卡在维度变换上卡了一个多小时那次卡壳之后才真的记住了。6.2 笔记维护与索引更新笔记不是写一遍就完了索引更是要持续维护。我的做法是每学完一节用三到五行把这一节的核心问题、关键代码和踩过的坑记下来放进对应章节的索引里。这样一来越到后面越轻松因为回头看的时候搜索成本接近零。维护笔记还有一个好处是能暴露知识盲区。有些内容你以为懂了真要写清楚为什么这一步要这样的时候就写不出来这说明理解还停在表面。把写不出来的地方标记出来回去补这比漫无目的地重看视频高效得多。这套索引本身也是这么一点点堆出来的每补一篇正文就更新一次目录最后自然形成一条完整的路线。我自己在长期使用这套课的过程中最大的体会是别追求看完要追求能复现。看完了课不等于学会了能合上所有资料从零把一个模型搭起来、跑通、调好才算真正掌握。这份索引存在的意义说到底就是让这个复现的过程有迹可循卡在哪一环能立刻定位到对应的知识点。真正动手的时间越多这份索引对你的价值就越大。