当前位置: 首页 > news >正文

机器学习基础(九):PyTorch入门

一、引言

在前面的学习中,我们已经掌握了机器学习的基础算法,从线性回归到逻辑回归,从 NumPy 手写实现到使用 Scikit-learn。但随着问题复杂度的提升,我们遇到了新的挑战:

如何构建和训练更复杂的模型,比如深度神经网络?

传统的 NumPy 实现虽然有助于理解原理,但在实际应用中面临诸多问题:

  • 计算效率低:无法利用 GPU 加速
  • 自动求导困难:需要手动推导和实现梯度计算
  • 代码复杂度高:搭建深层网络非常繁琐

PyTorch 正是为解决这些问题而生。它是目前最流行的深度学习框架之一,以其动态计算图简洁的 API强大的生态深受研究者喜爱。


二、什么是 PyTorch?

1. PyTorch 简介

PyTorch 是由 Facebook AI Research (FAIR) 于 2016 年发布的开源深度学习框架。它基于 Torch 库,使用 Python 作为前端接口,兼具灵活性和高效性。

核心特点:

特点 说明
动态计算图 像写普通 Python 代码一样构建网络,调试方便
自动求导 自动计算梯度,无需手动推导
GPU 加速 一行代码即可将计算转移到 GPU
Python 优先 与 Python 生态无缝集成
社区活跃 丰富的预训练模型和教程资源

2. PyTorch vs TensorFlow

特性 PyTorch TensorFlow
计算图 动态图(即时执行) 静态图(先定义后执行)
调试 简单,可用 pdb 相对复杂
部署 TorchServe TensorFlow Serving
学术界 更受欢迎 广泛使用
工业界 快速增长 成熟稳定

对于初学者和研究人员,PyTorch 的直观性使其成为首选。


三、PyTorch 核心概念

1. Tensor(张量)

Tensor 是 PyTorch 的基本数据结构,类似于 NumPy 的 ndarray,但可以在 GPU 上运行。

import torch# 创建 Tensor
x = torch.tensor([1.0, 2.0, 3.0])           # 从列表创建
y = torch.zeros(2, 3)                        # 2x3 零矩阵
z = torch.ones(3, 3)                         # 3x3 全1矩阵
w = torch.randn(2, 2)                        # 2x2 随机矩阵(标准正态分布)# Tensor 属性
print(x.shape)   # torch.Size([3])
print(x.dtype)   # torch.float32
print(x.device)  # cpu

Tensor 与 NumPy 的转换:

import numpy as np# Tensor -> NumPy
numpy_array = x.numpy()# NumPy -> Tensor
tensor_from_numpy = torch.from_numpy(numpy_array)

2. 自动求导(Autograd)

PyTorch 的 autograd 包提供了自动微分功能,这是神经网络训练的核心。

# 创建需要梯度的 Tensor
x = torch.tensor(2.0, requires_grad=True)
y = torch.tensor(3.0, requires_grad=True)# 定义计算图
z = x ** 2 + y ** 3  # z = x² + y³# 反向传播
z.backward()# 查看梯度
print(x.grad)  # dz/dx = 2x = 4.0
print(y.grad)  # dz/dy = 3y² = 27.0

关键点:

  • requires_grad=True 表示需要计算梯度
  • backward() 自动计算所有梯度
  • 梯度会累积在 .grad 属性中

3. GPU 加速

PyTorch 让 GPU 计算变得极其简单:

# 检查是否有 GPU
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f"使用设备: {device}")# 创建 Tensor 并移到 GPU
x = torch.randn(1000, 1000).to(device)# 或者直接指定设备创建
y = torch.randn(1000, 1000, device=device)# 计算在 GPU 上自动进行
z = x @ y  # 矩阵乘法

四、使用 PyTorch 构建神经网络

1. 使用 nn.Module 定义网络

PyTorch 提供了 torch.nn 模块来简化神经网络构建:

import torch
import torch.nn as nn
import torch.optim as optimclass NeuralNetwork(nn.Module):"""简单的三层神经网络"""def __init__(self, input_size, hidden_size, num_classes):super(NeuralNetwork, self).__init__()# 定义网络层self.layer1 = nn.Linear(input_size, hidden_size)self.relu = nn.ReLU()self.dropout = nn.Dropout(0.2)self.layer2 = nn.Linear(hidden_size, hidden_size)self.layer3 = nn.Linear(hidden_size, num_classes)def forward(self, x):"""前向传播"""out = self.layer1(x)out = self.relu(out)out = self.dropout(out)out = self.layer2(out)out = self.relu(out)out = self.layer3(out)return out# 创建模型实例
model = NeuralNetwork(input_size=784, hidden_size=256, num_classes=10)
print(model)

2. 使用 Sequential 快速搭建

对于简单的网络,可以使用更简洁的 Sequential

