ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

深度学习小白速通:从Python环境搭建到MNIST推理实战

深度学习小白速通:从Python环境搭建到MNIST推理实战 深度学习入门基本绕不开 Python。不管是 PyTorch、TensorFlow还是各种开源模型库、训练脚本和部署代码大多数第一手资料都用 Python 写。很多小白真正卡住的地方其实不是算法有多难而是环境装不对、语法没入门、手里没有一个能跑起来的项目。这篇文章不打算带你把 Python 从头学一遍也不打算堆一堆神经网络公式。我会按“环境 - 语法 - 小项目 - 推理”这个顺序帮你快速跑通一个深度学习最小闭环。适合编程基础薄弱、刚想进入深度学习、还不确定该装什么工具的人。我的核心建议只有一个不要先写 300 行代码也不要先啃 300 页书。先花一个晚上把环境装好再花一个晚上跑通手写数字识别你会比看 30 节视频更有感觉。1. 学 Python 不是背语法而是先跑通一个深度学习小项目1.1 为什么小白入门深度学习先学 PythonPython 在深度学习领域基本是默认语言。PyTorch、TensorFlow、scikit-learn、NumPy、Pandas 这些常用库第一优先提供的接口几乎都是 Python。社区里分享的训练代码、模型示例、部署项目绝大多数也是 Python 脚本。Python 的语法相对直白读起来像描述步骤写起来不需要关心内存回收、指针类型这类底层概念。这一点对深度学习入门很关键因为你的注意力应该放在模型结构、数据、训练结果上而不是被语言细节拖住。还有一个实际原因深度学习的学习资料有大量“半成品”需要你自己运行、修改、观察结果。如果只会看 TensorFlow 或 PyTorch 的简介而不懂 Python 基本语法就很难调试一个报错脚本。反过来说只要会一点 Python你就能读懂大部分开源模型代码哪怕不知道每个函数的具体实现。所以入门深度学习选 Python 不是因为它最先进而是因为它帮你省掉大量工程成本让你有机会把时间花在理解模型、跑通实验、分析结果上。1.2 入门路线最常见的误区只学语法不跑项目我见过很多新手第一周先买语法书第二周开始看视频第三周还在学列表、字典、文件读写。结果一个月过去了连一个神经网络都没跑起来。原因很简单把 Python 当成了目标本身而不是工具。深度学习中真正需要的 Python 语法量没有想象的那么大。你不需要精通装饰器、元类、多线程你更需要的是变量、容器、循环、函数、类、导入模块以及 NumPy 数组的基本操作。这些内容一个周末就够用。正确路线应该是装好 Python 和编辑器。掌握能写小脚本的基础语法。跑一个最小的深度学习项目比如 MNIST 手写数字识别。出现报错就去查查询过程中自然补上对 Python 的理解。很多人在第三步就停了因为环境问题太多或者觉得自己的 Python 还不够熟。我的建议是一边学一边跑先把最小闭环打通。跑通一个真实项目后你会发现之前零散的语法知识会自动串联起来。2. 第一台“深度学习环境”怎么搭Python 安装、虚拟环境与编辑器2.1 安装 Python 与验证环境配置是小白入坑的第一个大障碍但也是性价比最高的一步因为这步做对了后面基本不会再因为“不知道装了什么”而焦虑。Windows 用户直接去 python.org 下载安装包版本选最新稳定版即可。安装时一定记得勾选“Add Python to PATH”不勾的话后面在命令行输入 python 会提示找不到命令。安装完成后打开命令提示符执行这条命令验证python --version如果输出类似Python 3.12.x说明安装成功。macOS 用户可以用 Homebrew 安装brew install python3然后验证python3 --versionLinux 用户更简单Ubuntu 24.04 这类系统通常会自带 Python 3也可以直接用包管理器补充sudo apt update sudo apt install python3 python3-pip验证时注意Windows 上常见命令是pythonLinux 和 macOS 上可能是python3。如果执行python和python3得到不同结果说明系统里可能存在多个 Python 版本。这不是大问题但自己心里要有数你当前用的是哪个 Python。2.2 虚拟环境与依赖管理我强烈建议新手安装 Python 后先学会创建虚拟环境。虚拟环境不是可选的高级技巧而是避免依赖冲突最基础的手段。实际工作中常遇到这种情况项目 A 需要 PyTorch 2.0项目 B 需要 PyTorch 1.13两个版本共存很容易出现诡异报错。用虚拟环境可以让每个项目运行在自己独立的 Python 空间里互不干扰。创建虚拟环境只需要两步。先在项目目录下执行python -m venv venv然后激活环境Windows 命令提示符venv\Scripts\activateWindows PowerShellvenv\Scripts\Activate.ps1Linux / macOSsource venv/bin/activate激活后命令行提示符前面通常会出现(venv)后面再用pip install安装的包都会装进这个环境里。安装依赖常用pip install numpy如果下载速度不理想可以配置国内 PyPI 镜像源但要注意镜像源更新可能比官方源稍慢。遇到“找不到这个版本”的时候可以先切回官方源确认。管理依赖还有一个好习惯把当前环境的所有包导出到requirements.txtpip freeze requirements.txt换机器或重新配环境时执行pip install -r requirements.txt这样就能让项目依赖保持一致。2.3 编辑器与运行工具VSCode 和 Jupyter 怎么选深度学习入门阶段写代码的方式一般有两种VSCode 写脚本Jupyter Notebook 做探索。VSCode 是目前最主流的编辑器安装 Python 扩展后可以实现代码补全、调试、运行单个 Python 文件。新手需要做的配置很少安装 VSCode。安装 Python 扩展。用命令面板选择一个 Python 解释器一般选你刚创建的venv环境。写一个test.py点右键运行。Jupyter Notebook 更适合边写代码边看结果。你可以把“读取数据 - 查看图片 - 训练一个小模型 - 看结果”拆成多个单元格每次只运行一个单元格中间结果直接显示在页面里。对图像处理、数据分析、模型实验来说体验很好。很多老手会把两者结合Jupyter 做实验VSCode 写正式脚本。新手不用追求复杂配置能运行文件、能看到报错信息就行。我踩过的坑是这样的装完 Python 后直接打开 VSCode发现import torch报错一看解释器选的是系统全局 Python而不是虚拟环境里的 Python。这个报错排查起来很迷惑但本质就是解释器选错了。3. Python 速通小白只需要掌握的 6 个核心知识点3.1 变量、容器与循环深度学习中Python 代码大多是“处理数据 调用模型”真正需要手写的控制逻辑其实不多。最常用的语法包括变量、列表、字典、for 循环、函数、类、import。变量不需要声明类型直接赋值batch_size 32 epochs 5 learning_rate 0.001列表和字典是数据处理里的高频容器labels [0, 1, 2, 3] # 列表遍历 for label in labels: print(label) # 字典保存配置 config { batch_size: 32, epochs: 5, } print(config[batch_size])如果数据是“某个类别的图片路径列表”字典就很方便dataset { train: [img1.jpg, img2.jpg], val: [img3.jpg], }for 循环配合range也是训练代码里最常见的for epoch in range(5): print(epoch, epoch)这里要理解range生成的是从 0 开始的整数序列所以range(5)会输出 0 到 4。很多新手在这里容易混淆“epoch 值”和“epoch 次数”后面看训练日志时就会发懵。3.2 函数、类与模块函数的作用是封装重复逻辑。比如计算模型准确率写成函数后可以反复调用def compute_accuracy(preds, labels): correct (preds labels).sum().item() total len(labels) return correct / total类的作用更像定义模板。在 PyTorch 里模型通常定义成一个类新手只需要看懂基本结构__init__里放模型层forward里写数据如何流过这些层。import torch.nn as nn class SimpleNet(nn.Module): def __init__(self): super().__init__() self.fc nn.Linear(784, 10) def forward(self, x): return self.fc(x)你可能会发现深度学习里的“模型”本质上就是一个 Python 对象。你调用model(x)时它内部会执行forward。这个逻辑和普通 Python 类没有区别。模块导入也很简单import torch import numpy as np from torch import nn只要记住一点如果代码里用到某个库第一步先确认已经安装第二步确认导入路径正确。报错时第一反应别怀疑模型写错了先看导入是否成功。3.3 NumPy 是深度学习的最底层数据结构深度学习中最底层的数据结构不是 Python 列表而是张量。张量听起来很高级但你可以先把它理解成“多维数组”而 NumPy 的ndarray就是这个概念的经典实现。Minimal 示例import numpy as np arr np.zeros((2, 3)) print(arr.shape) # (2, 3)深度学习中经常会把图片读成 NumPy 数组形状是(H, W, C)。把多张图片堆叠成批量数据形状是(B, H, W, C)。对数组做归一化、缩放、转置。新手需要重点掌握四个操作shape、reshape、sum、mean。后面所有数据预处理基本都围绕这些展开。arr np.random.rand(4, 784) print(arr.shape) reshaped arr.reshape(4, 28, 28) print(reshaped.mean())PyTorch 里的torch.Tensor和 NumPy 数组很相似很多函数名称也一样。你先掌握 NumPy 后再看 PyTorch 数据操作会顺畅很多。4. 用 PyTorch 训练一个手写数字识别模型4.1 构造数据与模型环境搭好、基础语法也扫了一遍之后就可以跑第一个真正意义上的深度学习项目了。我建议选 MNIST 手写数字识别原因很直接数据小、任务简单、训练快、资料多。MNIST 数据集是 28x28 的灰度图内容是 0 到 9 的手写数字训练集有 6 万张测试集有 1 万张。用 PyTorch 加载 MNIST 非常简单。第一次运行会下载数据之后会缓存到本地目录import torch from torch import nn from torch.utils.data import DataLoader from torchvision import datasets, transforms transform transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ]) train_dataset datasets.MNIST(root./data, trainTrue, transformtransform, downloadTrue) test_dataset datasets.MNIST(root./data, trainFalse, transformtransform, downloadTrue) train_loader DataLoader(train_dataset, batch_size64, shuffleTrue) test_loader DataLoader(test_dataset, batch_size64, shuffleFalse)这里有两个细节值得理解。第一ToTensor()会把图片从(H, W)的 PIL 图像转成形状为(C, H, W)的 Tensor并把像素值从 0 到 255 缩放到 0 到 1。深度学习模型通常需要输入范围稳定这样训练更平稳。第二Normalize((0.1307,), (0.3081,))是 MNIST 数据集的均值和标准差把数据从 0 到 1 再标准化到接近 0 附近。后续推理时如果直接用摄像头拍的数字图片也要做同样的预处理否则模型效果会明显下降。模型结构不需要复杂一个最简单的全连接网络就能做 MNISTmodel nn.Sequential( nn.Flatten(), nn.Linear(28 * 28, 128), nn.ReLU(), nn.Linear(128, 10), )Flatten把 28x28 的图片拉平成 784 维向量两个线性层负责把 784 维映射到 10 类。中间的 ReLU 给模型加入非线性能力没有它两层线性叠加等价于一层表达能力会弱很多。4.2 训练循环损失、优化器、epoch模型定义好之后还需要三样东西损失函数、优化器、训练循环。损失函数用来衡量模型预测和真实标签之间的差距。MNIST 是分类任务最常用的是交叉熵损失criterion nn.CrossEntropyLoss()优化器负责更新模型参数。新手可以先从 Adam 开始它对学习率的敏感度相对低容易跑出不错的结果optimizer torch.optim.Adam(model.parameters(), lr0.001)学习率lr0.001是常见默认值。调大可能收敛更快但容易震荡调小更稳但训练时间变长。遇到 loss 不下降时优先检查学习率是否设得有问题。训练循环的骨架如下model.train() for epoch in range(3): total_loss 0 for images, labels in train_loader: optimizer.zero_grad() outputs model(images) loss criterion(outputs, labels) loss.backward() optimizer.step() total_loss loss.item() print(fepoch {epoch}, loss: {total_loss / len(train_loader):.4f})这里每一步都有意义optimizer.zero_grad()清空上一次计算的梯度。如果不清空梯度会累加参数更新方向就错了。outputs model(images)前向传播让数据流过网络得到预测结果。loss.backward()反向传播计算每个参数对 loss 的梯度。optimizer.step()用梯度更新参数。对于 MNISTCPU 上跑 2 到 3 个 epoch 通常已经能看到明显的 loss 下降。要注意这里说的“通常”取决于你的硬件、PyTorch 版本和数据下载状态。第一次跑建议用小batch_size64不要一上来就开最大并发或者改大 batch。如果电脑有 NVIDIA GPU你可以在代码里加一个设备判断device torch.device(cuda if torch.cuda.is_available() else cpu) model model.to(device)然后把 images 和 labels 也放到device上images, labels images.to(device), labels.to(device)没有 GPU 也可以先跑 CPU 版本MNIST 足够小训练时间不夸张。4.3 验证与测试怎么看模型有没有学会训练完模型之后必须在测试集上评估不能在训练集上一看 loss 很低就结束。这是一个新手最容易忽视的步骤。模型可能在训练数据上表现很好但遇到没见过的数据就崩溃这个现象就是过拟合。测试评估代码model.eval() correct 0 total 0 with torch.no_grad(): for images, labels in test_loader: images, labels images.to(device), labels.to(device) outputs model(images) _, predicted torch.max(outputs, 1) total labels.size(0) correct (predicted labels).sum().item() accuracy correct / total print(ftest accuracy: {accuracy:.4f})这里有两个关键点。第一model.eval()会把模型切换到推理模式。像 Dropout、BatchNorm 这类层在训练和推理时的行为不同。如果不写这一步某些模型在测试时结果会不稳定。第二torch.no_grad()会关闭梯度计算。推理阶段不需要反向传播关闭后可以降低显存占用并提升速度。MNIST 这个任务比较简单按照上面的默认设置跑几个 epoch 后测试准确率通常能到 95% 以上但具体数值会受随机种子、学习率、训练轮数影响。如果你第一次跑只有 90%也不用急着怀疑代码先多跑几个 epoch 看趋势。模型训练好后保存权重torch.save(model.state_dict(), mnist_model.pth)之后推理时再加载model.load_state_dict(torch.load(mnist_model.pth)) model.eval()这套“训练 - 保存 - 加载 - 测试”的流程是后面所有深度学习项目的基础。5. 训练之后还要会推理从 CPU 到 GPU精度格式怎么选5.1 推理和训练有什么区别很多人训练完模型就以为结束了真正做项目时才发现推理阶段才是问题高发区。训练和推理的主要区别有三点。第一训练要反向传播所以要保存中间激活值和梯度显存占用高得多。推理只需要前向传播显存占用小但也需要注意模型本身的大小和 batch_size 是否过大。第二训练关心收敛效果推理更关心延迟、吞吐和稳定性。同一个模型可能训练时不在乎几十毫秒但推理时每张图多 20 毫秒批量跑 10 万张图就会差很多。第三推理流程往往要处理真实输入而不是已经预处理好的数据集。比如你做数字识别项目用户上传的图片可能是任意尺寸、任意背景、任意亮度你不能直接把 28x28 的模型逻辑套上去。常见做法是先对图像做缩放、灰度化、二值化再送入模型。推理的基础代码很简单model.eval() with torch.no_grad(): output model(image_tensor)但真正落地时需要注意输入图片是否做了和训练时一样的预处理。batch_size 是多少会不会导致显存或内存溢出。输出结果如何映射成类别标签比如argmax。日志里能不能看到每条输入对应的输出方便排查。5.2 fp32、fp16、bf16、tf32 到底怎么选训练和推理绕不开一个问题浮点数格式。很多新手看到 fp32、fp16、bf16、tf32 就懵了其实它们只在描述同一个问题的不同选择模型参数和中间计算用多少位二进制来存小数。先说 fp32也就是 32 位单精度浮点数。它是深度学习的默认精度训练时最稳数值范围大精度也够。缺点是占显存内存最多计算速度相对较慢。fp16 是 16 位半精度浮点数显存占用只有 fp32 的一半计算速度明显更快。但 fp16 的动态范围小数值容易溢出特别是计算 loss 或梯度时可能出现inf或nan。在支持 Tensor Core 的 NVIDIA GPU 上混合精度训练既保留 fp32 的主权重又用 fp16 加速计算能兼顾速度和稳定。bf16 是 bfloat16同样 16 位但它保留了和 fp32 相近的动态范围只是精度更低。它不容易出现溢出问题训练和推理都比较稳。很多大模型训练使用 bf16因为数值稳定性比 fp16 好。tf32 是 TensorFlow 里常见的一个精度选项准确说它是 NVIDIA Ampere 及以上架构 GPU 的 Tensor Core 加速模式用截断的 fp32 输入来计算综合了性能与精度。它不完全等价于 fp16但在某些框架里可以通过配置来启用。一个简单对比表格格式位数动态范围精度常见用途fp3232大高训练默认、稳定性要求高的任务fp1616小中Tensor Core 加速、混合精度训练bf1616接近 fp32较低大模型训练、长尾数值场景tf32基于 fp32裁剪接近 fp32中Ampere 架构 GPU 加速选型时我的建议是刚入门时先无脑用 fp32先保证结果正确。训练大模型时优先看 bf16尤其当 loss 出现nan可能是 fp16 溢出了。推理追求吞吐时再换 fp16 或 bf16但必须验证输出质量和精度损失。tf32 不是所有框架默认开启需要根据实际框架设置开启。这里要特别提醒低精度能跑通不代表输出质量一定会降低但也不代表一定不会降低。不管用哪种格式都建议用几条典型样本对比 fp32 和低精度结果确认误差在可接受范围内再决定是否上线。5.3 批量推理、接口化与日志排查模型训练好、精度格式也确定后下一步往往是把模型用到真实任务里。最常见的是批量处理图片比如需要识别 1000 张数字图片。批量推理时不要一次把所有图片全部塞进内存。更稳妥的做法是先读一张图确认预处理流程无误。用一个小批量比如 32 或 64跑一次推理。观察显存或内存占用。再考虑分批处理记录每批的成功和失败情况。批量推理代码可以这样组织image_paths [img1.jpg, img2.jpg, ...] batch_size 32 results [] for i in range(0, len(image_paths), batch_size): batch_paths image_paths[i:i batch_size] try: batch_tensors [preprocess(path) for path in batch_paths] batch torch.stack(batch_tensors) with torch.no_grad(): preds model(batch) results.extend(preds.argmax(dim1).tolist()) except Exception as e: print(fbatch {i} failed: {e}) continue这里把日志和异常捕获加上是批量任务稳定运行的关键。很多新手只看“最后有没有结果”却忽略了中间某几张图可能失败。排查推理问题时我一般按这个顺序先看有没有报错报错信息是什么。再看输入图片路径、格式、尺寸、是否损坏。继续看预处理是否和训练一致均值方差是否匹配。再看模型加载的权重路径是否正确是否切换到了eval模式。最后看 batch_size 是否太大导致显存或内存溢出。一个典型场景昨天模型还能跑今天报维度错误。大概率不是模型坏了而是今天输入图片尺寸不对或者预处理环节少了resize。真正跑落地项目时输入数据的格式和路径比模型本身更容易出错。另外保存推理结果的命名也要提前设计好。如果输出文件重名后面的结果会直接覆盖前面的。简单做法是在输出名里加上原始文件名或时间戳。这些细节看起来不起眼但批量跑几千张图时没有规范命名会非常痛苦。结尾先把最小闭环跑稳再想下一步小白学深度学习最怕的是目标太大、起步太重。与其纠结“我 Python 还不够熟”“环境还没配好”“理论还没看完”不如先跑通一个 MNIST 手写数字识别。我的建议是先用 CPU 跑通训练和测试代码。再尝试加 GPU观察速度变化和显存占用。然后替换成自己的图片走一遍推理流程。最后再考虑换数据集、换模型结构、学习混合精度和部署优化。踩过几次坑之后你会发现很多问题不是工具能力不够而是前置环境和输入数据没有处理干净。浮点数格式、batch_size、虚拟环境、预处理一致性、批量推理的日志这些才是真正影响项目能否落地的细节。把最小闭环跑稳后面学任何模型都会有底气。
返回列表