作用
.eval() 是 PyTorch 中 nn.Module 类的一个方法,它的核心目的是 将模型切换到“评估/推理模式”,而 非 训练模式。
这个方法主要影响两类层的行为:
Dropout 层:训练时会 随机丢弃部分神经元,
.eval()模式下会 关闭 Dropout,所有神经元都参与计算;BatchNorm 层:训练时会 实时更新均值/方差,
.eval()模式下会 固定使用训练阶段统计的均值/方差,避免推理时的波动。
注意:.eval() 并不会改变模型参数的可训练状态(不会冻结参数),也不会自动关闭梯度计算(需要配合 torch.no_grad() 使用)。
例子
下面是一个完整的示例,展示 .eval() 的正确使用方式:
import torch
import torch.nn as nn
import torch.nn.functional as F
# 定义一个简单的模型(包含Dropout和BatchNorm)
class SimpleModel(nn.Module):
def __init__(self):
super(SimpleModel, self).__init__()
self.fc1 = nn.Linear(10, 20)
self.bn1 = nn.BatchNorm1d(20) # BatchNorm层
self.dropout = nn.Dropout(0.5) # Dropout层(丢弃率50%)
self.fc2 = nn.Linear(20, 5)
def forward(self, x):
x = F.relu(self.bn1(self.fc1(x)))
x = self.dropout(x)
x = self.fc2(x)
return x
# 1. 创建模型并初始化
model = SimpleModel()
# 2. 训练阶段(默认是train模式)
model.train() # 显式切换到训练模式(可选,默认就是train)
# (此处省略训练代码)
# 3. 推理/评估阶段(核心操作)
model.eval() # 切换到评估模式
# 使用torch.no_grad()关闭梯度计算(节省内存、加速推理)
with torch.no_grad():
# 构造测试输入
test_input = torch.randn(1, 10) # 批次大小1,输入维度10
output = model(test_input)
print("推理输出:", output)
# 4. 如果后续需要继续训练,要切回train模式
model.train()
验证是否切换成功
可以通过 model.training 属性查看(True 是训练模式,False 是评估模式):
print(model.training) # 调用eval()前:True
model.eval()
print(model.training) # 调用eval()后:False
.eval() 和 .no_grad() 区别
.eval():改变层的行为(Dropout/BatchNorm);torch.no_grad():关闭梯度计算(不计算梯度、不更新参数);
推理时 必须同时使用 这两个操作,缺一不可。
.eval()的生效范围:会作用于模型的所有子模块(比如模型内的子网络、层);
总结
.eval()的核心是切换模型到推理模式,禁用 Dropout、固定 BatchNorm 的统计量;- 推理时必须配合
torch.no_grad()使用,前者改层行为,后者关梯度; - 推理完成后如果要继续训练,需调用
model.train()切回训练模式。