AlexNet训练自定义图像数据集准确率约1/7,模型未收敛求助
解决AlexNet训练无进展(准确率维持随机水平)的方案
1. 补充输入数据归一化
AlexNet要求输入图像做均值方差归一化,你的预处理仅完成Resize和ToTensor,缺少关键的归一化步骤,会导致模型训练不稳定。修改图像变换管道:
img_transform = transforms.Compose([ transforms.Resize((227, 227)), transforms.ToTensor(), # 采用ImageNet标准均值方差,匹配AlexNet的训练逻辑 transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ])
2. 优化器添加动量
原AlexNet使用带动量的SGD,你当前的SGD未设置momentum,收敛效率极低。调整优化器:
optimizer = torch.optim.SGD(network.parameters(), lr=Learning_rate, momentum=0.9, weight_decay=5e-4)
初始可尝试用0.01的学习率配合动量,观察损失是否出现下降趋势。
3. 检查训练/验证函数的正确性
确保AlexNet_train和AlexNet_Val函数实现符合标准流程:
- 训练时必须调用
network.train(),验证时调用network.eval() - 训练循环中需先执行
optimizer.zero_grad()清零梯度,再反向传播并更新参数 - 准确率计算需正确取模型输出的argmax作为预测类别,与真实标签对比
示例训练函数框架:
def AlexNet_train(network, dataloader, optimizer, loss_fn): network.train() total_loss = 0.0 correct = 0 total = 0 for imgs, labels in dataloader: imgs, labels = imgs.to(device), labels.to(device) optimizer.zero_grad() outputs = network(imgs) loss = loss_fn(outputs, labels) loss.backward() optimizer.step() total_loss += loss.item() * imgs.size(0) _, preds = torch.max(outputs.data, 1) total += labels.size(0) correct += (preds == labels).sum().item() avg_loss = total_loss / total avg_acc = correct / total return avg_loss, avg_acc
示例验证函数框架:
def AlexNet_Val(network, dataloader, loss_fn): network.eval() total_loss = 0.0 correct = 0 total = 0 with torch.no_grad(): for imgs, labels in dataloader: imgs, labels = imgs.to(device), labels.to(device) outputs = network(imgs) loss = loss_fn(outputs, labels) total_loss += loss.item() * imgs.size(0) _, preds = torch.max(outputs.data, 1) total += labels.size(0) correct += (preds == labels).sum().item() avg_loss = total_loss / total avg_acc = correct / total return avg_loss, avg_acc
4. 优化模型权重初始化
默认权重初始化可能引发梯度消失/爆炸问题,手动给卷积层和全连接层添加初始化逻辑:
在AlexNet类的__init__函数末尾添加:
# 针对ReLU激活的网络做Kaiming初始化 for m in self.modules(): if isinstance(m, nn.Conv2d): nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu') if m.bias is not None: nn.init.constant_(m.bias, 0) elif isinstance(m, nn.Linear): nn.init.normal_(m.weight, 0, 0.01) nn.init.constant_(m.bias, 0)
5. 排查数据集问题
- 确认数据集目录结构符合ImageFolder要求:每个类别对应独立子文件夹,子文件夹内为该类图像
- 检查所有图像均为3通道RGB格式,若存在灰度图,在预处理中添加
transforms.Grayscale(num_output_channels=3) - 验证训练集类别分布是否均衡,极端不平衡会导致模型难以学习
- 随机抽取样本,检查数据加载的图像与标签是否匹配
6. 调整学习率策略
若带动量的SGD仍不收敛,可尝试:
- 先用0.01的学习率训练5-10个epoch,观察损失变化,之后每10个epoch将学习率乘以0.1逐步降低
- 改用Adam优化器:
optimizer = torch.optim.Adam(network.parameters(), lr=0.0001, weight_decay=5e-4),Adam对学习率的容忍度更高
内容的提问来源于stack exchange,提问作者smnie
相关产品推荐
相关产品推荐

