【深度学习】60 分钟 PyTorch 极速入门:从 Tensor 到 CIFAR-10 分类

60 分钟 PyTorch 极速入门:从 Tensor 到 CIFAR-10 分类(超详细)

作者:南方的狮子先生

日期:2025-10

关键词:PyTorch、深度学习、CNN、CIFAR-10、Autograd、CUDA、初学者


1. 写在最前:为什么选 PyTorch?

NumPy 只负责"科学计算",PyTorch 专为"深度学习"而生------两者目标不同,功能重叠但不冲突。

维度 NumPy PyTorch
核心定位 通用多维数组库 深度学习自动求导框架
计算图 ❌ 无 ✅ 动态图自动构建
自动求导 ❌ 手工推导链式法则 ✅ 自动反向传播
GPU 加速 ❌(需 CuPy 等外挂) ✅ 原生 .cuda()
稀疏/量化/分布式 ✅ 内置多种训练策略
部署工具链 ✅ TorchScript、ONNX、TensorRT
社区生态 科学计算 预训练模型、数据集、Hub

形象比喻:

  • NumPy 像一把瑞士军刀:削铅笔、开瓶盖都能干,但砍树费力。
  • PyTorch 像电锯:专为砍树(训练神经网络)设计,插上电(GPU)效率爆表;也能削铅笔,但没必要。

所以:

  1. 只做传统数值模拟 → NumPy 足够。
  2. 要做深度学习 → 直接用 PyTorch,少踩 90% 的坑。
特性 一句话总结
动态图 写代码就像写 Python,调试无痛
GPU 加速 .cuda() 一行搞定,速度飞起
生态丰富 torchvision、torchaudio、transformers 全家桶

2. 环境准备(1 分钟)

bash 复制代码
# CPU 版
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu

# GPU 版(以 CUDA 11.8 为例)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

验证安装:

python 复制代码
import torch
print(torch.__version__)          # 2.x.x
print(torch.cuda.is_available())  # True 说明 GPU 可用

3. Tensor:NumPy 的超级加强版

操作 NumPy PyTorch
创建矩阵 np.zeros((3,3)) torch.zeros(3,3)
矩阵乘法 a @ b a @ btorch.mm(a,b)
GPU 加速 a.cuda()
自动求导 a.requires_grad=True

代码速览:

python 复制代码
import torch

# 1. 创建
x = torch.rand(5, 3)          # 均匀分布
y = torch.zeros(5, 3, dtype=torch.long)
z = torch.tensor([[1, 2], [3, 4]])

# 2. 运算
print(x + y)
print(x.add_(y))              # 原地加法(带下划线)

# 3. 切片
print(x[:, 1])

# 4. 改变形状
v = x.view(-1, 8)             # -1 表示自动推断

# 5. 与 NumPy 互转
import numpy as np
np_array = x.numpy()          # Tensor -> ndarray
x2 = torch.from_numpy(np_array)

4. Autograd:自动求导黑科技

核心:只要 requires_grad=True,PyTorch 会帮你构建计算图 ,调用 .backward() 就能自动求导。

python 复制代码
x = torch.ones(2, 2, requires_grad=True)
y = x + 2
z = y * y * 3
out = z.mean()

out.backward()                # 反向传播
print(x.grad)                 # ∂out/∂x = 4.5

关闭梯度(推理阶段):

python 复制代码
with torch.no_grad():
    print((x * 2).requires_grad)  # False

5. 搭建你的第一个神经网络(LeNet)

网络结构:
3×32×32 → Conv2d(3,6,5) → ReLU → MaxPool(2) → Conv2d(6,16,5) → ReLU → MaxPool(2) → 展平 → 120 → 84 → 10

