python打卡day41@浙大疏锦行
知识回顾
1. 数据增强
2. 卷积神经网络定义的写法
3. batch归一化:调整一个批次的分布,常用与图像数据
4. 特征图:只有卷积操作输出的才叫特征图
5. 调度器:直接修改基础学习率
卷积操作常见流程如下:
1. 输入 → 卷积层 → Batch归一化层(可选) → 池化层 → 激活函数 → 下一层
2. Flatten -> Dense (with Dropout,可选) -> Dense (Output)
作业:尝试手动修改下不同的调度器和CNN的结构,观察训练的差异。
一、CNN结构修改示例
# 基础CNN结构
class BasicCNN(nn.Module):def __init__(self):super().__init__()self.conv_layers = nn.Sequential(nn.Conv2d(3, 32, 3, padding=1), # 修改1:调整卷积核数量nn.BatchNorm2d(32), # 修改2:添加/移除BN层nn.MaxPool2d(2),nn.ReLU(),nn.Conv2d(32, 64, 5, padding=2), # 修改3:调整卷积核大小nn.AdaptiveAvgPool2d(1) # 修改4:更换池化方式)self.fc = nn.Linear(64, 10)# 深度可分离卷积示例
class DepthwiseCNN(nn.Module):def __init__(self):super().__init__()self.layers = nn.Sequential(nn.Conv2d(3, 32, 3, groups=32), # 深度可分离卷积nn.Conv2d(32, 64, 1), # 逐点卷积nn.BatchNorm2d(64),nn.SiLU() # 修改5:更换激活函数)
二、学习率调度器修改示例
# 基础训练配置
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)# 方案1:阶梯下降
scheduler1 = torch.optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.1)# 方案2:余弦退火
scheduler2 = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer,T_max=10)# 方案3:带热启动的余弦退火
scheduler3 = torch.optim.lr_scheduler.CosineAnnealingWarmRestarts(optimizer,T_0=5,T_mult=2)# 训练循环中更新
for epoch in range(10):# ...训练步骤...scheduler1.step() # 切换不同调度器观察效果
三、实验建议对比项
① 卷积核数量对比
- 小通道数 (如32/64):训练快、显存占用低,但可能欠拟合
- 大通道数 (如64/128):模型容量大,但计算量高,需注意过拟合
②BatchNorm使用对比
- 带BN层 :训练稳定,允许更大学习率
- 不带BN层 :对初始化敏感,适合小批量数据
③激活函数对比
- ReLU :计算高效,但可能导致神经元死亡
- Swish :梯度更平滑,适合深层网络
④学习率调度器对比
- StepLR :阶梯式下降,适合离散式优化
- Cosine :平滑调整,适合连续训练
四、关键代码插入位置
# ...原有训练代码...
for epoch in range(epochs):# 插入学习率监控current_lr = optimizer.param_groups[0]['lr']print(f'Epoch {epoch}, LR: {current_lr:.6f}')# 插入特征图可视化(可选)if epoch % 5 == 0:visualize_features(model.conv1.weight)