You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

预训练VGG实现混凝土裂纹二分类时训练验证损失不下降求助

问题解决方案

你遇到的损失固定为0.693(二分类交叉熵的初始随机值)是代码存在多处逻辑错误导致模型完全没有被正常训练,具体错误及修正方式如下:

  • 反向传播未实际执行:代码中loss.backward未加括号,只是引用了方法本身,没有触发梯度计算,模型参数自始至终没有更新
  • 优化器初始化位置错误:optimizer = torch.optim.Adam(net.parameters(), lr=LEARNING_RATE)写在了batch循环内部,每处理一个batch就会重置优化器状态,之前迭代的梯度信息全部丢失
  • 梯度未清零:每次迭代更新参数前没有清空上一轮的梯度,会导致梯度不断叠加,更新逻辑完全混乱
  • 验证损失计算错误:验证集循环内直接对val_loss赋值而非累加,输出的损失仅为最后一个batch的结果,无法反映全局情况
  • 未加载预训练权重:你提到使用预训练VGG,但当前代码是手动从零搭建VGG结构,没有加载官方预训练权重,小数据集下从零训练收敛难度高

修正后的训练代码片段

# 如果你要使用预训练VGG,替换之前手动搭建VGG的部分即可,示例如下:
# net = torchvision.models.vgg16(pretrained=True)
# # 替换最后一层分类头适配二分类
# net.classifier[6] = nn.Linear(4096, 2)

num_epochs = 15
min_val_loss = np.inf
criterion = nn.CrossEntropyLoss()
# 优化器放在循环外,仅初始化一次
optimizer = torch.optim.Adam(net.parameters(), lr=LEARNING_RATE)

for epoch in range(num_epochs):
    train_loss = 0.0
    net.train()
    for data, labels in train_data_loader:
        # 每轮迭代前先清空梯度
        optimizer.zero_grad()
        target = net(data)
        loss = criterion(target, labels)
        # 加括号执行反向传播
        loss.backward()
        optimizer.step()
        train_loss += loss.item() * data.size(0)
    
    val_loss = 0.0
    net.eval()
    # 关闭梯度计算节省显存加快速度
    with torch.no_grad():
        for data, labels in val_data_loader:
            target = net(data)
            loss = criterion(target, labels)
            # 累加所有batch的损失
            val_loss += loss.item() * data.size(0)
    
    # 损失计算除以样本总数而非batch数,结果更准确
    print(f'Epoch {epoch+1} \t\t Training Loss: {train_loss/len(train_data)} \t\t Validation Loss: {val_loss/len(val_data)}')
print('Finished Training')

按照上述内容修正后即可正常训练收敛。

内容的提问来源于stack exchange,提问作者Will

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 19:06:03