第一部分:数据集的基本特征
MNIST数据集有以下特征:
①60000张训练图片
②10000张测试图片
③数据集为黑白图
④图片大小为28*28
第二部分:PyTorch搭建神经网络步骤
①读取数据
②设置网络结构
③计算损失函数
④使用优化器调节参数
⑤训练集训练模型
⑥测试集测试模型
⑦保存模型
第三部分:代码实现
(1)导包
#第一部分:导包
import torch
from torchvision import datasets
from torchvision import transforms
import torch.nn as nn
import torch.optim as optim
(2)加载数据集
#第二部分:导入数据集
train_data = datasets.MNIST(root="/data/mnist", train=True, transform=transforms.ToTensor(), download=True)
test_data = datasets.MNIST(root="/data/mnist", train=False, transform=transforms.ToTensor(), download=True)
#每次选取100条数据集训练
batch_size = 100
#因为我们不可能一次性将所有数据都喂给模型训练的,它吃不消也存不完
train_loader = torch.utils.data.DataLoader(dataset=train_data, batch_size=batch_size, shuffle=True)#True代表随机打乱的意思
test_loader = torch.utils.data.DataLoader(dataset=test_data, batch_size=batch_size, shuffle=False)
(3)设置MLP网络结构
#第三部分:设置MLP网络结构
class MLP(nn.Module):
# 初始化方法
# input_size 输入层的维度
# hidden_size 隐藏层的大小
# num_classes 输出层的类别数
def __init__(self, input_size, hidden_size, num_classes):
super(MLP, self).__init__()#初始化参数,并没有先后顺序
# 定义第1个全连接层
self.fc1 = nn.Linear(input_size, hidden_size)#分别代表传入的数据维度和输出的数据维度,#第一个隐藏层
# 定义激活函数ReLU
self.relu = nn.ReLU()
# 定义第2个全连接层
self.fc2 = nn.Linear(hidden_size, hidden_size)#第二个隐藏层
# 定义第3个全连接层
self.fc3 = nn.Linear(hidden_size, num_classes)#一个输出层
# 定义前向传播
def forward(self, x):
# 第一层的计算
out = self.fc1(x)
# 使用ReLU激活函数
out = self.relu(out)
# 第二层的计算
out = self.fc2(out)
# 再次使用ReLU激活函数
out = self.relu(out)
# 第三层的计算
out = self.fc3(out)
# 返回输出
return out
(4)定义交叉熵损失函数
#第四部分:定义交叉熵损失函数
criterion = nn.CrossEntropyLoss()
(5)设置优化器Adam
#第五部分:设置优化器Adam
learning_rate = 0.01 # 学习率
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
(6)设置训练集训练模型
#第六部分:设置训练集训练模型
num_epochs = 10 # 训练轮数
for epoch in range(num_epochs):
for i, (images, labels) in enumerate(train_loader):
# 将images的维度重置
images = images.reshape(-1, 28 * 28)
# 获得模型的预测输出
outputs = model(images)
# 计算损失
loss = criterion(outputs, labels)
# 梯度清零
optimizer.zero_grad()
# 反向传播
loss.backward()
# 更新参数
optimizer.step()
if (i + 1) % 100 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(train_loader)}], Loss: {loss.item():.4f}')
损失值整体上不断变小(中间过程可能会出现轻微的震荡)
(7)使用测试集评估模型
#第七部分:使用测试集评估模型
with torch.no_grad():
correct = 0
total = 0
# 从 test_loader 中获取数据进行评估
for images, labels in test_loader:
# 将 images 的维度重置
images = images.reshape(-1, 28 * 28)
# 获取模型预测结果
outputs = model(images)
# 从输出中获取最大值的索引作为预测标签
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
# 计算正确预测的数量
correct += (predicted == labels).sum().item()
# 打印模型在测试集上的准确率
print(f'Accuracy of the network on the 10000 test images: {100 * correct / total} %')
(8) 保存训练好的模型
#第八部分:保存训练好的模型
torch.save(model, 'mnist_mlp_model.pkl')
(9)完整pycharm代码
#第一部分:导包
import torch
from torchvision import datasets
from torchvision import transforms
import torch.nn as nn
import torch.optim as optim
#第二部分:导入数据集
train_data = datasets.MNIST(root="/data/mnist", train=True, transform=transforms.ToTensor(), download=True)
test_data = datasets.MNIST(root="/data/mnist", train=False, transform=transforms.ToTensor(), download=True)
#每次选取100条数据集训练
batch_size = 100
#因为我们不可能一次性将所有数据都喂给模型训练的,它吃不消也存不完
train_loader = torch.utils.data.DataLoader(dataset=train_data, batch_size=batch_size, shuffle=True)#True代表随机打乱的意思
test_loader = torch.utils.data.DataLoader(dataset=test_data, batch_size=batch_size, shuffle=False)
#第三部分:设置MLP网络结构
class MLP(nn.Module):
# 初始化方法
# input_size 输入层的维度
# hidden_size 隐藏层的大小
# num_classes 输出层的类别数
def __init__(self, input_size, hidden_size, num_classes):
super(MLP, self).__init__()#初始化参数,并没有先后顺序
# 定义第1个全连接层
self.fc1 = nn.Linear(input_size, hidden_size)#分别代表传入的数据维度和输出的数据维度,#第一个隐藏层
# 定义激活函数ReLU
self.relu = nn.ReLU()
# 定义第2个全连接层
self.fc2 = nn.Linear(hidden_size, hidden_size)#第二个隐藏层
# 定义第3个全连接层
self.fc3 = nn.Linear(hidden_size, num_classes)#一个输出层
# 定义前向传播
def forward(self, x):
# 第一层的计算
out = self.fc1(x)
# 使用ReLU激活函数
out = self.relu(out)
# 第二层的计算
out = self.fc2(out)
# 再次使用ReLU激活函数
out = self.relu(out)
# 第三层的计算
out = self.fc3(out)
# 返回输出
return out
# 定义参数
input_size = 28 * 28 # 输入大小
hidden_size = 512 # 隐藏层大小
num_classes = 10 # 输出大小 (类别数)
# 初始化MLP
model = MLP(input_size, hidden_size, num_classes)
#第四部分:定义交叉熵损失函数
criterion = nn.CrossEntropyLoss()
#第五部分:设置优化器Adam
learning_rate = 0.01 # 学习率
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
#第六部分:设置训练集训练模型
num_epochs = 10 # 训练轮数
for epoch in range(num_epochs):
for i, (images, labels) in enumerate(train_loader):
# 将images的维度重置
images = images.reshape(-1, 28 * 28)
# 获得模型的预测输出
outputs = model(images)
# 计算损失
loss = criterion(outputs, labels)
# 梯度清零
optimizer.zero_grad()
# 反向传播
loss.backward()
# 更新参数
optimizer.step()
if (i + 1) % 100 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(train_loader)}], Loss: {loss.item():.4f}')
#第七部分:使用测试集评估模型
with torch.no_grad():
correct = 0
total = 0
# 从 test_loader 中获取数据进行评估
for images, labels in test_loader:
# 将 images 的维度重置
images = images.reshape(-1, 28 * 28)
# 获取模型预测结果
outputs = model(images)
# 从输出中获取最大值的索引作为预测标签
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
# 计算正确预测的数量
correct += (predicted == labels).sum().item()
# 打印模型在测试集上的准确率
print(f'Accuracy of the network on the 10000 test images: {100 * correct / total} %')
#第八部分:保存训练好的模型
torch.save(model, 'mnist_mlp_model.pkl')