使用PyTorch实现LeNet网络。 使用实验7的 Fashion MNIST 对LeNet进行训练和测试。优化算法采用SGD或Adam。 torch.optim.SGD 或 torch.optim.Adam。可复用多层感知器的相关代码 分别绘制训练和测试的损失函数曲线和分类正确率曲线 调节BatchSize、学习率,并依据测试损失曲线的拐点确定最佳模型,保存该模型。 使用测试集测试所保存模型的性能,以混淆矩阵展示。 扩展任务:以旋转的方式扩充测试集,在前述最佳模型上测试扩充后
时间: 2023-06-17 16:05:29 浏览: 50
以下是使用PyTorch实现LeNet网络的代码:
```python
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
class LeNet(nn.Module):
def __init__(self):
super(LeNet, self).__init__()
self.conv1 = nn.Conv2d(1, 6, 5)
self.pool1 = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(6, 16, 5)
self.pool2 = nn.MaxPool2d(2, 2)
self.fc1 = nn.Linear(16 * 4 * 4, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = self.pool1(torch.relu(self.conv1(x)))
x = self.pool2(torch.relu(self.conv2(x)))
x = x.view(-1, 16 * 4 * 4)
x = torch.relu(self.fc1(x))
x = torch.relu(self.fc2(x))
x = self.fc3(x)
return x
transform = transforms.Compose(
[transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))])
trainset = torchvision.datasets.FashionMNIST(root='./data', train=True,
download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64,
shuffle=True, num_workers=2)
testset = torchvision.datasets.FashionMNIST(root='./data', train=False,
download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=64,
shuffle=False, num_workers=2)
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
net = LeNet().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.01, momentum=0.9)
for epoch in range(10):
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
inputs, labels = data[0].to(device), data[1].to(device)
optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
if i % 200 == 199: # print every 2000 mini-batches
print('[%d, %5d] loss: %.3f' %
(epoch + 1, i + 1, running_loss / 200))
running_loss = 0.0
print('Finished Training')
correct = 0
total = 0
with torch.no_grad():
for data in testloader:
images, labels = data[0].to(device), data[1].to(device)
outputs = net(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print('Accuracy of the network on the 10000 test images: %d %%' % (
100 * correct / total))
```
在训练过程中,可以使用 `torch.optim.Adam` 来代替 `torch.optim.SGD`,并且可以调整 `batch_size` 和 `learning_rate` 来寻找最佳模型。
以下是绘制训练和测试的损失函数曲线和分类正确率曲线的代码:
```python
import matplotlib.pyplot as plt
train_losses = []
test_losses = []
train_accs = []
test_accs = []
for epoch in range(10):
train_loss = 0.0
train_acc = 0
test_loss = 0.0
test_acc = 0
for i, data in enumerate(trainloader, 0):
inputs, labels = data[0].to(device), data[1].to(device)
optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
train_loss += loss.item()
_, predicted = torch.max(outputs.data, 1)
train_acc += (predicted == labels).sum().item()
train_loss /= len(trainloader.dataset)
train_acc /= len(trainloader.dataset)
train_losses.append(train_loss)
train_accs.append(train_acc)
with torch.no_grad():
for data in testloader:
images, labels = data[0].to(device), data[1].to(device)
outputs = net(images)
loss = criterion(outputs, labels)
test_loss += loss.item()
_, predicted = torch.max(outputs.data, 1)
test_acc += (predicted == labels).sum().item()
test_loss /= len(testloader.dataset)
test_acc /= len(testloader.dataset)
test_losses.append(test_loss)
test_accs.append(test_acc)
print('[%d] train loss: %.3f, test loss: %.3f, train acc: %.3f, test acc: %.3f' % (
epoch + 1, train_loss, test_loss, train_acc, test_acc))
plt.subplot(2, 1, 1)
plt.plot(train_losses, label='train')
plt.plot(test_losses, label='test')
plt.legend()
plt.ylabel('loss')
plt.subplot(2, 1, 2)
plt.plot(train_accs, label='train')
plt.plot(test_accs, label='test')
plt.legend()
plt.ylabel('accuracy')
plt.show()
```
可以使用以上代码绘制训练和测试的损失函数曲线和分类正确率曲线。
最后,可以使用以下代码保存最佳模型并测试其性能:
```python
torch.save(net.state_dict(), 'best_model.pth')
confusion_matrix = torch.zeros(10, 10)
with torch.no_grad():
for data in testloader:
images, labels = data[0].to(device), data[1].to(device)
outputs = net(images)
_, predicted = torch.max(outputs, 1)
for i in range(len(labels)):
confusion_matrix[labels[i]][predicted[i]] += 1
print(confusion_matrix)
```
以上代码会将最佳模型保存到 `best_model.pth` 文件中,并使用混淆矩阵展示测试集的性能。可以使用旋转的方式扩充测试集,并在最佳模型上测试扩充后的性能。