model = nn.Sequential(nn.Linear(784, 256),nn.ReLU(),nn.Dropout(0.2),nn.Linear(256, 128),nn.ReLU(),nn.Linear(128, 10)
)

3. 常用的层和激活函数

层/函数 说明 使用示例
nn.Linear 全连接层 nn.Linear(784, 256)
nn.Conv2d 卷积层 nn.Conv2d(1, 32, kernel_size=3)
nn.ReLU ReLU激活 nn.ReLU()
nn.Sigmoid Sigmoid激活 nn.Sigmoid()
nn.Tanh Tanh激活 nn.Tanh()
nn.Dropout Dropout正则化 nn.Dropout(0.5)
nn.BatchNorm2d 批归一化 nn.BatchNorm2d(32)

五、训练流程

1. 完整训练循环

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset# 假设我们有训练数据
# X_train: [batch_size, input_size]
# y_train: [batch_size]# 超参数
input_size = 784
hidden_size = 256
num_classes = 10
num_epochs = 10
batch_size = 64
learning_rate = 0.001# 创建模型、损失函数和优化器
model = NeuralNetwork(input_size, hidden_size, num_classes)
criterion = nn.CrossEntropyLoss()  # 交叉熵损失(内置 Softmax)
optimizer = optim.Adam(model.parameters(), lr=learning_rate)# 创建数据加载器
train_dataset = TensorDataset(X_train, y_train)
train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)# 训练循环
for epoch in range(num_epochs):model.train()  # 训练模式total_loss = 0for batch_idx, (data, target) in enumerate(train_loader):# 前向传播outputs = model(data)loss = criterion(outputs, target)# 反向传播optimizer.zero_grad()  # 清空梯度loss.backward()        # 计算梯度optimizer.step()       # 更新参数total_loss += loss.item()avg_loss = total_loss / len(train_loader)print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {avg_loss:.4f}')

2. 模型评估

model.eval()  # 评估模式(关闭 Dropout)
correct = 0
total = 0with torch.no_grad():  # 不计算梯度,节省内存for data, target in test_loader:outputs = model(data)_, predicted = torch.max(outputs.data, 1)total += target.size(0)correct += (predicted == target).sum().item()accuracy = 100 * correct / total
print(f'测试准确率: {accuracy:.2f}%')

3. 模型保存与加载

# 保存模型
torch.save(model.state_dict(), 'model.pth')# 加载模型
model = NeuralNetwork(input_size, hidden_size, num_classes)
model.load_state_dict(torch.load('model.pth'))
model.eval()

六、代码实战:手写数字识别

下面是一个完整的 MNIST 手写数字识别示例:

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms# 设置设备
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')# 1. 数据准备
transform = transforms.Compose([transforms.ToTensor(),  # 转换为 Tensor,并归一化到 [0, 1]transforms.Normalize((0.1307,), (0.3081,))  # MNIST 的标准化参数
])# 下载数据集
train_dataset = torchvision.datasets.MNIST(root='./data', train=True, transform=transform, download=True)
test_dataset = torchvision.datasets.MNIST(root='./data', train=False, transform=transform, download=True)train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=64, shuffle=False)# 2. 定义模型
class CNN(nn.Module):def __init__(self):super(CNN, self).__init__()self.conv1 = nn.Conv2d(1, 32, kernel_size=3, padding=1)self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)self.pool = nn.MaxPool2d(2, 2)self.dropout = nn.Dropout(0.25)# 计算全连接层输入大小: 28x28 -> 14x14 -> 7x7self.fc1 = nn.Linear(64 * 7 * 7, 128)self.fc2 = nn.Linear(128, 10)self.relu = nn.ReLU()def forward(self, x):# 卷积层: [batch, 1, 28, 28] -> [batch, 32, 28, 28]x = self.relu(self.conv1(x))x = self.pool(x)  # -> [batch, 32, 14, 14]x = self.relu(self.conv2(x))x = self.pool(x)  # -> [batch, 64, 7, 7]x = x.view(x.size(0), -1)  # 展平: [batch, 64*7*7]x = self.dropout(x)x = self.relu(self.fc1(x))x = self.fc2(x)return x# 3. 训练
model = CNN().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)num_epochs = 5
for epoch in range(num_epochs):model.train()running_loss = 0.0for batch_idx, (images, labels) in enumerate(train_loader):images, labels = images.to(device), labels.to(device)# 前向 + 反向 + 优化optimizer.zero_grad()outputs = model(images)loss = criterion(outputs, labels)loss.backward()optimizer.step()running_loss += loss.item()if (batch_idx + 1) % 100 == 0:print(f'Epoch [{epoch+1}/{num_epochs}], 'f'Step [{batch_idx+1}/{len(train_loader)}], 'f'Loss: {loss.item():.4f}')print(f'Epoch [{epoch+1}] 平均损失: {running_loss/len(train_loader):.4f}')print('训练完成!')# 4. 测试
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.data, 1)total += labels.size(0)correct += (predicted == labels).sum().item()print(f'测试集准确率: {100 * correct / total:.2f}%')

