前言
在当今人工智能与机器学习飞速发展的时代,神经网络作为一种强大的工具,在图像识别、自然语言处理等众多领域都展现出了卓越的性能。其中,BP(Back Propagation)神经网络作为一种经典的前馈神经网络,以其简单的结构和高效的学习能力,一直备受研究者和开发者的青睐。
本次实战,我们将目光聚焦于著名的 MNIST 数据集。MNIST 数据集由手写数字的图像组成,它具有规模适中、问题清晰等特点,非常适合作为神经网络的入门实战案例。
通过使用 BP 神经网络对 MNIST 数据集中的手写数字进行识别,我们将深入了解神经网络的工作原理、训练过程以及在实际问题中的应用。 在这个过程中,我们将逐步探索如何构建 BP 神经网络模型、如何加载和预处理数据集、如何进行模型的训练和优化,以及如何评估模型的性能。
一、MNIST数据集介绍和加载
1.MNIST数据集介绍
MNIST 数据集是机器学习领域中广泛使用的一个基准数据集,主要用于图像识别和数字分类任务。
MNIST 数据集由手写数字的图像组成,这些数字是从 0 到 9 的整数。它包含了 70,000 张灰度图像,其中 60,000 张用于训练,10,000 张用于测试。每一张图像都是 28×28 像素的,呈现出不同人书写的数字形态,具有一定的多样性和复杂性。
该数据集的图像是灰度的且数字居中,这在一定程度上减少了预处理的工作量并加快了模型的运行速度。其简洁明了的特点使得 MNIST 成为初学者进入机器学习和深度学习领域的理想选择,许多经典的算法和模型都首先在这个数据集上进行验证和优化。 MNIST 数据集的广泛应用推动了图像识别技术的发展,研究人员通过在这个数据集上不断尝试新的算法和改进模型结构,为更复杂的图像识别任务奠定了基础。
2.加载数据集MNIST数据集
# MNIST 包含 70,000 张手写数字图像: 60,000 张用于训练,10,000 张用于测试。
# 图像是灰度的,28×28 像素的,并且居中的,以减少预处理和加快运行。
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
# 使用 torchvision 读取数据
trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
# 使用 DataLoader 加载数据
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)
testloader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False)
首先定义了一个数据转换 transform,包括将图像转换为张量并进行归一化处理。然后使用 torchvision.datasets.MNIST 加载 MNIST 数据集,分别设置 train=True 和 train=False 来获取训练集和测试集。最后使用 torch.utils.data.DataLoader 将数据集包装成数据加载器,设置了批量大小为 64,训练集进行随机打乱,测试集不打乱。
二、构建 BP 网络模型
# 第 1 步:构建 BP 网络模型
class BPNetwork(torch.nn.Module):
def __init__(self):
super(BPNetwork, self).__init__()
"""
定义第一个线性层,
输入为图片(28x28),
输出为第一个隐层的输入,大小为 128。
"""
self.linear1 = torch.nn.Linear(28 * 28, 128)
# 在第一个隐层使用 ReLU 激活函数
self.relu1 = torch.nn.ReLU()
"""
定义第二个线性层,
输入是第一个隐层的输出,
输出为第二个隐层的输入,大小为 64。
"""
self.linear2 = torch.nn.Linear(128, 64)
# 在第二个隐层使用 ReLU 激活函数
self.relu2 = torch.nn.ReLU()
"""
定义第三个线性层,
输入是第二个隐层的输出,
输出为输出层,大小为 10
"""
self.linear3 = torch.nn.Linear(64, 10)
# 最终的输出经过 softmax 进行归一化
self.softmax = torch.nn.LogSoftmax(dim=1)
def forward(self, x):
"""
定义神经网络的前向传播
x: 图片数据, shape 为(64, 1, 28, 28)
"""
# 首先将 x 的 shape 转为(64, 784)
x = x.view(x.shape[0], -1)
# 接下来进行前向传播
x = self.linear1(x)
x = self.relu1(x)
x = self.linear2(x)
x = self.relu2(x)
x = self.linear3(x)
x = self.softmax(x)
# 上述一串,可以直接使用 x = self.model(x) 代替。
return x
1.神经网络结构图示
[table]
[tr]
[td]层名[/td]
[td]输入大小[/td]
[td]输出大小[/td]
[/tr]
[tr]
[td]输入层(展平后的图片)