根据以下要求对以下代码进行改进以LeNet为基础分别实现如下几种改进并比较改进前与改进后模型的性能。6与7为扩展任务激活函数的改进:将LeNet中的激活函数替换为ReLU。池化方式:平均池化改为最大池化。卷积核大小:将其中一个55的卷积核修改为77正则化方法1:在全连接层后加入Dropout层中间的全连接层可增加维度正则化方法2:卷积层后加入BatchNorm层将卷积核从55修改为33但增加网络
第一种改进:将LeNet中的激活函数替换为ReLU
class LeNet_ReLU(nn.Module): def init(self): super(LeNet_ReLU, self).init() self.conv1 = nn.Conv2d(1, 6, 5) self.pool1 = nn.MaxPool2d(2) self.conv2 = nn.Conv2d(6, 16, 5) self.pool2 = nn.MaxPool2d(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(nn.ReLU()(self.conv1(x)))
x = self.pool2(nn.ReLU()(self.conv2(x)))
x = x.view(-1, 16 * 4 * 4)
x = nn.ReLU()(self.fc1(x))
x = nn.ReLU()(self.fc2(x))
x = self.fc3(x)
return x
训练模型
model = LeNet_ReLU() criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=learning_rate)
train_loss_list = [] test_loss_list = [] train_acc_list = [] test_acc_list = []
for epoch in range(epochs): train_loss = 0 train_acc = 0
# 训练模型
model.train()
for i, (images, labels) in enumerate(train_loader):
optimizer.zero_grad()
outputs = model(images)
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(train_loader.dataset)
train_acc /= len(train_loader.dataset)
train_loss_list.append(train_loss)
train_acc_list.append(train_acc)
# 测试模型
model.eval()
with torch.no_grad():
test_loss = 0
test_acc = 0
for images, labels in test_loader:
outputs = model(images)
loss = criterion(outputs, labels)
test_loss += loss.item()
_, predicted = torch.max(outputs.data, 1)
test_acc += (predicted == labels).sum().item()
test_loss /= len(test_loader.dataset)
test_acc /= len(test_loader.dataset)
test_loss_list.append(test_loss)
test_acc_list.append(test_acc)
# 打印训练和测试结果
print('Epoch [{}/{}], Train Loss: {:.4f}, Train Acc: {:.4f}, Test Loss: {:.4f}, Test Acc: {:.4f}'
.format(epoch+1, epochs, train_loss, train_acc, test_loss, test_acc))
绘制损失函数曲线
plt.plot(train_loss_list, label='Train Loss') plt.plot(test_loss_list, label='Test Loss') plt.legend(loc='upper right') plt.xlabel('Epoch') plt.ylabel('Loss') plt.show()
绘制分类正确率曲线
plt.plot(train_acc_list, label='Train Acc') plt.plot(test_acc_list, label='Test Acc') plt.legend(loc='lower right') plt.xlabel('Epoch') plt.ylabel('Accuracy') plt.show()
保存模型
torch.save(model.state_dict(), 'lenet_relu.pth')
加载模型
model.load_state_dict(torch.load('lenet_relu.pth'))
使用测试集测试模型性能,并展示混淆矩阵
confusion_matrix = np.zeros((10, 10)) model.eval() with torch.no_grad(): for images, labels in test_loader: outputs = model(images) _, predicted = torch.max(outputs.data, 1) for i, j in zip(labels, predicted): confusion_matrix[i, j] += 1
print(confusion_matrix)
扩充测试集
rotated_test_dataset = datasets.FashionMNIST( root='data', train=False, transform=transforms.Compose([ transforms.ToTensor(), transforms.RandomRotation(45) ]), download=True )
rotated_test_loader = torch.utils.data.DataLoader( dataset=rotated_test_dataset, batch_size=batch_size, shuffle=False )
测试模型在扩充后的测试集上的性能
model.eval() with torch.no_grad(): test_loss = 0 test_acc = 0 for images, labels in rotated_test_loader: outputs = model(images) loss = criterion(outputs, labels)
test_loss += loss.item()
_, predicted = torch.max(outputs.data, 1)
test_acc += (predicted == labels).sum().item()
test_loss /= len(rotated_test_loader.dataset)
test_acc /= len(rotated_test_loader.dataset)
print('Test Loss: {:.4f}, Test Acc: {:.4f}'.format(test_loss, test_acc)
原文地址: https://www.cveoy.top/t/topic/fimz 著作权归作者所有。请勿转载和采集!