python 复制代码
import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = F.max_pool2d(F.relu(self.conv1(x)), 2)
        x = F.max_pool2d(F.relu(self.conv2(x)), 2)
        x = x.view(-1, 16 * 5 * 5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

net = Net()
print(net)

6. 损失函数 & 优化器

组件 常用选择
损失函数 nn.CrossEntropyLoss()(分类)
优化器 optim.SGD / optim.Adam
python 复制代码
import torch.optim as optim

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

7. 训练循环(万能模板)

python 复制代码
for epoch in range(2):
    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        inputs, labels = data

        optimizer.zero_grad()        # 1. 清零梯度
        outputs = net(inputs)        # 2. 前向
        loss = criterion(outputs, labels)
        loss.backward()              # 3. 反向
        optimizer.step()             # 4. 更新权重

        running_loss += loss.item()
        if i % 2000 == 1999:
            print(f'[{epoch + 1}, {i + 1}] loss: {running_loss / 2000:.3f}')
            running_loss = 0.0

8. CIFAR-10 完整实战(含数据加载)

8.1 数据准备(torchvision 一键搞定)

python 复制代码
import torchvision
import torchvision.transforms as transforms

transform = transforms.Compose([
    transforms.ToTensor(),                      # 0-1
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))  # -1-1
])

trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
                                        download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
                                          shuffle=True, num_workers=2)

testset = torchvision.datasets.CIFAR10(root='./data', train=False,
                                       download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=4,
                                         shuffle=False, num_workers=2)

classes = ('plane', 'car', 'bird', 'cat', 'deer',
           'dog', 'frog', 'horse', 'ship', 'truck')

8.2 训练 + 测试

把第 7 步的 trainloader 换成 CIFAR-10 即可。

测试准确率(2 epoch,CPU)≈ 54%(10 类随机 10%,已学到东西!)

python 复制代码
correct = 0
total = 0
with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = net(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print(f'Accuracy: {100 * correct / total:.0f}%')

9. GPU 加速:2 行代码搞定

python 复制代码
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
net.to(device)                 # 模型搬过去
inputs, labels = inputs.to(device), labels.to(device)  # 数据搬过去

小网络 CPU 也能跑;增大通道数/层数后 GPU 速度优势明显。


10. 常见问题 & 排坑指南

报错/现象 解决
CUDA out of memory 减小 batch_size
loss 震荡不降 调低学习率、加 BatchNorm
准确率一直 10% 忘记 optimizer.zero_grad()
图片显示全黑 忘记 img / 2 + 0.5 反归一化

11. 下一步学什么?

方向 资源
更深的 CNN ResNet、DenseNet(torchvision 现成)
数据增强 transforms.RandomCropRandAugment
学习率调度 torch.optim.lr_scheduler.CosineAnnealingLR
迁移学习 预训练 ImageNet 模型微调
可视化 TensorBoard、Netron、Grad-CAM

相关推荐
格林威4 小时前
AOI设备在光伏制造领域的核心应用
人工智能·数码相机·计算机视觉·目标跟踪·视觉检测·制造
报错小能手4 小时前
C++笔记(面向对象)类模板
算法
测试开发Kevin4 小时前
大语言模型技术Agentic Context Engineering (ACE) 的到来会取代微调吗
人工智能·ai·语言模型·自然语言处理
卡奥斯开源社区官方4 小时前
实战|AWS Snowcone边缘计算落地工业场景:从技术原理到代码实现
人工智能·边缘计算
StarPrayers.4 小时前
机器学习中的等高线
人工智能·机器学习
闲人编程4 小时前
Docker化你的Python应用:从开发到生产
python·docker·eureka·开发·生产·codecapsule
JJJJ_iii4 小时前
【机器学习10】项目生命周期、偏斜类别评估、决策树
人工智能·python·深度学习·算法·决策树·机器学习
rgb2gray4 小时前
共享自行车与电动共享自行车使用中建成环境影响的对比研究:基于合肥数据的时空机器学习分析
人工智能·机器学习·图论·xgboost·shap·gtwr·时空机器学习
fie88895 小时前
基于MATLAB的LBFGS优化算法实现
算法·matlab