ARTICLE DETAIL

资讯详情

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

深度学习入门实战:从PyTorch环境搭建到CNN与Transformer模型部署

深度学习入门实战:从PyTorch环境搭建到CNN与Transformer模型部署 深度学习入门这件事最容易死在第一步不是数学太难而是环境还没搭好就崩了。PyTorch 装不上、CUDA 版本对不上、模型一跑就 OOM这些问题比“反向传播为什么这样计算”更早来敲门。所以这篇内容不整虚的直接从 Python 环境开始把神经网络、CNN、Transformer 的原理、代码、实战和排查一起过一遍目标是让你今天晚上就能在本地跑通第一个深度学习模型。整个路线设计成“能跑起来”优先。不追求用数学公式把自己劝退而是先用代码建立手感再回头补原理。全文围绕三件事展开环境怎么搭、模型怎么训、结果怎么用。代码基于 Python 和 PyTorch兼顾 CPU 和 GPU兼容常见个人电脑。无论你是刚学过 Python 语法、还是只会写几个爬虫脚本都能按这一套流程走完。很多初学者喜欢直接去看 Transformer 论文结果看到 Multi-Head Attention 就卡住了。我的建议是先跳过复杂推导直接跑一个 10 行代码的 Transformer 分类器先记住输入输出格式再反推内部结构。这比抱着论文啃三天更有效。1. 核心能力速览能力项说明面向人群Python 基础薄弱、想系统入门深度学习的开发者编程语言Python推荐框架PyTorch 2.x可按需使用 TensorFlow核心主题环境搭建、神经网络、CNN、Transformer、项目实战硬件要求CPU 可入门GPU 可加速训练显存越大越好典型任务手写数字识别、图像分类、文本分类训练方式单机训练先小参数跑通再放大部署方式本地推理脚本、FastAPI 服务、ONNX 导出批量任务支持批量预测通过脚本或队列处理学习边界以理解和跑通为主不深入数学推导这里给一个明确的心理预期入门阶段 4GB 显存够不够够。如果你不训练大模型只做 MNIST、CIFAR-10、小规模 CNN绝大多数电脑都能扛住。如果你准备训练更大模型建议先看显卡驱动和 CUDA 版本再决定安装哪个 PyTorch 版本。显存占用取决于模型参数、batch size 和输入分辨率同一个模型在不同机器上的占用可能差很多所以别在意别人报出来的“7G”或“11G”以你自己运行时的实际输出为准。2. 适用场景与学习边界这套内容适合谁刚学完 Python 基础不知道下一步学什么的同学。做数据分析、爬虫、后端开发想转 AI 落地的人。学校课程太偏理论想亲手跑通深度学习模型的本科生。需要把图像分类、文本分类做成 Demo 或内部工具的工程师。它能帮你解决什么问题搭建一套可复用的深度学习开发环境。理解神经网络、CNN、Transformer 的核心概念和代码写法。完成图像分类、文本分类两类典型任务。把训练好的模型封装成接口给其他程序调用。它不适合什么场景如果你想让模型直接达到商业级精度这部分内容只是起点还需要调参、数据扩充、大规模训练。如果你完全没有 Python 语法基础建议先花两周把变量、循环、函数、类、列表、字典过一遍。如果你期望一个晚上学会所有数学推导不现实。我们更推荐“先跑通再补理论”的方式。另外必须提醒边界问题。深度学习实践过程中会用到数据集、预训练模型、第三方代码。对于公开数据集要注意数据集的许可协议对于 Hugging Face 等平台上的预训练模型要注意模型许可证是否允许商用如果你处理的是人脸、声音、医疗等敏感数据必须确保数据来源合法并对模型输出做人工复核。任何涉及版权、隐私、肖像权的内容都不建议在没有授权的情况下直接商用。3. 环境准备与前置条件3.1 软件清单推荐使用 Windows 10/11 或 Ubuntu 20.04/22.04/24.04 作为主力系统。macOSApple Silicon也能跑但有些 GPU 加速功能受限。这里以 Windows 和 Linux 为主。Python建议使用 3.9 到 3.11安装包统一由 conda 管理。包管理器Miniconda 或 Anaconda推荐 Miniconda更轻量。深度学习框架PyTorch版本以官网为准。开发环境VSCode Python 插件或者 Jupyter Lab。辅助工具Git、nvidia-smiNVIDIA 驱动自带。3.2 硬件要求入门阶段对硬件要求不高。CPU支持 AVX 指令集的普通 x86_64 处理器即可。内存8GB 起步16GB 更舒服。GPUNVIDIA GeForce GTX 1050 Ti 及以上都能跑入门实验。CPU 训练也能跑通只是慢一些MNIST 全连接网络在纯 CPU 上几分钟也能完成一个 epoch。磁盘至少预留 20GB包括 conda 环境、PyTorch、数据集和输出文件。如果你的机器没有 NVIDIA GPU不用慌先用 CPU 版本跑通所有代码。后续需要再租云 GPU。TensorFlow 用户也可以参考同样的环境思路只是安装命令不同。3.3 需要提前掌握的知识不建议先去啃《深度学习》花书你可以先掌握这些 Python 技能使用 numpy 创建数组、做矩阵运算。使用 matplotlib 简单画图。定义 Python 类理解__init__和forward方法。会用pip或conda安装包。能读懂torch.Tensor的基本操作.shape、.view()、.unsqueeze()。如果你已经具备这些基础可以直接进入环境搭建。4. 安装部署与启动方式4.1 创建虚拟环境建议每个项目建一个独立环境避免包版本冲突。# 创建 Python 3.10 环境 conda create -n dl python3.10 -y # 激活环境 conda activate dlWindows 下激活命令相同。如果你没有 conda也可以用python -m venv但 conda 在管理 CUDA 相关包时更省心。4.2 安装 PyTorch打开 PyTorch 官网的 Get Started 页面选择系统、包管理方式、CUDA 版本会自动生成安装命令。CPU 版安装示例# CPU 版本Windows/Linux 通用 pip install torch torchvision torchaudioGPU 版安装示例CUDA 12.1# 具体版本号以官网为准 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121安装完成后验证环境python -c import torch; print(torch.__version__); print(torch.cuda.is_available())如果输出 PyTorch 版本号并且torch.cuda.is_available()返回True说明 GPU 可用。返回False也不代表失败CPU 模式同样能跑。4.3 安装 Jupyter Lab 和 VSCodepip install jupyterlab启动jupyter lab或者直接用 VSCode 打开项目文件夹并选择dl环境作为 Python 解释器。下面所有代码都可以在 Jupyter Notebook 或.py文件中运行。4.4 下载数据集PyTorch 的torchvision会自动下载 MNIST、CIFAR-10 等公开数据集。如果下载慢可以手动下载后放到本地目录也可以通过设置TORCH_HOME环境变量修改缓存目录。# Linux/macOS export TORCH_HOME$HOME/.cache/torch # Windows PowerShell $env:TORCH_HOME D:\torch_cache这样数据集会统一存放在指定目录方便迁移和复用。5. 功能测试与效果验证5.1 跑通第一个神经网络MNIST 手写数字识别MNIST 是深度学习的 Hello World。训练一个全连接神经网络把 28x28 的灰度图分成 10 类0-9。先导入必要模块import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader from torchvision import datasets, transforms # 超参数 batch_size 64 epochs 5 learning_rate 0.001数据加载transform transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ]) train_dataset datasets.MNIST(root./data, trainTrue, downloadTrue, transformtransform) test_dataset datasets.MNIST(root./data, trainFalse, downloadTrue, transformtransform) train_loader DataLoader(train_dataset, batch_sizebatch_size, shuffleTrue) test_loader DataLoader(test_dataset, batch_sizebatch_size, shuffleFalse)定义模型class MLP(nn.Module): def __init__(self): super().__init__() self.fc1 nn.Linear(28*28, 256) self.fc2 nn.Linear(256, 128) self.fc3 nn.Linear(128, 10) self.relu nn.ReLU() def forward(self, x): x x.view(x.size(0), -1) x self.relu(self.fc1(x)) x self.relu(self.fc2(x)) x self.fc3(x) return x训练函数device torch.device(cuda if torch.cuda.is_available() else cpu) model MLP().to(device) criterion nn.CrossEntropyLoss() optimizer optim.Adam(model.parameters(), lrlearning_rate) for epoch in range(epochs): model.train() total_loss 0 correct 0 total 0 for images, labels in train_loader: images, labels images.to(device), labels.to(device) optimizer.zero_grad() outputs model(images) loss criterion(outputs, labels) loss.backward() optimizer.step() total_loss loss.item() _, predicted outputs.max(1) total labels.size(0) correct predicted.eq(labels).sum().item() print(fEpoch {epoch1}/{epochs}, Loss: {total_loss/len(train_loader):.4f}, Acc: {100.0 * correct / total:.2f}%)验证效果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 outputs.max(1) total labels.size(0) correct predicted.eq(labels).sum().item() print(fTest Accuracy: {100.0 * correct / total:.2f}%)这段代码跑通后你就完成了第一个完整的深度学习训练流程。判断成功的标准很简单训练 Loss 持续下降测试准确率达到 90% 以上。如果准确率很低先检查数据预处理是否用了 Normalize学习率是否设置过大。5.2 神经网络中的几个核心概念刚才的 MLP 里用到了一些必须搞懂的概念。nn.Linear全连接层作用是把输入特征线性变换到输出维度内部有权重矩阵和偏置项bias。ReLU激活函数给网络引入非线性。深度学习中很多任务不能只用线性变换否则多层网络等价于一层。CrossEntropyLoss交叉熵损失分类任务常用的目标函数。optimizer.zero_grad()清空梯度。PyTorch 的梯度会累加不清空会导致训练异常。model.train()和model.eval()切换训练/推理模式影响 Dropout 和 BatchNorm 的行为。很多人困惑“神经网络中 biases 是什么”。简单说偏置是线性变换中的常数项让模型在输入全为 0 时也能有非零输出增强拟合能力。在 PyTorch 里nn.Linear默认使用 bias如果不需要可以传biasFalse。5.3 CNN 实战CIFAR-10 图像分类CNN卷积神经网络适合图像任务因为卷积可以提取局部特征参数数量远小于全连接网络。同样使用 PyTorch先加载 CIFAR-10import torchvision.transforms as T transform_cifar T.Compose([ T.Resize((32, 32)), T.ToTensor(), T.Normalize((0.4914, 0.4822, 0.4465), (0.2470, 0.2435, 0.2616)) ]) train_set datasets.CIFAR10(root./data, trainTrue, downloadTrue, transformtransform_cifar) test_set datasets.CIFAR10(root./data, trainFalse, downloadTrue, transformtransform_cifar) train_loader DataLoader(train_set, batch_size64, shuffleTrue, num_workers2) test_loader DataLoader(test_set, batch_size64, shuffleFalse, num_workers2)定义一个小型 CNNclass SimpleCNN(nn.Module): def __init__(self): super().__init__() self.conv1 nn.Conv2d(3, 32, kernel_size3, padding1) self.conv2 nn.Conv2d(32, 64, kernel_size3, padding1) self.pool nn.MaxPool2d(2, 2) self.fc1 nn.Linear(64 * 8 * 8, 256) self.fc2 nn.Linear(256, 10) self.relu nn.ReLU() def forward(self, x): x self.pool(self.relu(self.conv1(x))) x self.pool(self.relu(self.conv2(x))) x x.view(x.size(0), -1) x self.relu(self.fc1(x)) x self.fc2(x) return x训练代码与 MNIST 很像只需把模型替换为SimpleCNN()。CIFAR-10 比 MNIST 难5 个 epoch 后准确率可能只有 60%-70%这是正常的。想提高精度可以增加 epoch、使用数据增强、引入 BatchNorm 和 Dropout。CNN 训练中最常遇到的陷阱是输入尺寸不匹配。CIFAR-10 输入是 32x32经过两次 MaxPool2d 后尺寸变成 8x8所以全连接层的输入必须是64 * 8 * 8。如果你改了输入尺寸这里的维度也要跟着改。5.4 Transformer 入门不用复现论文先跑通文本分类Transformer 现在是大模型的基础也是“为什么最后是 Transformer”这个问题的答案。但入门不需要从零复现 Multi-Head Attention我们可以直接用 PyTorch 内置的TransformerEncoder做一个简单文本分类器先理解输入输出。这里使用一个非常小的“玩具”例子随机生成整数序列预测序列中最大值是奇数还是偶数。这个任务本身没什么实际意义但它能让你看到 Transformer 在序列数据上的工作方式。import torch import torch.nn as nn import torch.optim as optim import random from torch.utils.data import TensorDataset, DataLoader def generate_data(num_samples, seq_len, vocab_size100): xs [] ys [] for _ in range(num_samples): seq [random.randint(1, vocab_size) for _ in range(seq_len)] xs.append(seq) ys.append(1 if max(seq) % 2 0 else 0) return torch.tensor(xs), torch.tensor(ys) seq_len 16 x, y generate_data(1000, seq_len) dataset TensorDataset(x, y) loader DataLoader(dataset, batch_size32, shuffleTrue)定义简化版 Transformer 分类器class ToyTransformerClassifier(nn.Module): def __init__(self, vocab_size100, d_model64, nhead4, num_layers2, num_classes2): super().__init__() self.embedding nn.Embedding(vocab_size, d_model) encoder_layer nn.TransformerEncoderLayer(d_modeld_model, nheadnhead, batch_firstTrue) self.transformer nn.TransformerEncoder(encoder_layer, num_layersnum_layers) self.fc nn.Linear(d_model, num_classes) def forward(self, x): x self.embedding(x) # [batch, seq_len, d_model] x self.transformer(x) # [batch, seq_len, d_model] x x.mean(dim1) # 全局平均池化 x self.fc(x) return x训练循环与前面类似model ToyTransformerClassifier() criterion nn.CrossEntropyLoss() optimizer optim.Adam(model.parameters(), lr0.001) for epoch in range(10): total_loss 0 for xs, ys in loader: xs xs.long() optimizer.zero_grad() outputs model(xs) loss criterion(outputs, ys) loss.backward() optimizer.step() total_loss loss.item() print(fEpoch {epoch1}, Loss: {total_loss/len(loader):.4f})这里的关键理解点nn.Embedding把离散 token 映射成稠密向量。TransformerEncoderLayer由 Multi-Head Attention 和 Feed-Forward 组成。输入形状是[batch_size, seq_len]输出形状是[batch_size, seq_len, d_model]分类时通常取mean或第一个 token 位置。跑通后你就能理解 Transformer 的基本数据流。之后再看《Attention Is All You Need》会轻松很多。5.5 模型训练中的浮点数问题热词里提到的 fp32、fp16、bf16、tf32是做训练和部署时必须了解的概念。fp32单精度浮点深度学习默认精度训练最稳定。fp16半精度显存占用减半但精度范围小容易溢出。bf16BFloat16范围与 fp32 接近适合大模型训练。tf32NVIDIA Ampere 架构上 Tensor Core 的一种计算格式用于加速精度介于 fp32 和 fp16 之间。在 PyTorch 中启用混合精度可以使用torch.cuda.ampscaler torch.cuda.amp.GradScaler() with torch.cuda.amp.autocast(): outputs model(images) loss criterion(outputs, labels) scaler.scale(loss).backward() scaler.step(optimizer) scaler.update()这能在绝大多数 GPU 上减少显存占用并加快训练。但入门阶段先用 fp32 把逻辑跑通再考虑混合精度。部署时onnx 导出也可以选择 fp16能显著减小模型体积但精度可能略有下降需要验证。6. 接口 API 与批量任务模型训练完不能只在 Notebook 里看效果要能给别人调用。这里展示一个最简 FastAPI 服务如果来不及装 FastAPI也可以直接写一个 Python 脚本批量推理。6.1 批量推理脚本假设你已经把训练好的 CNN 保存为model_cnn.pth可以写一个批量预测函数import torch from torchvision import datasets, transforms from torch.utils.data import DataLoader def predict_batch(model, dataloader, device): model.eval() predictions [] with torch.no_grad(): for images, _ in dataloader: images images.to(device) outputs model(images) _, preds outputs.max(1) predictions.extend(preds.cpu().tolist()) return predictions # 加载测试集 transform transforms.ToTensor() test_set datasets.CIFAR10(root./data, trainFalse, downloadTrue, transformtransform) test_loader DataLoader(test_set, batch_size32, shuffleFalse) # 加载模型需要先保持模型结构一致 # model SimpleCNN() # model.load_state_dict(torch.load(model_cnn.pth)) # preds predict_batch(model, test_loader, torch.device(cuda))批量处理时建议将输入数据按目录整理使用torchvision.datasets.ImageFolder读取。对大量图片做预测时可以增加batch_size提高吞吐但要注意显存上限。6.2 FastAPI 部署示例先安装pip install fastapi uvicorn创建app.pyimport io import torch from PIL import Image from torchvision import transforms from fastapi import FastAPI, UploadFile, File app FastAPI() device torch.device(cuda if torch.cuda.is_available() else cpu) # 这里换成你的模型 # model SimpleCNN().to(device) # model.load_state_dict(torch.load(model_cnn.pth)) # model.eval() transform transforms.Compose([ transforms.Resize((32, 32)), transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2470, 0.2435, 0.2616)) ]) app.post(/predict) async def predict(file: UploadFile File(...)): image_bytes await file.read() img Image.open(io.BytesIO(image_bytes)).convert(RGB) tensor transform(img).unsqueeze(0).to(device) with torch.no_grad(): outputs model(tensor) _, pred outputs.max(1) return {prediction: int(pred.item())} if __name__ __main__: import uvicorn uvicorn.run(app, host127.0.0.1, port8000)启动python app.py测试接口curl -X POST -F filetest.png http://127.0.0.1:8000/predict接口返回 JSON{ prediction: 3 }注意示例代码中模型加载部分被注释实际使用需要替换成你自己的模型路径并保持类定义一致。如果服务只在本机使用host建议保持127.0.0.1避免暴露到局域网。6.3 导出 ONNX 用于部署ONNX 可以跨框架部署导出示例dummy_input torch.randn(1, 3, 32, 32).to(device) torch.onnx.export( model, dummy_input, model_cnn.onnx, input_names[images], output_names[logits], dynamic_axes{images: {0: batch}, logits: {0: batch}} )如果你接触“深度学习模型部署”onnx 之后还可以用 ONNX Runtime 或 TensorRT 加速但那是另一个话题。先把导出跑通后续再深入研究。7. 资源占用与性能观察训练时怎么观察资源占用GPU 显存命令行输入nvidia-smi可以看到每个进程占用显存。在 Windows 上可用nvidia-smi.exe。CPU 和内存任务管理器Windows或htopLinux。PyTorch 内部可以用torch.cuda.memory_allocated()查看已分配显存。影响性能的主要因素batch size 越大显存占用越高但吞吐可能更高。输入分辨率越大显存占用越高。模型参数越多显存占用越高。num_workers越大CPU 数据加载越快但会增加内存占用和系统负担。如果显存不足有几个常用手段降低batch_size。缩小输入尺寸。使用混合精度训练。使用梯度累积每几个 batch 再做一次 model.step()。换更小的模型。CPU 训练不是不能跑但建议不要把 epochs 设太大。比如 MNIST 全连接网络用 CPU 训练 5 个 epoch单 epoch 可能一两分钟CIFAR 的 CNN 可能要十几分钟。GPU 的加速效果在你第一次调用nvidia-smi看到利用率飙升时最明显。训练期间需要留意 Loss 值。如果 Loss 不下降优先检查数据是否归一化。学习率是否过大或过小。模型是否有输出形状错误。标签是否从 0 开始。8. 常见问题与排查方法问题现象可能原因排查方式解决方案pip 安装依赖失败网络问题或包版本冲突查看报错信息尝试换源使用国内 PyPI 镜像例如pip install -i https://pypi.tuna.tsinghua.edu.cn/simpletorch.cuda.is_available()返回 FalsePyTorch 安装成 CPU 版或驱动/CUDA版本不匹配在终端执行nvidia-smi查看驱动版本再对照官网选择 cu118/cu121重新安装对应的 GPU 版 PyTorch或升级驱动训练时报显存不足batch size 太大或输入分辨率太高查看nvidia-smi中进程占用减小 batch size、用torch.cuda.amp、减小图片尺寸模型训练 Loss 不降学习率不对、数据未归一化、模型代码有 bug先跑很小的数据集检查输入输出形状调试代码调低学习率检查标签范围Jupyter Notebook 导入 torch 报错内核使用的不是 conda 环境检查右上角或 VSCode 右下角解释器选择正确的 Python 解释器下载数据集失败或很慢网络原因看报错中 URL改为手动下载手动下载并放入./data对应目录FastAPI 启动后端口被占用8000 端口已被其他程序占用执行 netstat -anogrep 8000加载模型时报state_dict键不匹配模型类定义和保存时的结构不一致对比模型结构保持定义一致或只加载能匹配的键9. 最佳实践与使用建议9.1 第一次先跑通再调参不要一开始就追求高准确率。第一次跑通 MNIST哪怕只有 90%也算成功。之后可以尝试增加 epoch、改用 CNN、加入数据增强观察准确率变化。每个实验只改一个变量避免混在一起。9.2 目录管理建议项目目录这样组织dl_project/ ├── data/ # 数据集 ├── models/ # 保存的模型权重 ├── outputs/ # 日志、预测结果 ├── scripts/ # 训练、测试脚本 ├── app.py # API 服务 └── requirements.txt这样实验多了以后不会出现“哪个文件是谁生成的”这种混乱。9.3 日志和实验记录用print不是不行但最好记录到日志文件。可以使用 Python 标准库loggingimport logging logging.basicConfig( filenameoutputs/train.log, levellogging.INFO, format%(asctime)s %(message)s ) logging.info(fEpoch {epoch}, Loss: {loss:.4f})如果想更省事直接用 TensorBoardfrom torch.utils.tensorboard import SummaryWriter writer SummaryWriter(outputs/tb) writer.add_scalar(train_loss, loss, step)9.4 批量任务要注意失败恢复如果一次要跑几百张图片建议加入异常捕获把失败的图片路径记录下来便于后面重试failed [] for path in image_paths: try: result predict_one(path) save_result(path, result) except Exception as e: failed.append((path, str(e)))输出结果时保留输入路径、预测结果和置信度方便后续核查。9.5 合规使用数据与模型训练数据必须有合法来源。公开数据集要阅读许可协议爬取的数据要关注平台条款和隐私政策。使用预训练模型前查看模型卡Model Card中的 Licensed Under 字段。涉及人脸、声音等信息的场景务必获得当事人授权。部署到生产环境时建议增加人工复核机制不要完全依赖模型输出。10. 总结与下一步这套路线中最先应该跑通的不是 Transformer而是 MNIST 全连接网络。它包含深度学习的完整链路数据加载、模型定义、损失函数、优化器、训练循环、评估。跑通它你就具备了继续前进的基础。最容易踩的坑集中在环境部分conda 环境创建失败、PyTorch 版本和 CUDA 不匹配、数据集下载超时。解决起来其实不难多留意报错信息把版本固定下来就会少很多问题。接下来你可以做三件事把 MNIST 的网络换成 CNN对比效果。把 CIFAR-10 模型的准确率提升到 80% 以上加入数据增强和预训练模型。把文本分类的玩具 Transformer 换成真实的中文情感分类数据集尝试接入 Hugging Face 的预训练模型。深度学习入门不是一路刷理论而是从跑通一个极小的模型开始不断给自己正反馈。这个流程走完你已经不是零基础了。建议把这篇文章里的代码保存成自己的第一个深度学习项目后续所有新增内容都从这个项目扩展。
返回列表