踩坑:pytorch中eval模式下结果远差于train模式

首先,eval模式和train模式得到不同的结果是正常的。我的模型中,eval模式和train模式不同之处在于Batch Normalization和Dropout。Dropout比较简单,在train时会丢弃一部分连接,在eval时则不会。Batch Normalization,在train时不仅使用了当前batch的均值和方差,也使用了历史batch统计上的均值和方差,并做一个加权平均(momentum参数)。在test时,由于此时batchsize不一定一致,因此不再使用当前batch的均值和方差,仅使用历史训练时的统计值。

我出bug的现象是,train模式下可以收敛,但一旦在测试中切换到了eval模式,结果就很差。如果在测试中仍沿用train模式,反而可以得到不错的结果。为了确保是程序bug而不是算法本身就不适合于预测,我在测试时再次使用了训练集,正常情况下此时应发生过拟合,正确率一定会很高,然而eval模式下正确率仍然很低。参照网上的一些说法(Performance highly degraded when eval() is activated in the test phase
),我调大了batchsize,降低了BN层的momentum,检查了是否存在不同层使用相同BN层的bug,均不见效。有一种方法说应在BN层设置track_running_stats为False,它虽然带来了好的效果,但实际上它只不过是不用eval模式,切回train模式罢了

PyTorch ,`eval()` 函数主要用于将模型设置为评估模式。在评估模式下,模型不会更新梯度,从而可以更快地进行前向传播。以下是 `eval()` 函数的一些常见用法: 1. 设置模型为评估模式 在训练模型时,通常使用 `model.train()` 将模型设置为训练模式,使用 `model.eval()` 将模型设置为评估模式。在评估模式下,模型的一些层(例如 Dropout)会被禁用,从而确保在评估时得到一致的结果。 例如,以下代码将模型设置为评估模式: ``` model.eval() ``` 2. 计算模型的验证损失 在训练过程,通常需要计算模型在验证集上的损失。在计算损失之前,需要将模型设置为评估模式,以确保在计算损失时不会更新梯度。 例如,以下代码计算模型在验证集上的损失: ``` model.eval() with torch.no_grad(): for batch_idx, (data, target) in enumerate(val_loader): output = model(data) loss = criterion(output, target) val_loss += loss.item() * data.size(0) val_loss /= len(val_loader.dataset) ``` 在上面的代码,使用 `with torch.no_grad()` 将所有计算操作都设置为不需要计算梯度,从而提高计算效率。 3. 部署模型 在将模型部署到生产环境时,通常需要将模型设置为评估模式,以确保模型的输出是确定性的,并且在不同的硬件和操作系统上的结果是一致的。 例如,以下代码加载模型并将其设置为评估模式: ``` model = MyModel() model.load_state_dict(torch.load('model.pt')) model.eval() ``` 在上面的代码,使用 `load_state_dict()` 函数加载模型的权重,然后使用 `eval()` 函数将模型设置为评估模式
评论 36
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值