七、PyTorch 的优缺点

优点

优点 说明
直观易用 动态图机制,代码即模型,调试方便
Python 原生 与 Python 生态完美融合
自动求导 无需手动推导梯度,节省大量时间
GPU 加速 一行代码切换 CPU/GPU
社区活跃 丰富的教程、预训练模型和工具
研究友好 学术界首选框架,新算法实现快

缺点

缺点 说明
部署相对复杂 相比 TensorFlow,生产部署工具不够成熟
静态图优化 动态图在某些场景下性能略逊于静态图
移动端支持 移动端部署不如 TensorFlow Lite 成熟

八、应用场景

PyTorch 广泛应用于:

  • 计算机视觉:图像分类、目标检测、语义分割(如 ResNet、YOLO)
  • 自然语言处理:机器翻译、文本生成、情感分析(如 BERT、GPT)
  • 生成模型:GAN、VAE、扩散模型
  • 强化学习:游戏 AI、机器人控制
  • 科学计算:物理模拟、药物发现

九、总结

PyTorch 是深度学习入门的绝佳选择:

核心优势:动态计算图 + 自动求导 + Python 原生体验

关键点回顾:

要点 内容
核心数据结构 Tensor(支持 GPU)
自动求导 requires_grad + backward()
构建网络 继承 nn.Module 或使用 nn.Sequential
训练流程 定义模型 → 选择损失 → 设置优化器 → 训练循环
GPU 加速 .to(device) 或创建时指定 device

掌握 PyTorch,你就拥有了构建从简单神经网络到复杂深度学习系统的强大工具。它是通往计算机视觉、自然语言处理等前沿领域的必经之路。


http://www.jsqmd.com/news/577883/

相关文章:

  • AI辅助开发:让快马智能生成带安全验证的路由器手机登录界面
  • 2026成都极简门品牌Top8推荐榜单与选购指南 - 企业推荐师
  • AI赋能论文写作:开题→综述→初稿→降重→答辩全流程拆解
  • BulletinBoard快速入门:10分钟创建你的第一个iOS引导卡片
  • 【把玩数据结构】详解队列
  • GKD规则冲突检测:自动化识别并提示重叠规则问题
  • 2026年国内热门殡葬用品品牌科普推荐(新手必看):寿衣选购不再踩坑 - 资讯焦点
  • ChatGPT_JCM前端构建工具对比:Webpack、Vite与Rollup
  • 终极指南:如何用danger-js在Jest测试框架中实现自动化代码审查
  • 【ROS2】雷达驱动实战:从FMCW原理到PointCloud2发布
  • ensp实战演练:用快马AI生成含隐蔽故障的网络项目,锤炼排错能力
  • 10分钟掌握 Terraform AWS EKS Blueprints 的 Karpenter 集成:实现自动节点扩展与成本优化终极指南
  • 温和溶石除味不刺激,2026除牙结石防口臭牙膏实测推荐:日常护齿必看 - 资讯焦点
  • 终极指南:Graph Nets从入门到精通 - 深度解析图神经网络消息传递机制
  • 别再乱调参数了!手把手教你用MATLAB/Simulink分析VSG多机并联的频率稳定性
  • 电子设备流水线适配z型链板提升机高性价比之选 - 资讯焦点
  • GraphQL Ruby解析器模式:10个业务逻辑分离与代码复用的终极技巧
  • TOAST UI Chart错误处理与调试终极指南:10个常见问题解决方案大全
  • Danger.js故障排除终极指南:解决10个最常见配置问题
  • 白发转黑发哪个品牌有效?黑奥秘“防白三件套”产品,白发转黑科学养发 - 美业信息观察
  • CameraKit-Android终极社区贡献指南:从新手到核心开发者的完整教程
  • Svix-webhooks实战指南:电商、金融、物联网三大场景应用案例
  • Redacted Font:企业级产品设计的终极保密字体应用指南
  • TOAST UI Chart仪表盘开发终极指南:Gauge图表在企业监控中的完整应用方案
  • 图网络梯度计算与反向传播:自动微分技术的完整指南
  • 深入解析BulletinBoard:iOS上下文卡片库的完整架构指南与核心实现
  • 如何为RTX3090显卡在Ubuntu22.04上快速搭建PyTorch2.0.1的CUDA11.7环境
  • Windows窗口置顶3分钟快速上手指南:告别频繁切换的烦恼
  • Midscene.js:当视觉AI重新定义UI自动化边界
  • C++析构函数:关键特性与应用