欢迎光临散文网 会员登陆 & 注册

5.2 多层感知机代码实现

2023-02-07 11:44 作者:梗直哥丶  | 我要投稿

在 PyTorch 中实现多层感知机(MLP)可以分为以下几步:

  1. 导入所需的库和模块,包括 PyTorch 的 nn 模块,torch.optim 模块和数据加载及预处理的常用库,例如 torchvision 和 torchtext。

  2. 定义多层感知机模型。这可以通过继承 PyTorch 的 nn.Module 类并定义前向传播函数来完成。

  3. 加载数据集。这可以使用 PyTorch 提供的数据加载器或自定义加载器完成。

  4. 定义损失函数和优化器。这可以使用 PyTorch 的内置函数和优化器来完成。

  5. 开始训练模型。在训练循环中,您需要通过获取输入和标签,计算模型输出,计算损失并更新模型参数来训练模型。

  6. 在训练之后,可以使用模型进行推理或将其保存以供将来使用。

下面这个例子中,梗直哥给你演示了一个包含两个隐藏层的 MLP实现,使用 MNIST 数据集进行训练,一起来感受一下整个过程:

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms

# 定义 MLP 网络
class MLP(nn.Module):
    def __init__(self, input_size, hidden_size, num_classes):
        super(MLP, self).__init__()
        self.fc1 = nn.Linear(input_size, hidden_size)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(hidden_size, hidden_size)
        self.fc3 = nn.Linear(hidden_size, num_classes)
    
    def forward(self, x):
        out = self.fc1(x)
        out = self.relu(out)
        out = self.fc2(out)
        out = self.relu(out)
        out = self.fc3(out)
        return out

# 定义超参数
input_size = 28 * 28  # 输入大小
hidden_size = 512  # 隐藏层大小
num_classes = 10  # 输出大小(类别数)
batch_size = 100  # 批大小
learning_rate = 0.001  # 学习率
num_epochs = 10  # 训练轮数

# 加载 MNIST 数据集
train_dataset = datasets.MNIST(root='../data/mnist', train=True, transform=transforms.ToTensor(), download=True)
test_dataset = datasets.MNIST(root='../data/mnist', train=False, transform=transforms.ToTensor(), download=True)

train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)

# 实例化 MLP 网络
model = MLP(input_size, hidden_size, num_classes)

现在我们已经定义了 MLP 网络并加载了 MNIST 数据集,接下来使用 PyTorch 的自动求导功能和优化器进行训练。首先,定义损失函数和优化器;然后迭代训练数据并使用优化器更新网络参数。

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)

# 训练网络
for epoch in range(num_epochs):
    for i, (images, labels) in enumerate(train_loader):
        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}')

Epoch [1/10], Step [100/600], Loss: 0.0419
Epoch [1/10], Step [200/600], Loss: 0.0931
Epoch [1/10], Step [300/600], Loss: 0.0609
Epoch [1/10], Step [400/600], Loss: 0.0482
Epoch [1/10], Step [500/600], Loss: 0.1138
Epoch [1/10], Step [600/600], Loss: 0.0533
Epoch [2/10], Step [100/600], Loss: 0.0340
Epoch [2/10], Step [200/600], Loss: 0.0619
Epoch [2/10], Step [300/600], Loss: 0.2061
Epoch [2/10], Step [400/600], Loss: 0.0695
Epoch [2/10], Step [500/600], Loss: 0.0269
Epoch [2/10], Step [600/600], Loss: 0.0330
Epoch [3/10], Step [100/600], Loss: 0.0135
Epoch [3/10], Step [200/600], Loss: 0.0710
Epoch [3/10], Step [300/600], Loss: 0.0089
Epoch [3/10], Step [400/600], Loss: 0.0139
Epoch [3/10], Step [500/600], Loss: 0.0786
Epoch [3/10], Step [600/600], Loss: 0.0331
Epoch [4/10], Step [100/600], Loss: 0.0072
Epoch [4/10], Step [200/600], Loss: 0.0183
Epoch [4/10], Step [300/600], Loss: 0.0291
Epoch [4/10], Step [400/600], Loss: 0.0399
Epoch [4/10], Step [500/600], Loss: 0.0065
Epoch [4/10], Step [600/600], Loss: 0.0306
Epoch [5/10], Step [100/600], Loss: 0.0097
Epoch [5/10], Step [200/600], Loss: 0.0073
Epoch [5/10], Step [300/600], Loss: 0.0327
Epoch [5/10], Step [400/600], Loss: 0.0027
Epoch [5/10], Step [500/600], Loss: 0.0254
Epoch [5/10], Step [600/600], Loss: 0.0136
Epoch [6/10], Step [100/600], Loss: 0.0195
Epoch [6/10], Step [200/600], Loss: 0.0124
Epoch [6/10], Step [300/600], Loss: 0.0065
Epoch [6/10], Step [400/600], Loss: 0.0975
Epoch [6/10], Step [500/600], Loss: 0.0333
Epoch [6/10], Step [600/600], Loss: 0.0346
Epoch [7/10], Step [100/600], Loss: 0.0055
Epoch [7/10], Step [200/600], Loss: 0.0003
Epoch [7/10], Step [300/600], Loss: 0.0014
Epoch [7/10], Step [400/600], Loss: 0.0052
Epoch [7/10], Step [500/600], Loss: 0.0592
Epoch [7/10], Step [600/600], Loss: 0.0139
Epoch [8/10], Step [100/600], Loss: 0.0196
Epoch [8/10], Step [200/600], Loss: 0.0122
Epoch [8/10], Step [300/600], Loss: 0.0211
Epoch [8/10], Step [400/600], Loss: 0.0009
Epoch [8/10], Step [500/600], Loss: 0.0464
Epoch [8/10], Step [600/600], Loss: 0.0207
Epoch [9/10], Step [100/600], Loss: 0.0078
Epoch [9/10], Step [200/600], Loss: 0.0047
Epoch [9/10], Step [300/600], Loss: 0.0029
Epoch [9/10], Step [400/600], Loss: 0.0047
Epoch [9/10], Step [500/600], Loss: 0.0724
Epoch [9/10], Step [600/600], Loss: 0.0219
Epoch [10/10], Step [100/600], Loss: 0.0008
Epoch [10/10], Step [200/600], Loss: 0.0054
Epoch [10/10], Step [300/600], Loss: 0.0015
Epoch [10/10], Step [400/600], Loss: 0.0029
Epoch [10/10], Step [500/600], Loss: 0.0043
Epoch [10/10], Step [600/600], Loss: 0.0025

最后,我们可以在测试数据上评估模型的准确率:

# 测试网络
with torch.no_grad():
    correct = 0
    total = 0
    for images, labels in test_loader:
        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} %')

Accuracy of the network on the 10000 test images: 97.88 %

可以看到训练效果还不错,准确率97.88%。

梗直哥建议:我们这节课言简意赅的讲解了一个例子,主要目的是突出代码实现。如果你在理解方面感觉自己有问题,可以稍微分析一下原因。如果代码看不懂是python的问题,可以考虑补充这方面知识。如果对神经网络原理还希望了解更多,可以选修哥《机器学习必修课:python实战》中神经网络相关章节内容。如果是运行或调参经验缺乏,欢迎入群讨论(微信:gengzhige99)

点击收看更多视频讲解

 


5.2 多层感知机代码实现的评论 (共 条)

分享到微博请遵守国家法律