PyTorch 是目前最流行的深度学习框架之一,以其灵活性和易用性受到开发者的喜爱。本文将带你从零开始,用 PyTorch 实现一个简单的神经网络,用于解决经典的 MNIST 手写数字分类问题。我们将涵盖数据准备、模型构建、训练和预测的完整流程,并提供可运行的代码示例。
首先,确保你已安装 PyTorch 和相关依赖。本例使用 Python 3.8+ 和 PyTorch。你可以通过以下命令安装:
pip install torch torchvision
我们将使用 MNIST 数据集,它包含 28×28 像素的手写数字图像(0-9),目标是训练一个神经网络来识别这些数字。
MNIST 数据集可以通过 PyTorch 的 torchvision 模块直接加载。我们需要将数据加载为张量,并进行归一化处理以加速训练。
import torch
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
# 定义数据预处理:将图像转换为张量并归一化
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,)) # MNIST 的均值和标准差
])
# 加载 MNIST 数据集
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)
代码说明:
我们将定义一个简单的全连接神经网络,包含两个隐藏层,适合处理 MNIST 的分类任务。
import torch.nn as nn
class SimpleNN(nn.Module):
def __init__(self):
super(SimpleNN, self).__init__()
self.flatten = nn.Flatten() # 将 28x28 图像展平为 784 维向量
self.fc1 = nn.Linear(28 * 28, 128) # 第一个全连接层
self.relu = nn.ReLU() # 激活函数
self.fc2 = nn.Linear(128, 64) # 第二个全连接层
self.fc3 = nn.Linear(64, 10) # 输出层,10 个类别(0-9)
def forward(self, x):
x = self.flatten(x)
x = self.relu(self.fc1(x))
x = self.relu(self.fc2(x))
x = self.fc3(x)
return x
# 实例化模型
model = SimpleNN()
代码说明:
我们使用交叉熵损失(适合分类任务)和 Adam 优化器来训练模型。
import torch.optim as optim
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
代码说明:
接下来,我们训练模型 5 个 epoch,观察损失变化。
def train(model, train_loader, criterion, optimizer, epochs=5):
model.train() # 切换到训练模式
for epoch in range(epochs):
running_loss = 0.0
for images, labels in train_loader:
optimizer.zero_grad() # 清零梯度
outputs = model(images) # 前向传播
loss = criterion(outputs, labels) # 计算损失
loss.backward() # 反向传播
optimizer.step() # 更新参数
running_loss += loss.item()
print(f"Epoch {epoch+1}, Loss: {running_loss/len(train_loader):.4f}")
# 开始训练
train(model, train_loader, criterion, optimizer)
代码说明:
训练完成后,我们在测试集上评估模型的准确率。
def test(model, test_loader, criterion):
model. # 切换到评估模式
correct = 0
total = 0
test_loss = 0.0
with torch.no_grad(): # 禁用梯度计算
for images, labels in test_loader:
outputs = model(images)
loss = criterion(outputs, labels)
test_loss += loss.item()
_, predicted = torch.max(outputs.data, 1) # 获取预测类别
total += labels.size(0)
correct += (predicted == labels).sum().item()
accuracy = 100 * correct / total
print(f"Test Loss: {test_loss/len(test_loader):.4f}, Accuracy: {accuracy:.2f}%")
# 测试模型
test(model, test_loader, criterion)
代码说明:
最后,我们用训练好的模型对单张图像进行预测。
import matplotlib.pyplot as plt
# 获取一张测试图像
dataiter = iter(test_loader)
images, labels = next(dataiter)
image, label = images[0], labels[0]
# 预测
model.
with torch.no_grad():
output = model(image.unsqueeze(0)) # 增加 batch 维度
_, predicted = torch.max(output, 1)
# 显示图像和预测结果
plt.imshow(image.squeeze(), cmap='gray')
plt.title(f"Predicted: {predicted.item()}, Actual: {label.item()}")
plt.savefig('prediction.png') # 保存图像
代码说明:
以下是完整的可运行代码,整合了上述所有步骤:
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
import matplotlib.pyplot as plt
# 数据准备
transform = transforms.Compose([
transforms.ToTensor(),
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)
# 定义模型
class SimpleNN(nn.Module):
def __init__(self):
super(SimpleNN, self).__init__()
self.flatten = nn.Flatten()
self.fc1 = nn.Linear(28 * 28, 128)
self.relu = nn.ReLU()
self.fc2 = nn.Linear(128, 64)
self.fc3 = nn.Linear(64, 10)
def forward(self, x):
x = self.flatten(x)
x = self.relu(self.fc1(x))
x = self.relu(self.fc2(x))
x = self.fc3(x)
return x
# 实例化模型、损失函数和优化器
model = SimpleNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 训练函数
def train(model, train_loader, criterion, optimizer, epochs=5):
model.train()
for epoch in range(epochs):
running_loss = 0.0
for images, labels in train_loader:
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f"Epoch {epoch+1}, Loss: {running_loss/len(train_loader):.4f}")
# 测试函数
def test(model, test_loader, criterion):
model.
correct = 0
total = 0
test_loss = 0.0
with torch.no_grad():
for images, labels in test_loader:
outputs = model(images)
loss = criterion(outputs, labels)
test_loss += loss.item()
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
accuracy = 100 * correct / total
print(f"Test Loss: {test_loss/len(test_loader):.4f}, Accuracy: {accuracy:.2f}%")
# 训练和测试
train(model, train_loader, criterion, optimizer)
test(model, test_loader, criterion)
# 预测单张图像
dataiter = iter(test_loader)
images, labels = next(dataiter)
image, label = images[0], labels[0]
model.
with torch.no_grad():
output = model(image.unsqueeze(0))
_, predicted = torch.max(output, 1)
plt.imshow(image.squeeze(), cmap='gray')
plt.title(f"Predicted: {predicted.item()}, Actual: {label.item()}")
plt.savefig('prediction.png')
通过本文,可以了解到如何用 PyTorch 实现一个简单的神经网络,包括:
这个模型虽然简单,但在 MNIST 数据集上通常能达到 95% 以上的准确率。可以进一步尝试调整网络结构(如增加层数)、优化超参数(如学习率)或使用卷积神经网络(CNN)来提升性能。希望这篇文章对你理解 PyTorch 和深度学习有所帮助!
Keras深度学习:从“Hello World”到“我模型跑起来了!”的奇幻(秃头)之旅
朋友们,听说你想玩深度学习?不想从底层CUDA开始撸矩阵乘法,也不想被PyTorch的动态图绕晕?恭喜你,Ke […]
用 PyTorch 实现一个简单的神经网络:从数据到预测
PyTorch 是目前最流行的深度学习框架之一,以其灵活性和易用性受到开发者的喜爱。本文将带你从零开始,用 P […]
脉冲控制程序开发
一、脉冲控制程序的典型应用场景 应用类型 控制对象 脉冲作用 步进电机控制 电机转动/定位 每个脉冲对应一个步 […]
电机控制MATLAB仿真软件开发
一、 核心仿真模块构建 1. 电机本体建模 matlab % PMSM dq轴数学模型示例 (状态空 […]
使用Vue和Web Worker实现TCP消息监听并实时更新图表
在现代Web应用中,实时数据可视化是一个常见的需求。本文将介绍如何在Vue应用中结合Web Worker来监听 […]
数据处理上位机软件开发
一、 明确核心需求 二、 技术选型 三、 软件架构设计 四、 开发流程建议 总结 开发一个成功的数据处理上位 […]
仪器设备远端控制系统开发
核心实现色谱设备云端协同操控与数据全生命周期管理。系统采用分层架构设计:
机械臂路线规划系统开发
项目介绍: 该项目主要通过机械臂末端搭载双目相机扫描环境,实时构建障碍物点云地图通过红外结构光扫描面部生成密集 […]
无线路由器上位机开发
项目介绍 为满足智能工厂中对生产数据实时远程监测的需求,由你创为客户开发了一套无线路由器上位机软件。该项目采用 […]
血液检测管理系统软件定制开发
项目介绍 该项目是为 某医院开发的血液检测管理系统:以样本唯一码为线索,贯通接收、分拣、前处理、上机、审核、报 […]
分析仪控制采集分析软件开发
项目介绍 该项目是跨厂商、跨接口的通用仪器控制与数据平台,集连接管理、实时/触发/定时/条件采集、元数据绑定、 […]
开源鸿蒙适配器KHP-系列硬件设备产测功能开发
案例背景 开源鸿蒙适配器KHP-系列的硬件设备的产测功能开发。实现了KHP-IC500设备在出厂前测试硬件功能 […]
联系电话:
电子邮箱:unczzb@unicrom.cn
深圳研发中心(总部): 深圳市龙华区港深国际中心十楼E区
太原研发中心: 山西省太原市万迎泽西大街120号时代天峰1918室
上海办事处: 上海市浦东新区牡丹路60号,东辰大厦7楼702室
扫一扫,关注由你创科技