CNN模型异常问题:同一图像多次预测结果不一致的原因探究
首先直接说结论:你的预测结果每次波动是测试阶段用了随机数据增强导致的,而更深层的问题是你的模型根本没学会任何分类能力——从训练日志里loss一直卡在0.693左右就能看出来,这是模型在随机猜测时的典型BCELoss数值(ln(0.5)≈-0.693)。
一、预测结果波动的直接原因:随机裁剪在捣乱
你定义的训练transform里包含了transforms.RandomCrop((299, 299)),这个操作是随机截取图像区域——每次处理同一张图时,都会从356x356的图像里随机切出一个299x299的块。这就导致每次输入模型的图像其实是不一样的,预测结果自然会变。
训练时用随机裁剪是为了做数据增强,提升泛化能力,但预测时必须用固定的预处理逻辑,不能有随机操作。你需要单独定义一个测试用的transform:
test_transform = transforms.Compose( [ transforms.Resize((299, 299)), # 直接resize到模型要求的输入尺寸,不要随机裁剪 transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)), ] )
然后预测时改用这个transform,同时加上torch.no_grad()避免不必要的梯度计算,还要确保tensor和模型在同一个设备上:
model.eval() img = Image.open('train/cat.22.png').convert("RGB") img_t = test_transform(img) batch_t = torch.unsqueeze(img_t, 0).to(device) # 和模型保持同设备(GPU/CPU) with torch.no_grad(): out = model(batch_t) print(out)
二、模型未有效训练的核心问题(loss≈0.693)
你的模型本质上是在瞎猜,根本没学到猫狗的特征,主要原因可能有这几点:
1. 训练样本量太少
你只给了模型162个训练样本,这个数量对于微调InceptionV3这种大型预训练模型来说远远不够,模型根本无法学到有效的分类模式。建议:
- 增加训练数据量(如果可以的话)
- 换用更轻量的模型(比如MobileNetV2)
- 训练时加更多数据增强(比如
RandomHorizontalFlip、RandomRotation等)
2. 学习率太低
你用的1e-5学习率对于只训练全连接层的微调来说,可能偏慢,导致模型参数更新极其缓慢,甚至没机会收敛。可以尝试把学习率调到1e-4或5e-5,观察loss是否下降。
3. 预训练模型冻结过度
你的代码里只让全连接层(fc)的参数参与训练,但InceptionV3的fc层是随机初始化的,仅靠162个样本训练一个随机层,很难学到东西。可以尝试解冻部分顶层卷积层(比如最后2-3个Inception模块),让模型能结合预训练特征进行微调:
# 修改冻结逻辑,解冻顶层部分卷积层 for name, param in model.inception.named_parameters(): if "fc" in name or "Mixed_7" in name: # 解冻fc层和最后一个Inception模块 param.requires_grad = True else: param.requires_grad = train_CNN
4. 检查标签和数据加载是否正确
确认你的train_csv.csv里的标签完全正确:所有猫的图像对应label=0,狗对应label=1;另外检查数据集类读取图像时,有没有出现图像损坏、路径错误的情况。
先解决预测阶段的随机裁剪问题,让结果稳定下来,再针对模型训练无效的问题调整数据、学习率或冻结策略,慢慢就能看到模型效果提升了。
内容的提问来源于stack exchange,提问作者user164863

