第一种改进:将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)
根据以下要求对以下代码进行改进以LeNet为基础分别实现如下几种改进并比较改进前与改进后模型的性能。6与7为扩展任务激活函数的改进:将LeNet中的激活函数替换为ReLU。池化方式:平均池化改为最大池化。卷积核大小:将其中一个55的卷积核修改为77正则化方法1:在全连接层后加入Dropout层中间的全连接层可增加维度正则化方法2:卷积层后加入BatchNorm层将卷积核从55修改为33但增加网络

原文地址: https://www.cveoy.top/t/topic/fimz 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录