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

单TransformerEncoder层模型训练前确定,训练后为何非确定性?

问题原因及解决方案

核心原因

你的代码里有两个关键问题,其中直接导致推理结果不稳定的是动态创建未注册的线性层:

  • 在forward函数中直接用nn.Linear(2,1)(y),会让每次执行推理时都新建一个随机初始化的线性层,该层的权重和偏置完全随机,所以每次输出结果必然不同。
  • 这个动态创建的线性层没被注册为模型的子模块,既不会参与训练(优化器不会更新它的参数),也不受model.eval()的影响——不过Linear层本身没有随机组件,核心问题还是每次新建带来的随机性。

你提到“未训练时具备确定性”,大概率是因为未训练时只执行了一次推理,或是误判了多次执行的结果;实际上如果未训练时多次调用模型,同样会因为动态创建线性层导致输出不同。

修复方案

把线性层的定义移到模型的__init__方法中,注册为模型的子模块,确保训练时参数被优化,推理时使用固定的训练后参数:

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

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)
        # 将线性层注册为模型子模块
        self.fc = nn.Linear(2, 1)

    def forward(self, x):
        y = self.trans(x)
        y = torch.flatten(y)
        # 使用注册好的线性层
        y = self.fc(y)
        return y

model = MyModel()
model.train()
optimizer = optim.Adam(model.parameters(), lr=0.01)

for epoch in range(1):
    training = torch.rand(size=(2,1))
    labels = training[0] + 1
    optimizer.zero_grad()
    outputs = model(training)
    loss = nn.MSELoss()(outputs, labels)
    loss.backward()
    optimizer.step()

model.eval()
x = torch.tensor([[1.],[1.]])
# 多次执行也会得到相同输出
print(model(x))
print(model(x))

额外说明

TransformerEncoderLayer默认包含Dropout层,在train模式下会启用随机失活导致输出不确定,但你在推理前调用了model.eval(),该方法会自动关闭所有子模块的训练模式(包括Dropout),因此这部分不会导致推理结果不稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 22:58:14