为何TransformerEncoderLayer在eval模式下推理输出存在随机性?
问题原因及解决方法
情况1:每次重新运行脚本输出不同
这是因为模型参数初始化本身是随机的,eval()模式只是关闭Dropout、BatchNorm这类训练时的动态行为,管不了参数初始化的随机性。每次运行脚本都会重新随机初始化模型权重,输出自然不一样。
解决办法是在代码开头设置全局随机种子,强制每次初始化的参数一致:
import torch from torch import nn # 固定随机种子 torch.manual_seed(42) if torch.cuda.is_available(): torch.cuda.manual_seed_all(42) class MyModel(nn.Module): def __init__(self): super().__init__() self.encoder_layer = nn.TransformerEncoderLayer(d_model=1, nhead=1, dim_feedforward=2) self.trans = nn.TransformerEncoder(self.encoder_layer, num_layers=1) def forward(self, x): y = self.trans(x) return y model = MyModel() model.eval() x = torch.tensor([[1.],[1.]]) print(model(x))
情况2:同一次运行中多次调用model(x)输出不同
这种情况很少见,因为eval()模式会自动关闭TransformerEncoderLayer默认的Dropout层(默认dropout概率0.1)。如果真遇到,检查这两点:
- 有没有手动修改TransformerEncoderLayer的参数,开启了eval模式下仍随机的模块;
- 是不是在模型外自己加了随机操作(比如调用了
torch.randn之类的函数)。
另外补充:你的输入x形状是(2,1),TransformerEncoderLayer期望的输入是(序列长度, batch_size, d_model),这里d_model=1,PyTorch会自动补全成(2,1,1),没问题,但后续扩展模型的话,建议显式改成x = torch.tensor([[1.],[1.]]).unsqueeze(-1),避免歧义。
内容的提问来源于stack exchange,提问作者JobHunter69
相关产品推荐
相关产品推荐

