使用PyTorch 实现一个简单训练模型
·
一、深度学习基础概念(必懂)
1. 神经元(感知器)
模仿人脑神经细胞:输入数据 → 加权求和 → 激活函数 → 输出y=f(w⋅x+b)
- w:权重(参数)
- b:偏置
- f:激活函数(ReLU/Sigmoid),让网络非线性
2. 全连接神经网络(FC/MLP)
输入层 → 隐藏层 → 输出层每一层神经元全部和下一层相连,就是全连接网络。
3. 损失函数 Loss
衡量预测值 和 真实标签差多远分类任务用:交叉熵损失 CrossEntropyLoss
4. 反向传播 BP(最核心!)
正向传播:输入→计算预测结果反向传播:根据误差,自动更新权重 w、偏置 b,让误差越来越小优化器(SGD/Adam)负责更新参数。
5. 训练流程固定四步
- 前向传播(预测)
- 计算损失
- 反向传播求梯度
- 优化器更新参数(梯度下降)
二、MNIST 是什么?
手写数字数据集:
- 28×28 灰度图片(0~9)
- 训练集 6 万张,测试集 1 万张
- 我们把图片展平成 784 个数字 输入全连接网络
三、PyTorch 完整代码:全连接神经网络识别 MNIST
1. 安装 PyTorch
bash
运行
pip install torch torchvision
2. 完整可运行代码(注释超详细)
python
运行
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
# ======================
# 1. 设备选择:有GPU用GPU,没有用CPU
# ======================
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print("使用设备:", device)
# ======================
# 2. 数据预处理 & 加载MNIST数据集
# ======================
transform = transforms.Compose([
transforms.ToTensor(), # 转张量 0~1
transforms.Normalize((0.1307,), (0.3081,)) # 标准化
])
# 训练集
train_dataset = datasets.MNIST(
root="./data", train=True, download=True, transform=transform
)
# 测试集
test_dataset = datasets.MNIST(
root="./data", train=False, download=True, transform=transform
)
# 数据加载器(分批训练)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
# ======================
# 3. 定义全连接神经网络(MLP)
# 输入784 → 隐藏层128 → 隐藏层64 → 输出10(数字0~9)
# ======================
class FCNet(nn.Module):
def __init__(self):
super().__init__()
# 全连接层
self.fc1 = nn.Linear(28*28, 128)
self.fc2 = nn.Linear(128, 64)
self.fc3 = nn.Linear(64, 10)
# 激活函数
self.relu = nn.ReLU()
# 前向传播(必须实现)
def forward(self, x):
# x形状:[batch,1,28,28] -> 展平 [batch,784]
x = x.view(-1, 28*28)
x = self.relu(self.fc1(x))
x = self.relu(self.fc2(x))
x = self.fc3(x) # 最后一层不用激活(交叉熵自带softmax)
return x
# 创建模型并放到设备
model = FCNet().to(device)
# ======================
# 4. 损失函数 + 优化器
# ======================
criterion = nn.CrossEntropyLoss() # 分类损失
optimizer = optim.Adam(model.parameters(), lr=0.001) # Adam优化器
# ======================
# 5. 训练循环(epoch训练轮数)
# ======================
EPOCHS = 5
for epoch in range(EPOCHS):
model.train() # 设置为训练模式
total_loss = 0.0
for images, labels in train_loader:
# 数据放到GPU/CPU
images, labels = images.to(device), labels.to(device)
# 1.前向传播预测
outputs = model(images)
loss = criterion(outputs, labels)
# 2.梯度清零(必须!不然梯度累加)
optimizer.zero_grad()
# 3.反向传播(自动求梯度!!!)
loss.backward()
# 4.更新权重参数
optimizer.step()
total_loss += loss.item()
# 打印训练信息
avg_loss = total_loss / len(train_loader)
print(f"Epoch [{epoch+1}/{EPOCHS}] 平均损失: {avg_loss:.4f}")
# ======================
# 6. 测试模型准确率
# ======================
model.eval() # 评估模式(关闭梯度、dropout)
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)
_, pred = torch.max(outputs, dim=1)
total += labels.size(0)
correct += (pred == labels).sum().item()
acc = correct / total
print(f"\n测试集准确率:{acc:.4f}")
四、代码对应知识点讲解(完全对应你要的)
1. 全连接神经网络结构
plaintext
输入层:28×28=784
隐藏层1:128神经元 + ReLU激活
隐藏层2:64神经元 + ReLU激活
输出层:10神经元(0~9分类)
2. 反向传播核心四行代码
python
运行
optimizer.zero_grad() # 清空旧梯度
loss.backward() # 反向传播,自动计算梯度!!!
optimizer.step() # 根据梯度更新w、b参数
PyTorch 自动求导,你不用手写数学公式!
3. 模型训练效果
运行 5 轮
五、一句话总结所有知识点
- 神经网络:多层神经元堆叠,加权 + 激活,拟合复杂函数
- 反向传播 BP:根据误差反向计算梯度,自动更新权重
- 全连接网络 MLP:层与层全部相连,适合简单分类
- PyTorch 流程:加载数据 → 定义模型 → 损失 + 优化器 → 训练循环(前向→损失→反向→更新)→ 测试
epoch 后准确率:97% 左右已经能很好识别手写数字。
更多推荐


所有评论(0)