制作PyTorch图像分类CNN速查表,需补充哪些核心组件与模式?
PyTorch CNN图像分类速查表(适用于CIFAR-10等任务)
1. CNN类结构
class MyCNN(nn.Module): def __init__(self): super().__init__() def forward(self, x): return x
2. 卷积层
nn.Conv2d( in_channels=3, out_channels=32, kernel_size=3 )
常见变体:
nn.Conv2d(3, 32, 3) nn.Conv2d(3, 32, kernel_size=3) nn.Conv2d(3, 32, kernel_size=3, padding=1) nn.Conv2d(3, 32, kernel_size=5) nn.Conv2d(3, 32, kernel_size=3, stride=2) nn.Conv2d(3, 32, kernel_size=3, dilation=2)
示例:
nn.Conv2d(3, 32, 3, padding=1)
此操作可保留32×32的空间尺寸。
3. 激活函数
nn.ReLU()
或
F.relu(x)
4. 池化层
nn.MaxPool2d( kernel_size=2, stride=2 )
nn.AvgPool2d( kernel_size=2, stride=2 )
nn.AdaptiveAvgPool2d((1, 1))
5. 批量归一化
self.conv1 = nn.Conv2d(3, 32, 3, padding=1) self.bn1 = nn.BatchNorm2d(32)
前向传播:
x = self.conv1(x) x = self.bn1(x) x = F.relu(x)
6. Dropout
nn.Dropout(0.5)
nn.Dropout2d(0.3)
7. 展平操作
torch.flatten(x, 1)
8. 全连接层
self.fc1 = nn.Linear( in_features=128 * 4 * 4, out_features=512 ) self.dropout = nn.Dropout(p=0.5) self.fc2 = nn.Linear( in_features=512, out_features=10 )
前向传播:
x = self.conv3(x) x = self.bn3(x) x = F.relu(x) x = self.pool3(x) x = torch.flatten(x, 1) x = F.relu(self.fc1(x)) x = self.dropout(x) x = self.fc2(x)
9. Sequential块
self.block1 = nn.Sequential( nn.Conv2d(3, 32, 3, padding=1), nn.BatchNorm2d(32), nn.ReLU(), nn.MaxPool2d(2) )
10. 训练循环
for images, labels in train_loader: optimizer.zero_grad() outputs = model(images) loss = criterion(outputs, labels) loss.backward() optimizer.step()
补充内容:初中级CNN常用核心模块/模式
11. 分组卷积(Grouped Convolution)
用于减少参数量,是轻量模型的基础结构:
# 将输入通道分成2组,每组对应输出通道的一半 nn.Conv2d(32, 64, kernel_size=3, padding=1, groups=2)
12. 深度可分离卷积(Depthwise Separable Convolution)
先做逐通道卷积提取空间特征,再用1×1卷积融合通道特征,大幅降低计算量:
# 逐通道卷积:每个输入通道单独卷积 self.depthwise = nn.Conv2d(32, 32, kernel_size=3, padding=1, groups=32) # 点卷积:跨通道融合特征 self.pointwise = nn.Conv2d(32, 64, kernel_size=1)
前向传播:
x = self.depthwise(x) x = F.relu(x) x = self.pointwise(x) x = F.relu(x)
13. 残差连接(Residual Connection)
解决深度网络退化问题,是ResNet的核心,基础用法如下:
class ResidualBlock(nn.Module): def __init__(self, in_channels, out_channels, stride=1): super().__init__() self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1, stride=stride) self.bn1 = nn.BatchNorm2d(out_channels) self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1) self.bn2 = nn.BatchNorm2d(out_channels) # 输入输出维度不一致时,用1×1卷积调整 self.shortcut = nn.Sequential() if stride != 1 or in_channels != out_channels: self.shortcut = nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride), nn.BatchNorm2d(out_channels) ) def forward(self, x): residual = self.shortcut(x) x = F.relu(self.bn1(self.conv1(x))) x = self.bn2(self.conv2(x)) x += residual x = F.relu(x) return x
14. 学习率调度器(Learning Rate Scheduler)
动态调整学习率,提升模型收敛效果:
optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # 每隔10个epoch将学习率乘以0.1 scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1) # 训练循环中添加 for epoch in range(20): for images, labels in train_loader: # 原有训练步骤 optimizer.zero_grad() outputs = model(images) loss = criterion(outputs, labels) loss.backward() optimizer.step() scheduler.step() # 每个epoch结束后更新学习率
15. 验证循环
监控模型泛化能力,完整训练流程必备:
model.eval() # 切换到评估模式,关闭dropout、batchnorm训练行为 val_loss = 0 correct = 0 total = 0 with torch.no_grad(): # 禁用梯度计算,节省资源 for images, labels in val_loader: outputs = model(images) loss = criterion(outputs, labels) val_loss += loss.item() _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() val_loss /= len(val_loader) val_acc = 100 * correct / total print(f'Epoch {epoch+1}, Val Loss: {val_loss:.4f}, Val Acc: {val_acc:.2f}%') model.train() # 切回训练模式
16. 更多常用激活函数
nn.LeakyReLU(negative_slope=0.1) # 缓解ReLU死神经元问题 nn.GELU() # 平滑激活,适配更多场景 nn.Sigmoid() # 二分类输出常用 nn.Softmax(dim=1) # 多分类输出时将logits转为概率分布
17. 权重初始化
合理初始化加速模型收敛:
# 对卷积层、全连接层做He初始化(适配ReLU类激活) def init_weights(m): if isinstance(m, nn.Conv2d) or isinstance(m, nn.Linear): nn.init.kaiming_normal_(m.weight, mode='fan_in', nonlinearity='relu') if m.bias is not None: nn.init.constant_(m.bias, 0) model.apply(init_weights) # 应用到整个模型
内容的提问来源于stack exchange,提问作者Sabby Smith
相关产品推荐
相关产品推荐

