python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > PyTorch model.eval()使用

PyTorch中model.eval()使用与作用小结

作者:Geoking.

本文主要介绍了PyTorch中model.eval()使用与作用小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、🚀model.train()与model.eval()是什么?

使用 PyTorch 进行深度学习训练时,我们经常会看到如下的代码片段:

model.train()
# 训练阶段...

model.eval()
# 验证或测试阶段...

很多初学者第一次看到时都会问:

“为什么要在测试前加一句 model.eval()?
不加行不行?到底起了什么作用?”

eval,英文意即为评估

在 PyTorch 中,每个神经网络模型都是一个 nn.Module 的子类。
nn.Module 中有两个非常重要的模式:

模式含义常用于
model.train()开启训练模式(默认)模型训练阶段
model.eval()开启评估模式验证、测试阶段

👉 它们的区别不在于是否计算梯度
而在于模型内部某些层(如 Dropout、BatchNorm)的行为发生变化

二、为什么需要model.eval()

神经网络中有些层在“训练”和“推理”阶段需要不同的行为,例如:

Dropout 层

如果你不调用 model.eval()
那在测试阶段 Dropout 仍然会随机丢弃神经元,导致结果不稳定、性能下降

Batch Normalization 层(BN层)

如果不切换到 eval 模式,
BN 层会继续更新统计信息,导致推理结果偏差甚至错误

结论:

model.eval() 的核心作用是让模型中某些层(Dropout、BatchNorm)进入“推理模式”。

三、model.eval()与torch.no_grad()的区别

这两个经常一起出现,很多人容易混淆:

功能是否影响 Dropout/BN是否停止计算梯度使用场景
model.eval()✅ 是❌ 否切换模型状态(推理模式)
torch.no_grad()❌ 否✅ 是禁止梯度计算,加快推理速度、节省显存

因此,推理时我们通常会这样写👇:

model.eval()  # 切换为推理模式
with torch.no_grad():  # 不计算梯度
    outputs = model(inputs)

四、完整示例:对比train()和eval()

让我们用一个小例子直观看看区别 👇

import torch
import torch.nn as nn

# 一个简单的网络,包含 Dropout
class SimpleNet(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc = nn.Linear(4, 4)
        self.dropout = nn.Dropout(p=0.5)

    def forward(self, x):
        return self.dropout(self.fc(x))

# 创建模型和输入
x = torch.ones(4)
model = SimpleNet()

# 训练模式
model.train()
print("Train Mode Output:")
for _ in range(3):
    print(model(x))

# 推理模式
model.eval()
print("\nEval Mode Output:")
for _ in range(3):
    print(model(x))

输出对比

Train Mode Output:
tensor([-0.0000, -1.4387,  0.7793,  0.0000], grad_fn=<MulBackward0>)
tensor([-0.0000, -1.4387,  0.0000,  0.0000], grad_fn=<MulBackward0>)
tensor([-0.0000, -1.4387,  0.7793,  0.0000], grad_fn=<MulBackward0>)

Eval Mode Output:
tensor([-0.2442, -0.7194,  0.3897,  0.9389], grad_fn=<ViewBackward0>)
tensor([-0.2442, -0.7194,  0.3897,  0.9389], grad_fn=<ViewBackward0>)
tensor([-0.2442, -0.7194,  0.3897,  0.9389], grad_fn=<ViewBackward0>)

✅ 说明:

五、与model.train()的区别总结

比较项model.train()model.eval()
模型状态训练模式推理模式
Dropout启用随机丢弃关闭
BatchNorm使用批次统计使用全局统计
是否影响梯度❌ 不影响❌ 不影响
常用场景模型训练阶段验证、推理阶段

六、完整实战代码(训练 + 验证)

import torch
import torch.nn as nn
import torch.optim as optim

# 定义简单模型
class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(4, 10)
        self.relu = nn.ReLU()
        self.dropout = nn.Dropout(0.5)
        self.fc2 = nn.Linear(10, 3)

    def forward(self, x):
        x = self.fc1(x)
        x = self.relu(x)
        x = self.dropout(x)
        return self.fc2(x)

model = Net()
optimizer = optim.Adam(model.parameters())
criterion = nn.CrossEntropyLoss()

for epoch in range(3):
    # ===== 训练阶段 =====
    model.train()
    optimizer.zero_grad()
    x = torch.randn(5, 4)
    y = torch.randint(0, 3, (5,))
    out = model(x)
    loss = criterion(out, y)
    loss.backward()
    optimizer.step()

    # ===== 验证阶段 =====
    model.eval()
    with torch.no_grad():
        val_x = torch.randn(5, 4)
        val_out = model(val_x)
        val_pred = val_out.argmax(dim=1)
    print(f"Epoch {epoch}: loss={loss.item():.4f}, val_pred={val_pred.tolist()}")

输出如下:

Epoch 0: loss=1.0044, val_pred=[1, 1, 1, 2, 2]
Epoch 1: loss=0.9953, val_pred=[2, 1, 2, 2, 2]
Epoch 2: loss=1.2143, val_pred=[2, 2, 1, 2, 1]

✅ 训练时:

✅ 验证时:

七、常见错误与避坑指南

错误用法后果
在测试时忘记 model.eval()Dropout、BN 层仍随机,导致结果波动、不稳定
在推理时忘记 torch.no_grad()会记录梯度,浪费显存、速度变慢
在训练时调用了 model.eval()模型学不动,BN 不更新统计信息
忘记在训练开始前加 model.train()模型仍在推理模式,训练效果不佳

八、小结

项目说明
函数名model.eval()
所属模块torch.nn.Module
作用切换模型到评估(推理)模式
影响层Dropout、BatchNorm
与 no_grad 区别eval() 控制模式,no_grad 控制梯度
使用场景验证、测试、推理阶段
常用组合model.eval() + with torch.no_grad():

到此这篇关于PyTorch中model.eval()使用与作用小结的文章就介绍到这了,更多相关PyTorch model.eval()使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文