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

ResNet在Train与Eval模式下输出差异过大的技术咨询

Train/Eval模式下ResNet输出差异显著是否影响模型性能?

我正尝试在PyTorch中实现ResNet,但发现Train模式与Eval模式下的前向传播输出差异显著。由于Train和Eval模式仅会影响BatchNorm和Dropout,我不确定该结果是否合理。

测试代码

import torch
from torch import nn
from torchvision import models

class resnet_lstm(torch.nn.Module):
    def __init__(self):
        super(resnet_lstm, self).__init__()
        resnet = models.resnet50(pretrained=True)
        self.share = torch.nn.Sequential()
        self.share.add_module("conv1", resnet.conv1)
        self.share.add_module("bn1", resnet.bn1)  # Use BatchNorm3d
        self.share.add_module("relu", resnet.relu)
        self.share.add_module("maxpool", resnet.maxpool)
        self.share.add_module("layer1", resnet.layer1)
        self.share.add_module("layer2", resnet.layer2)
        self.share.add_module("layer3", resnet.layer3)
        self.share.add_module("layer4", resnet.layer4)
        self.share.add_module("avgpool", resnet.avgpool)
        self.fc = nn.Sequential(nn.Linear(2048, 512),
                                nn.ReLU(),
                                nn.Linear(512, 7))

    def forward(self, x):
        x = x.view(-1, 3, 224, 224)
        x = self.share(x)
        return x
    
model = resnet_lstm()

input_ = torch.randn(1, 3, 224, 224)
model.train()
print("train mode output", model(input_))
model.eval()
print("eval mode output", model(input_))

终端输出

train mode output tensor([[[[0.3603]],

         [[0.5518]],

         [[0.4599]],

         ...,

         [[0.3381]],

         [[0.4445]],

         [[0.3481]]]], grad_fn=<MeanBackward1>)
eval mode output tensor([[[[0.1582]],

         [[0.1822]],

         [[0.0000]],

         ...,

         [[0.0567]],

         [[0.0054]],

         [[0.3605]]]], grad_fn=<MeanBackward1>)

解答

这种差异是完全正常且合理的,核心原因是BatchNorm在Train和Eval模式下的行为逻辑截然不同:

  • 训练模式:BatchNorm会使用当前输入批次的均值和方差做归一化,同时持续更新内部维护的全局均值、方差统计量
  • 评估模式:BatchNorm会直接调用训练阶段累计下来的全局均值和方差做归一化,不再更新统计量

你用的是预训练ResNet,它的BatchNorm统计量是基于ImageNet全量数据集累计得到的。而测试时你用的是随机生成的输入,训练模式下会用这个随机批次的统计量计算,和预训练的全局统计量偏差极大,自然会导致输出差异明显。

这种差异不会损害模型性能,只要严格遵循「训练时开model.train(),推理时开model.eval()」的规范即可:训练阶段用批次统计量能让模型更好地适配当前数据分布,推理阶段用全局统计量能保证输出的稳定性和一致性。

另外注意代码里的注释写了"Use BatchNorm3d",但ResNet的bn1实际是BatchNorm2d,这里别混淆,不过不影响当前问题的结论。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 09:21:19