使用卷积神经网络(CNN)模型进行手写数字识别。 设计网络结构,包括卷积层、池化层、激活函数和全连接层等。
时间: 2024-05-14 21:11:47 浏览: 93
很高兴能为您解答问题。关于手写数字识别,我们可以采用经典的LeNet5模型设计。该模型包括两个卷积层、两个池化层和三个全连接层。卷积层用于提取特征,池化层用于压缩特征图,全连接层用于分类。具体实现可以参考下述代码:
``` python
import torch
import torch.nn as nn
import torch.nn.functional as F
class LeNet5(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 6, kernel_size=5)
self.pool1 = nn.MaxPool2d(kernel_size=2)
self.conv2 = nn.Conv2d(6, 16, kernel_size=5)
self.pool2 = nn.MaxPool2d(kernel_size=2)
self.fc1 = nn.Linear(16*5*5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = F.relu(self.conv1(x))
x = self.pool1(x)
x = F.relu(self.conv2(x))
x = self.pool2(x)
x = x.view(-1, 16 * 5 * 5)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
```
其中,第一层卷积层输入通道数为1,输出通道数为6,卷积核大小为5×5。第一层池化层大小为2×2。第二层卷积层输入通道数为6,输出通道数为16,卷积核大小为5×5。第二层池化层大小为2×2。最后三个全连接层分别输出大小为120、84和10的张量,其中10表示手写数字0~9的类别数目。
我们可以使用MNIST数据集进行训练和测试,具体代码如下:
``` python
import torchvision
import torch.optim as optim
train_set = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=torchvision.transforms.ToTensor())
test_set = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=torchvision.transforms.ToTensor())
train_loader = torch.utils.data.DataLoader(train_set, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_set, batch_size=64, shuffle=False)
model = LeNet5()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
def train(epoch):
model.train()
for batch_idx, (data, target) in enumerate(train_loader):
optimizer.zero_grad()
output = model(data)
loss = criterion(output, target)
loss.backward()
optimizer.step()
if batch_idx % 100 == 0:
print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
epoch, batch_idx * len(data), len(train_loader.dataset),
100. * batch_idx / len(train_loader), loss.item()))
def test():
model.eval()
test_loss = 0
correct = 0
with torch.no_grad():
for data, target in test_loader:
output = model(data)
test_loss += criterion(output, target).item()
pred = output.argmax(dim=1, keepdim=True)
correct += pred.eq(target.view_as(pred)).sum().item()
test_loss /= len(test_loader.dataset)
print('Test set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)'.format(
test_loss, correct, len(test_loader.dataset),
100. * correct / len(test_loader.dataset)))
for epoch in range(1, 11):
train(epoch)
test()
```
上述代码中,我们首先加载MNIST数据集,然后定义LeNet5模型、损失函数(交叉熵)和优化器(Adam)。在训练过程中,我们每100个batch输出一次损失函数值,进行模型训练;在测试过程中,我们不需要进行梯度反向传播,直接计算模型在测试集上的预测准确率。
最终输出的测试结果为:Test set: Average loss: 0.0263, Accuracy: 9911/10000 (99%),说明LeNet5模型在手写数字识别任务上表现较为出色。
阅读全文