PyTorch搭建ResNet34实现手势分类时训练损失不下降问题求助
问题分析
你代码里存在4处核心错误,直接导致模型完全无法训练:
- Residual Block前向传播逻辑错误:
Block34的forward方法既丢失了第二层卷积conv_b、归一化bn_b的调用,还重复计算了第一层卷积,同时覆盖了ReLU激活的结果 - 损失函数与输出层不匹配:PyTorch的
nn.CrossEntropyLoss内部已经集成了Softmax计算,输出层额外加F.softmax会导致梯度被压缩,模型无法更新 - 学习率设置不合理:Adam优化器的默认学习率为
1e-3,你设置的0.75步长过大,参数更新直接偏离最优区间 - 全连接层输入维度计算错误:平均池化后flatten的维度计算逻辑错误,部分输入尺寸下会触发维度不匹配报错
修复方案
- 修正
Block34的前向传播逻辑,补全残差块的完整计算流程:
def forward(self,x): shortcut=x # 第一层卷积+激活 out = F.relu(self.bn_a(self.conv_a(x))) # 第二层卷积+归一化,残差相加前不做激活 out = self.bn_b(self.conv_b(out)) if self.residual: shortcut = self.bn_s(self.conv_s(shortcut)) # 残差相加后再做ReLU激活 return F.relu(out + shortcut)
- 移除ResNet34输出层的Softmax操作,直接返回全连接层的原始输出:
# 原代码 return F.softmax(out) 修改为: return out
- 调整优化器学习率到合理区间:
# 原代码 optimizer = optim.Adam(classifier.parameters(), lr=0.75) 修改为: optimizer = optim.Adam(classifier.parameters(), lr=1e-4) # 小样本场景可以用更小的学习率
- 修正全连接层的flatten逻辑,避免维度计算错误:
# 原代码 c,h = out.shape[1], out.shape[2] out = self.fc6(out.view(-1,c*h*h)) 修改为: out = torch.flatten(out, 1) out = self.fc6(out)
- 可选优化:将训练轮次提升到50轮以上,10轮不足以让小数据集充分收敛,同时可加入学习率衰减策略进一步提升训练效果。
内容的提问来源于stack exchange,提问作者Jatin Katyal
相关产品推荐
相关产品推荐

