使用Python实现一个简单的神经网络分类器

今天 4阅读

在机器学习和人工智能领域,神经网络是一种非常强大的工具,广泛应用于图像识别、自然语言处理、语音识别等领域。本文将介绍如何使用 Python 和 PyTorch 框架来构建一个简单的全连接神经网络(Fully Connected Neural Network),用于对经典的 MNIST 手写数字数据集进行分类。

我们将从环境准备开始,逐步介绍代码实现,并解释其工作原理。最终的模型将在测试集上达到较高的准确率。


环境准备

首先,确保你的环境中安装了以下依赖库:

Python 3.xPyTorchmatplotlib(用于可视化)torchvision(提供标准数据集)

你可以通过以下命令安装所需的库:

pip install torch torchvision matplotlib

导入必要的模块

import torchimport torch.nn as nnimport torch.optim as optimfrom torchvision import datasets, transformsfrom torch.utils.data import DataLoaderimport matplotlib.pyplot as plt

定义超参数

batch_size = 64learning_rate = 0.01num_epochs = 5

这些参数决定了训练过程的行为:

batch_size: 每次迭代使用的样本数量。learning_rate: 控制优化器的学习步长。num_epochs: 训练整个数据集的次数。

加载MNIST数据集

我们使用 torchvision.datasets.MNIST 来加载手写数字数据集,并对其进行预处理。

transform = transforms.Compose([    transforms.ToTensor(),    transforms.Normalize((0.5,), (0.5,))])train_dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True)test_dataset = datasets.MNIST(root='./data', train=False, transform=transform, download=True)train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)test_loader = DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)

我们可以查看一下数据集的基本信息:

print(f"Train dataset size: {len(train_dataset)}")print(f"Test dataset size: {len(test_dataset)}")

输出示例:

Train dataset size: 60000Test dataset size: 10000

构建神经网络模型

我们定义一个具有两个隐藏层的全连接神经网络。

class SimpleNN(nn.Module):    def __init__(self):        super(SimpleNN, self).__init__()        self.flatten = nn.Flatten()        self.fc1 = nn.Linear(28 * 28, 512)        self.relu1 = nn.ReLU()        self.fc2 = nn.Linear(512, 256)        self.relu2 = nn.ReLU()        self.fc3 = nn.Linear(256, 10)    def forward(self, x):        x = self.flatten(x)        x = self.fc1(x)        x = self.relu1(x)        x = self.fc2(x)        x = self.relu2(x)        x = self.fc3(x)        return x

该模型结构如下:

输入层:28x28 = 784 个像素点。隐藏层1:512个神经元,ReLU激活函数。隐藏层2:256个神经元,ReLU激活函数。输出层:10个神经元,对应0~9的数字类别。

初始化模型、损失函数和优化器

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")model = SimpleNN().to(device)criterion = nn.CrossEntropyLoss()optimizer = optim.Adam(model.parameters(), lr=learning_rate)

这里我们使用交叉熵损失函数(CrossEntropyLoss)和 Adam 优化器。


训练模型

for epoch in range(num_epochs):    model.train()    running_loss = 0.0    for images, labels in train_loader:        images, labels = images.to(device), labels.to(device)        # 前向传播        outputs = model(images)        loss = criterion(outputs, labels)        # 反向传播与优化        optimizer.zero_grad()        loss.backward()        optimizer.step()        running_loss += loss.item()    print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {running_loss/len(train_loader):.4f}")

每轮训练结束后,打印当前的平均损失值。


评估模型性能

model.eval()correct = 0total = 0with 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"Test Accuracy: {100 * correct / total:.2f}%")

这段代码将计算模型在测试集上的准确率。


可视化部分预测结果

为了更直观地了解模型的表现,我们可以随机选择一些测试图片并显示模型的预测结果。

