简单CNN——作业(补充)
调度器种类
总共训练了15个epoch,结构为三层卷积层 + 两层全连接层。
ReduceLROnPlateau
scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer=optimizer, # 指定要控制的优化器(这里是Adam)mode='min', # 监测的指标是"最小化"(如损失函数)patience=3, # 如果连续3个epoch指标没有改善,才降低LRfactor=0.5 # 降低LR的比例(新LR = 旧LR × 0.5)
)最终测试集准确率为78.50 %,累计平均损失为0.7247



StepLR
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.1) 最终测试集准确率为78.63 %,累计平均损失为0.7534


MultiStepLR
scheduler = optim.lr_scheduler.MultiStepLR(optimizer, milestones=[10, 20, 30], gamma=0.5) 最终测试集准确率为79.17 %,累计平均损失为0.7035


CosineAnnealingLR
scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=10, eta_min=0.0001) 最终测试集准确率为78.05 %,累计平均损失为0.6986,整个训练内波动有点大。


在当前情况下(存在误差,每一个调度器只训练了一次),综合准确率和累计平均损失来看,使用MultiStepLR作为调度器的结果最好
| 调度器 | 测试集准确率 | 训练集准确率 | 累计平均损失 |
| ReduceLROnPlateau | 78.50% | 74.58% | 0.7247 |
| StepLR | 78.63% | 73.80% | 0.7534 |
| MultiStepLR | 79.17% | 75.36% | 0.7035 |
| CosineAnnealingLR | 78.05% | 75.60% | 0.6986 |
CNN结构
增加一层全连接层,测试集准确率为79.06%,累计平均损失为0.7293
def forward(self, x):# 第一个卷积层后接ReLU激活函数和最大池化操作,经过池化后图像尺寸变为原来的一半,这里输出尺寸变为16x16x = self.pool(F.relu(self.conv1(x))) # F.relu()不支持hook,无法监控中间结果# 第二个卷积层后接ReLU激活函数和最大池化操作,输出尺寸变为8x8x = self.pool(F.relu(self.conv2(x))) # 第三个卷积层后接ReLU激活函数和最大池化操作,输出尺寸变为4x4x = self.pool(F.relu(self.conv3(x))) # 将特征图展平为一维向量,以便输入到全连接层x = x.view(-1, 128 * 4 * 4)# 第一个全连接层后接ReLU激活函数x = F.relu(self.fc1(x))# 第二个全连接层后接ReLU激活函数x = F.relu(self.fc2(x))x = self.dropout(x) # p=0.5# 第三个全连接层输出分类结果x = self.fc3(x)return x

