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

PyTorch中Dropout无法降低损失但Keras中正常的问题排查

问题

在TensorFlow/Keras与PyTorch框架下,基于Keras的IMDB数据集,对有无Dropout的简单MLP模型损失情况做对比测试。结果显示Keras中带Dropout的模型表现正常,但PyTorch中带Dropout的模型未达到预期的损失下降效果,与Keras表现不一致。相关实现代码及结果如下:

Keras实现代码

# Keras - IMDB Dataset
model = Sequential()
model.add(Dense(16, activation = "relu", input_shape= (10000,)))
model.add(Dropout(0.5)) # comment out this line for no dropout model
model.add(Dense(16, activation = "relu"))
model.add(Dropout(0.5)) # comment out this line for no dropout model
model.add(Dense(1, activation = "sigmoid"))

model.compile(
    optimizer = "rmsprop",
    loss = "binary_crossentropy",
    metrics = ["accuracy"]
)

history = model.fit(
    X_train,
    y_train, 
    epochs = 20,
    batch_size =  512,
    validation_data = (X_val, y_val)
)

Keras测试结果:左图为无Dropout模型,右图为带Dropout模型

PyTorch实现代码

# Pytorch - same IMDB dataset from keras

class MLP(nn.Module):
    def __init__(self, in_dims, l1, l2, out_dims):
        super(MLP, self).__init__()
        self.fc1 = nn.Linear(in_dims, l1)
        self.fc2 = nn.Linear(l1, l2)
        self.fc3 = nn.Linear(l2, out_dims)
        self.dropout = nn.Dropout(p=0.5)

    def forward(self, X):
        out = F.relu(self.fc1(X))
        out = self.dropout(out) # comment out this line for no dropout model
        out = F.relu(self.fc2(out))
        out = self.dropout(out) # comment out this line for no dropout model
        out = F.sigmoid(self.fc3(out))
        return out

model = MLP(10000, 16, 16, 1)
optimizer = optim.RMSprop(model.parameters(), lr = 0.001)
criterion = nn.BCELoss()

min_val_loss = np.inf
losses = []
val_losses = []
accuracy = []
val_accuracy = []

for e in range(0,20):
    running_loss = 0
    for i,(X_train, y_train) in enumerate(train_loader):
        yhat = model.forward(X_train)
        loss = criterion(yhat.flatten(), y_train)
        running_loss += loss.item()

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

    losses.append(running_loss / (i+1)) #note its i+1 since i starts from 0

    model.eval()
    with torch.no_grad():
        running_val_loss = 0
        for i,(X_val, y_val) in enumerate(val_loader):
            yhat_val = model.forward(X_val)
            val_loss = criterion(yhat_val.flatten(), y_val)
            running_val_loss += val_loss.item()

        val_losses.append(running_val_loss / (i + 1))

        if val_loss < min_val_loss:
            best_params = model.state_dict()
            min_val_loss = val_loss 
    
    print(f"epochs : {e}, train_loss : {loss}, val_loss : {val_loss}")

PyTorch测试结果:左图为无Dropout模型(与Keras结果相近),但带Dropout的模型表现不符合预期


问题排查与解决

以下是PyTorch实现中可能存在的关键问题及修复方案:

1. 训练模式未重置

PyTorch中调用model.eval()会将Dropout切换到评估模式(关闭随机失活),但你在每个epoch的验证环节结束后,没有将模型切回训练模式model.train()。这会导致后续训练阶段Dropout仍处于关闭状态,相当于全程没启用Dropout,自然无法达到预期效果。

修复代码:在验证环节结束后添加:

model.train()

2. RMSprop优化器参数不匹配

Keras与PyTorch的RMSprop默认参数存在差异:

  • Keras默认rho=0.9、epsilon=1e-7;
  • PyTorch默认rho=0.99、epsilon=1e-8。
    这些差异会直接影响优化器的更新节奏,导致模型收敛效果不一致。

修复代码:对齐Keras的默认参数:

optimizer = optim.RMSprop(model.parameters(), lr=0.001, rho=0.9, eps=1e-7)

3. 损失日志显示逻辑错误

你当前打印的train_loss和val_loss是每个epoch最后一个batch的损失值,而非整个epoch的平均损失,这会干扰对模型收敛情况的判断。

修复代码:修改打印语句使用平均损失:

print(f"epochs : {e}, train_loss : {losses[-1]}, val_loss : {val_losses[-1]}")

4. 数据预处理一致性问题

需确保PyTorch使用的IMDB数据集与Keras的预处理逻辑完全一致:

  • 确认词汇表大小限制为10000(与Keras输入维度匹配);
  • 确认输入向量化方式相同(如是否为one-hot编码);
  • 确认标签 dtype 与模型输出匹配(BCELoss要求输入和标签均为float类型,若标签是整数需转换:y_train = y_train.float())。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 14:30:53