def imshow(img):    img = img / 2 + 0.5  # unnormalize    npimg = img.numpy()    plt.imshow(np.transpose(npimg, (1, 2, 0)), cmap='gray')    plt.show()dataiter = iter(test_loader)images, labels = next(dataiter)imshow(torchvision.utils.make_grid(images[:4]))model.eval()with torch.no_grad():    outputs = model(images.to(device))    _, predicted = torch.max(outputs, 1)print('Predicted:', ' '.join(f'{predicted[j].item()}' for j in range(4)))print('GroundTruth:', ' '.join(f'{labels[j]}' for j in range(4)))

这段代码会显示前4张图像及其预测标签与真实标签。


十、完整代码汇总

以下是完整的代码整合版本:

import torchimport torch.nn as nnimport torch.optim as optimfrom torchvision import datasets, transformsfrom torch.utils.data import DataLoaderimport matplotlib.pyplot as pltimport torchvision# 超参数batch_size = 64learning_rate = 0.01num_epochs = 5# 数据预处理transform = transforms.Compose([    transforms.ToTensor(),    transforms.Normalize((0.5,), (0.5,))])# 加载数据集train_dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True)test_dataset = datasets.MNIST(root='./data', train=False, transform=transform, download=True)train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)test_loader = DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)# 定义神经网络class SimpleNN(nn.Module):    def __init__(self):        super(SimpleNN, self).__init__()        self.flatten = nn.Flatten()        self.fc1 = nn.Linear(28 * 28, 512)        self.relu1 = nn.ReLU()        self.fc2 = nn.Linear(512, 256)        self.relu2 = nn.ReLU()        self.fc3 = nn.Linear(256, 10)    def forward(self, x):        x = self.flatten(x)        x = self.fc1(x)        x = self.relu1(x)        x = self.fc2(x)        x = self.relu2(x)        x = self.fc3(x)        return x# 初始化设备、模型、损失函数和优化器device = torch.device("cuda" if torch.cuda.is_available() else "cpu")model = SimpleNN().to(device)criterion = nn.CrossEntropyLoss()optimizer = optim.Adam(model.parameters(), lr=learning_rate)# 训练模型for epoch in range(num_epochs):    model.train()    running_loss = 0.0    for images, labels in train_loader:        images, labels = images.to(device), labels.to(device)        outputs = model(images)        loss = criterion(outputs, labels)        optimizer.zero_grad()        loss.backward()        optimizer.step()        running_loss += loss.item()    print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {running_loss/len(train_loader):.4f}")# 测试模型model.eval()correct = 0total = 0with 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"Test Accuracy: {100 * correct / total:.2f}%")# 显示预测结果def imshow(img):    img = img / 2 + 0.5    npimg = img.numpy()    plt.imshow(np.transpose(npimg, (1, 2, 0)), cmap='gray')    plt.show()dataiter = iter(test_loader)images, labels = next(dataiter)imshow(torchvision.utils.make_grid(images[:4]))model.eval()with torch.no_grad():    outputs = model(images.to(device))    _, predicted = torch.max(outputs, 1)print('Predicted:', ' '.join(f'{predicted[j].item()}' for j in range(4)))print('GroundTruth:', ' '.join(f'{labels[j]}' for j in range(4)))

十总结与展望

本文介绍了如何使用 PyTorch 构建一个简单的全连接神经网络,并在 MNIST 数据集上进行训练和测试。我们实现了数据加载、模型定义、训练循环、模型评估以及结果可视化等完整流程。

虽然这个模型相对简单,但它为理解深度学习的基础提供了良好的实践基础。未来可以尝试以下改进:

使用卷积神经网络(CNN)提升准确率;添加 dropout 层防止过拟合;使用学习率调度器动态调整学习率;尝试不同的优化器和损失函数组合;部署模型到 Web 或移动端应用中。

希望这篇文章能够帮助你入门神经网络编程和 PyTorch 的使用!如果你有任何问题或建议,欢迎留言讨论。


字数统计:约1400字

免责声明:本文来自网站作者,不代表CIUIC的观点和立场,本站所发布的一切资源仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。客服邮箱:ciuic@ciuic.com

目录[+]

您是本站第19237名访客 今日有9篇新文章

微信号复制成功

打开微信,点击右上角"+"号,添加朋友,粘贴微信号,搜索即可!